summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJukka Jokiniva <[email protected]>2024-11-08 13:43:23 +0200
committerJukka Jokiniva <[email protected]>2024-11-08 11:58:27 +0000
commit379620bae78a80adeed3b03641c647aa558330d5 (patch)
treefb451d5bfe08c3911e14b458b62c667c8d97d873
parent1e76a3d20a25bf98f0c24533794e550839fed9ed (diff)
Revert "Update Harfbuzz to 7.2.0"
This reverts commit 6ad56dce3467c32d04b9cf12314ec0f235741af1. First revert was strangely lost during merge process. Change-Id: Ib8ea9d527f6606467386f8929f0c5e452e3e236e Reviewed-by: Tarja Sundqvist <[email protected]>
-rw-r--r--src/3rdparty/harfbuzz-ng/AUTHORS15
-rw-r--r--src/3rdparty/harfbuzz-ng/COPYING20
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS1452
-rw-r--r--src/3rdparty/harfbuzz-ng/THANKS2
-rw-r--r--src/3rdparty/harfbuzz-ng/config.h13
-rw-r--r--src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro170
-rw-r--r--src/3rdparty/harfbuzz-ng/hb-dummy.cc8
-rw-r--r--src/3rdparty/harfbuzz-ng/qt_attribution.json33
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh1030
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh2436
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/colrv1-closure.hh107
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh350
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh452
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh151
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh337
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh133
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh232
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh85
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh918
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh83
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat1.hh46
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat2.hh58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh100
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh77
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ChainContextPos.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh33
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ContextPos.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePos.hh35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh301
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ExtensionPos.hh17
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh171
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh56
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkArray.hh128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePos.hh41
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh244
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPos.hh41
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh223
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPos.hh42
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh228
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkRecord.hh52
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPos.hh46
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh217
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh351
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh207
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh99
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookup.hh79
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookupSubTable.hh79
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh100
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh164
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh176
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh394
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSet.hh126
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubst.hh62
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubstFormat1.hh128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ChainContextSubst.hh18
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Common.hh21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ContextSubst.hh18
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ExtensionSubst.hh22
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/GSUB.hh61
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh190
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh131
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubst.hh71
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh166
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubst.hh62
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubstFormat1.hh130
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh36
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh244
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Sequence.hh165
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh103
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat1.hh204
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat2.hh176
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookup.hh220
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookupSubTable.hh77
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh66
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh399
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh566
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/GlyphHeader.hh52
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh345
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/SubsetGlyph.hh152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh371
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/composite-iter.hh68
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/coord-setter.hh34
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh104
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh504
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/loca.hh43
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh193
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/name/name.hh589
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh216
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/graph.hh1392
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.cc70
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.hh61
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh414
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh510
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh647
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/serialize.hh270
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/split-helpers.hh69
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc119
-rw-r--r--src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc62
-rw-r--r--src/3rdparty/harfbuzz-ng/src/harfbuzz.cc60
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh98
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh158
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh919
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh222
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh417
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh1001
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh1210
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh173
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh230
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc440
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h795
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh77
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh92
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc172
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh123
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat.h38
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-algs.hh1405
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-array.hh494
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh189
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic.hh221
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bimap.hh164
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh340
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh378
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh968
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.cc556
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.h58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.hh98
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh570
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh692
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh332
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh571
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh388
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc652
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc439
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc1162
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.h328
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.hh668
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh74
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cache.hh101
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc874
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.hh107
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cairo.cc1010
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cairo.h99
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh643
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh907
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh201
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff1-interp-cs.hh160
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh282
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.cc709
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h867
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-config.hh195
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.h34
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.mm (renamed from src/3rdparty/harfbuzz-ng/src/hb-coretext.cc)719
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh223
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-debug.hh167
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-deprecated.h202
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc884
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-directwrite.h40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh60
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-draw.cc458
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-draw.h340
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-draw.hh231
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-dsalgs.hh167
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-builder.cc246
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-face.hh)80
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc412
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.h85
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc60
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh555
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.cc2544
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.h781
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.hh720
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh567
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ft.cc1500
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ft.h145
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gdi.cc85
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gdi.h39
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-glib.cc232
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl80
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl56
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc116
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h136
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-gobject.h40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc449
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-graphite2.h61
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-icu.cc290
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-iter.hh1026
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-kern.hh145
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-limits.hh109
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-machinery.hh325
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-map.cc419
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-map.h143
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-map.hh490
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-meta.hh238
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ms-feature-ranges.hh232
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-multimap.hh92
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-mutex.hh)103
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-null.hh226
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh237
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-number.cc79
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-number.hh41
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-object-private.hh196
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-object.hh357
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh280
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-file.hh537
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh1184
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type.hh1147
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh471
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh516
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh425
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc620
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh1484
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc222
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh540
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh1923
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc363
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-color.h155
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h147
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-face.hh77
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc596
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-font.h2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh84
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh155
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh170
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh99
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh90
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh490
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh479
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh525
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh1772
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh3715
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh427
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh1619
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh1341
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh2373
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh4550
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh85
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh722
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh)266
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc2311
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h339
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh)187
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc249
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh839
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc265
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math.h132
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh111
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh129
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc79
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h72
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc436
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h129
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.hh35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh456
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-language.hh40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh108
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc184
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name.h164
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh388
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh231
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-table-v2subset.hh136
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh243
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-fallback.hh)199
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.hh)10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-table.hh)234
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-win1256.hh)46
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc)243
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-default.cc)37
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hangul.cc)103
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hebrew.cc)59
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh1566
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh190
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc486
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.cc)1221
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh404
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc547
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper.hh)249
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc)54
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-face.cc)59
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh459
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh97
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc777
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc612
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.hh)23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc267
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh)16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc298
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh108
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc1065
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh171
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-joining-list.hh47
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-pua.hh118
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh627
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-table.cc561
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh428
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer.cc387
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh553
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar.cc390
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.cc100
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.hh47
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh1080
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh674
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use.cc511
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.cc477
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.hh39
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh620
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh2993
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc1322
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h (renamed from src/3rdparty/harfbuzz-ng/src/hb-glib.h)37
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh177
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh594
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh158
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh412
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh516
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh375
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh54
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc245
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var.h138
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh136
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot.h6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-outline.cc321
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-outline.hh83
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc330
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-paint-extents.hh293
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-paint.cc703
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-paint.h987
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-paint.hh228
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-pool.hh107
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh159
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh899
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-repacker.hh410
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh442
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-serialize.hh768
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-digest-private.hh179
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh207
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-private.hh577
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.cc417
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.h67
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.hh184
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.hh)57
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc629
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h20
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.hh77
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc392
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.h14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-shaper-impl.hh)23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh124
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper.cc81
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper.hh134
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-static.cc135
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-string-array.hh16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-style.cc134
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-style.h81
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh132
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc220
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh1165
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc956
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh37
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc661
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh37
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc591
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh153
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc464
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc1226
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh327
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.cc58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.h81
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.cc639
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.h230
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.hh74
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh5633
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ucd.cc258
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh79
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh (renamed from src/3rdparty/harfbuzz-ng/src/hb-unicode.hh)160
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.cc268
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.h414
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc889
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-uniscribe.h46
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh282
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-utf.hh481
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-vector.hh510
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h39
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-warning.cc (renamed from src/3rdparty/harfbuzz-ng/src/hb-icu.h)35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb.h8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb.hh534
-rw-r--r--src/gui/configure.json28
-rw-r--r--tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp4
-rw-r--r--tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp3
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp7
393 files changed, 29108 insertions, 119555 deletions
diff --git a/src/3rdparty/harfbuzz-ng/AUTHORS b/src/3rdparty/harfbuzz-ng/AUTHORS
index 83c0c66f99e..81cdc4cf37f 100644
--- a/src/3rdparty/harfbuzz-ng/AUTHORS
+++ b/src/3rdparty/harfbuzz-ng/AUTHORS
@@ -1,14 +1,9 @@
Behdad Esfahbod
-David Corbett
-David Turner
-Ebrahim Byagowi
-Garret Rieger
+Simon Hausmann
+Martin Hosken
Jonathan Kew
-Khaled Hosny
Lars Knoll
-Martin Hosken
-Owen Taylor
-Roderick Sheeter
-Roozbeh Pournader
-Simon Hausmann
Werner Lemberg
+Roozbeh Pournader
+Owen Taylor
+David Turner
diff --git a/src/3rdparty/harfbuzz-ng/COPYING b/src/3rdparty/harfbuzz-ng/COPYING
index 1dd917e9f2e..9d1056f40b1 100644
--- a/src/3rdparty/harfbuzz-ng/COPYING
+++ b/src/3rdparty/harfbuzz-ng/COPYING
@@ -2,23 +2,17 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
For parts of HarfBuzz that are licensed under different licenses see individual
files names COPYING in subdirectories where applicable.
-Copyright © 2010-2022 Google, Inc.
-Copyright © 2015-2020 Ebrahim Byagowi
-Copyright © 2019,2020 Facebook, Inc.
-Copyright © 2012,2015 Mozilla Foundation
+Copyright © 2010,2011,2012 Google, Inc.
+Copyright © 2012 Mozilla Foundation
Copyright © 2011 Codethink Limited
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright © 2009 Keith Stribley
-Copyright © 2011 Martin Hosken and SIL International
+Copyright © 2009 Martin Hosken and SIL International
Copyright © 2007 Chris Wilson
-Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod
-Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.
-Copyright © 1998-2005 David Turner and Werner Lemberg
-Copyright © 2016 Igalia S.L.
-Copyright © 2022 Matthias Clasen
-Copyright © 2018,2021 Khaled Hosny
-Copyright © 2018,2019,2020 Adobe, Inc
-Copyright © 2013-2015 Alexei Podtelezhnikov
+Copyright © 2006 Behdad Esfahbod
+Copyright © 2005 David Turner
+Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
+Copyright © 1998-2004 David Turner and Werner Lemberg
For full copyright notices consult the individual files in the package.
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
index e53a244f1b3..7434bcada03 100644
--- a/src/3rdparty/harfbuzz-ng/NEWS
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -1,1451 +1,3 @@
-Overview of changes leading to 7.2.0
-Thursday, April 27, 2023
-====================================
-- Add Tifinagh to the list of scripts that can natively be either right-to-left
- or left-to-right, to improve handling of its glyph positioning.
- (Simon Cozens)
-- Return also single substitution from hb_ot_layout_lookup_get_glyph_alternates()
- (Behdad Esfahbod)
-- Fix 4.2.0 regression in applying across syllables in syllabic scripts.
- (Behdad Esfahbod)
-- Add flag to avoid glyph substitution closure during subsetting, and the
- corresponding “--no-layout-closure” option to “hb-subset” command line tool.
- (Garret Rieger)
-- Support instancing COLRv1 table. (Qunxin Liu)
-- Don’t drop used user-defined name table entries during subsetting.
- (Qunxin Liu)
-- Optimize handling of “gvar” table. (Behdad Esfahbod)
-- Various subsetter bug fixes and improvements. (Garret Rieger, Qunxin Liu)
-- Various documentation improvements. (Behdad Esfahbod, Josef Friedrich)
-
-- New API:
-+HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE
-+HB_UNICODE_COMBINING_CLASS_CCC132
-
-- Deprecated API:
-+HB_UNICODE_COMBINING_CLASS_CCC133
-
-
-Overview of changes leading to 7.1.0
-Friday, March 3, 2023
-====================================
-- New experimental hb_shape_justify() API that uses font variations to expand
- or shrink the text to a given advance. (Behdad Esfahbod)
-- Various build and bug fixes. (Behdad Esfahbod, Garret Rieger, Qunxin Liu)
-
-- New API:
-+hb_font_set_variation()
-
-
-Overview of changes leading to 7.0.1
-Monday, February 20, 2023
-====================================
-- Various build and bug fixes.
-
-
-Overview of changes leading to 7.0.0
-Saturday, February 11, 2023
-====================================
-- New hb-paint API that is designed mainly to paint “COLRv1” glyphs, but can be
- also used as a unified API to paint any of the glyph representations
- supported by HarfBuzz (B/W outlines, color layers, or color bitmaps).
- (Behdad Esfahbod, Matthias Clasen)
-- New hb-cairo API for integrating with cairo graphics library. This is provided
- as a separate harfbuzz-cairo library. (Behdad Esfahbod, Matthias Clasen)
-- Support for instancing “CFF2” table. (Behdad Esfahbod)
-- Support font emboldening. (Behdad Esfahbod)
-- Support feature ranges with AAT shaping. (Behdad Esfahbod)
-- Experimental support to cubic curves in “glyf” table, see
- https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md
- for spec. (Behdad Esfahbod)
-- Various subsetter improvements. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
-- Various documentation improvements.
- (Behdad Esfahbod, Matthias Clasen, Khaled Hosny)
-- Significantly reduced memory use during shaping. (Behdad Esfahbod)
-- Greatly reduced memory use during subsetting “CFF” table. (Behdad Esfahbod)
-- New command line utility, hb-info, for querying various font information.
- (Behdad Esfahbod, Matthias Clasen)
-- New hb-shape/hb-view options: --glyphs, --color-palette, --font-bold,
- --font-grade, and --named-instance. (Behdad Esfahbod)
-- Miscellaneous fixes and improvements.
- (Amir Masoud Abdol, Andres Salomon, Behdad Esfahbod, Chun-wei Fan,
- Garret Rieger, Jens Kutilek, Khaled Hosny, Konstantin Käfer, Matthias Clasen,
- Nirbheek Chauhan, Pedro J. Estébanez, Qunxin Liu, Sergei Trofimovich)
-
-- New API:
-+HB_FONT_NO_VAR_NAMED_INSTANCE
-+HB_PAINT_IMAGE_FORMAT_BGRA
-+HB_PAINT_IMAGE_FORMAT_PNG
-+HB_PAINT_IMAGE_FORMAT_SVG
-+hb_cairo_font_face_create_for_face
-+hb_cairo_font_face_create_for_font
-+hb_cairo_font_face_get_face
-+hb_cairo_font_face_get_font
-+hb_cairo_font_face_get_scale_factor
-+hb_cairo_font_face_set_font_init_func
-+hb_cairo_font_face_set_scale_factor
-+hb_cairo_font_init_func_t
-+hb_cairo_glyphs_from_buffer
-+hb_cairo_scaled_font_get_font
-+hb_color_line_get_color_stops
-+hb_color_line_get_color_stops_func_t
-+hb_color_line_get_extend
-+hb_color_line_get_extend_func_t
-+hb_color_line_t
-+hb_color_stop_t
-+hb_draw_funcs_get_empty
-+hb_draw_funcs_get_user_data
-+hb_draw_funcs_set_user_data
-+hb_face_collect_nominal_glyph_mapping
-+hb_font_draw_glyph
-+hb_font_draw_glyph_func_t
-+hb_font_funcs_set_draw_glyph_func
-+hb_font_funcs_set_paint_glyph_func
-+hb_font_get_synthetic_bold
-+hb_font_get_var_named_instance
-+hb_font_paint_glyph
-+hb_font_paint_glyph_func_t
-+hb_font_set_synthetic_bold
-+hb_map_keys
-+hb_map_next
-+hb_map_update
-+hb_map_values
-+hb_ot_color_glyph_has_paint
-+hb_ot_color_has_paint
-+hb_ot_layout_script_select_language2
-+hb_ot_name_id_predefined_t
-+hb_paint_color
-+hb_paint_color_func_t
-+hb_paint_composite_mode_t
-+hb_paint_custom_palette_color
-+hb_paint_custom_palette_color_func_t
-+hb_paint_extend_t
-+hb_paint_funcs_create
-+hb_paint_funcs_destroy
-+hb_paint_funcs_get_empty
-+hb_paint_funcs_get_user_data
-+hb_paint_funcs_is_immutable
-+hb_paint_funcs_make_immutable
-+hb_paint_funcs_reference
-+hb_paint_funcs_set_color_func
-+hb_paint_funcs_set_custom_palette_color_func
-+hb_paint_funcs_set_image_func
-+hb_paint_funcs_set_linear_gradient_func
-+hb_paint_funcs_set_pop_clip_func
-+hb_paint_funcs_set_pop_group_func
-+hb_paint_funcs_set_pop_transform_func
-+hb_paint_funcs_set_push_clip_glyph_func
-+hb_paint_funcs_set_push_clip_rectangle_func
-+hb_paint_funcs_set_push_group_func
-+hb_paint_funcs_set_push_transform_func
-+hb_paint_funcs_set_radial_gradient_func
-+hb_paint_funcs_set_sweep_gradient_func
-+hb_paint_funcs_set_user_data
-+hb_paint_funcs_t
-+hb_paint_image
-+hb_paint_image_func_t
-+hb_paint_linear_gradient
-+hb_paint_linear_gradient_func_t
-+hb_paint_pop_clip
-+hb_paint_pop_clip_func_t
-+hb_paint_pop_group
-+hb_paint_pop_group_func_t
-+hb_paint_pop_transform
-+hb_paint_pop_transform_func_t
-+hb_paint_push_clip_glyph
-+hb_paint_push_clip_glyph_func_t
-+hb_paint_push_clip_rectangle
-+hb_paint_push_clip_rectangle_func_t
-+hb_paint_push_group
-+hb_paint_push_group_func_t
-+hb_paint_push_transform
-+hb_paint_push_transform_func_t
-+hb_paint_radial_gradient
-+hb_paint_radial_gradient_func_t
-+hb_paint_sweep_gradient
-+hb_paint_sweep_gradient_func_t
-+hb_set_is_inverted
-+hb_subset_input_keep_everything
-
-- Deprecated API:
-+hb_font_funcs_set_glyph_shape_func
-+hb_font_get_glyph_shape_func_t
-+hb_font_get_glyph_shape
-
-
-Overview of changes leading to 6.0.0
-Friday, December 16, 2022
-====================================
-- A new API have been added to pre-process the face and speed up future
- subsetting operations on that face. Provides up to a 95% reduction in
- subsetting times when the same face is subset more than once.
-
- For more details and benchmarks, see:
- https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md
-
- (Garret Rieger, Behdad Esfahbod)
-
-- Shaping have been speedup by skipping entire lookups when the buffer contents
- don't intersect with the lookup. Shows up to a 10% speedup in shaping some
- fonts. (Behdad Esfahbod)
-
-- A new experimental feature, “Variable Composites” (enabled by passing
- -Dexperimental_api=true to meson), is also featured in this release.
- This technology enables drastic compression of fonts in the Chinese,
- Japanese, Korean, and other writing systems, by reusing the OpenType Font
- Variations technology for encoding “smart components” into the font.
-
- The specification for these extensions to the font format can be found in:
- https://github.com/harfbuzz/boring-expansion-spec/blob/glyf1/glyf1.md
-
- A test variable-font with ~7160 Hangul syllables derived from the
- NotoSerifKR-VF font has been built, with existing OpenType technology, as
- well as with the new Variable Composites (VarComposites) technology. The
- VarComposites font is over 90% smaller than the OpenType version of the font!
- Both fonts can be obtained from the “smarties” repository:
- https://github.com/behdad/smarties/tree/3.0/fonts/hangul/serif
-
- When building HarfBuzz with experimental features enabled, you can test
- the “smarties” font with a sample character like this:
-
- $ hb-view butchered-hangul-serif-smarties-variable.ttf -u AE01 --variations=wght=700
-
- (Behdad Esfahbod)
-
-- The HarfBuzz subsetter can now drop axes by pinning them to specific values
- (also referred to as instancing). There are a couple of restrictions
- currently:
-
- - Only works with TrueType (“glyf”) based fonts. “CFF2” fonts are not yet
- supported.
- - Only supports the case where all axes in a font are pinned.
-
- (Garret Rieger, Qunxin Liu)
-
-- Miscellaneous fixes and improvements.
-
- (Behdad Esfahbod, Christoph Reiter, David Corbett, Eli Schwartz, Garret
- Rieger, Joel Auterson, Jordan Petridis, Khaled Hosny, Lorenz Wildberg,
- Marco Rebhan, Martin Storsjö, Matthias Clasen, Qunxin Liu, Satadru Pramanik)
-
-
-- New API
-+hb_subset_input_pin_axis_location()
-+hb_subset_input_pin_axis_to_default()
-+hb_subset_preprocess()
-
-
-Overview of changes leading to 5.3.1
-Wednesday, October 19, 2022
-====================================
-- Subsetter repacker fixes. (Garret Rieger)
-- Adjust Grapheme clusters for Katakana voiced sound marks. (Behdad Esfahbod)
-- New “hb-subset” option “--preprocess-face”. (Garret Rieger)
-
-
-Overview of changes leading to 5.3.0
-Saturday, October 8, 2022
-"Women, Life, Freedom" #MahsaAmini
-====================================
-- Don’t add glyphs from dropped MATH or COLR tables to the subset glyphs.
- (Khaled Hosny)
-- Map “rlig” to appropriate AAT feature selectors. (Jonathan Kew)
-- Update USE data files to latest version. (David Corbett)
-- Check “CBDT” extents first before outline tables, to help with fonts that
- also include an empty “glyf” table. (Khaled Hosny)
-- More work towards variable font instancing in the subsetter. (Qunxin Liu)
-- Subsetter repacker improvements. (Garret Rieger)
-- New API:
-+hb_ot_layout_lookup_get_optical_bound()
-+hb_face_builder_sort_tables()
-
-
-Overview of changes leading to 5.2.0
-Saturday, September 17, 2022
-====================================
-- Fix regressions in hb-ft font functions for FT_Face’s with transformation
- matrix. (Behdad Esfahbod)
-- The experimental hb-repacker API now supports splitting several GPOS subtable
- types when needed. (Garret Rieger)
-- The HarfBuzz extensions to OpenType font format are now opt-in behind
- build-time flags. (Behdad Esfahbod)
-- The experimental hb-subset variable fonts instantiation API can now
- instantiate more font tables and arbitrary axis locations. (Qunxin Liu)
-- Unicode 15 support. (David Corbett)
-- Various documentation improvements. (Behdad Esfahbod, Matthias Clasen)
-- The hb-view command line tool now detects WezTerm inline images support.
- (Wez Furlong)
-- Fix FreeType and ICU dependency lookup with meson. (Xavier Claessens)
-
-- New API:
-+HB_SCRIPT_KAWI
-+HB_SCRIPT_NAG_MUNDARI
-
-
-Overview of changes leading to 5.1.0
-Sunday, July 31, 2022
-====================================
-- More extensive buffer tracing messages. (Behdad Esfahbod)
-- Fix hb-ft regression in bitmap fonts rendering. (Behdad Esfahbod)
-- Support extension promotion of lookups in hb-subset-repacker. (Garret Rieger)
-- A new HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL for scripts that use elongation
- (e.g. Arabic) to signify where it is safe to insert tatweel glyph without
- interrupting shaping. (Behdad Esfahbod)
-- Add “--safe-to-insert-tatweel” to “hb-shape” tool. (Behdad Esfahbod)
-
-- New API
-+HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL
-+HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL
-
-
-Overview of changes leading to 5.0.1
-Saturday, July 23, 2022
-====================================
-- Fix version 2 “avar” table with hb-ft. (Behdad Esfahbod)
-
-
-Overview of changes leading to 5.0.0
-Saturday, July 23, 2022
-====================================
-- Support fonts with more than 65535 glyphs in “GDEF”, “GSUB”, and “GPOS”
- tables. This is part of https://github.com/be-fonts/boring-expansion-spec to
- extend OpenType in a backward-compatible way.
- (Behdad Esfahbod, Garret Rieger)
-- Complete support for more than 65535 glyphs in “glyf” table that started in
- 4.0.0 release. Part of boring-expansion-spec. (Behdad Esfahbod)
-- Support version 2 of “avar” table. Part of boring-expansion-spec.
- (Behdad Esfahbod)
-- Fix mark attachment on multiple substitutions in some cases.
- (Behdad Esfahbod)
-- Fix application of “calt”, “rclt”, and “ccmp” features to better match
- Uniscribe behaviour with some Arabic fonts. (Behdad Esfahbod)
-- Improvement to interaction between multiple cursive attachments.
- (Behdad Esfahbod)
-- Improve multiple mark interactions in Hebrew. (Behdad Esfahbod)
-- Implement language-specific forms in AAT shaping. (Behdad Esfahbod)
-- Fix variation of “VORG” table. (Behdad Esfahbod)
-- Support for specific script tags to be retained in the subsetter, and add
- “--layout-scripts” option to “hb-subset” tool. (Garret Rieger)
-- Accept space as delimiter for --features/--variations in command line tools.
-- Improve subsetting of “COLR” table. (Qunxin Liu)
-- Improved fuzzing coverage for ot-math API. (Frédéric Wang)
-- Fix “kern” table version 2 (AAT) sanitization on 32-bit systems.
- (Behdad Esfahbod)
-- Allow negative glyph advances from “graphite2” shaper. (Stephan Bergmann)
-- Implement loading (color) bitmap fonts with hb-ft. (Behdad Esfahbod)
-- Fix regression in hb-ft when changing font size. (Behdad Esfahbod)
-- Fix build on GCC < 7. (Kleis Auke Wolthuizen)
-- Dynamically load dwrite.dll on windows if “directwrite” shaper is enabled.
- (Luca Bacci)
-- Provide a single-file harfbuzz-subset.cc file for easier alternate building
- of hb-subset library, similar to harfbuzz.cc. (Khaled Hosny)
-
-- New API
-+HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG
-+hb_language_matches()
-
-
-Overview of changes leading to 4.4.1
-Wednesday, June 29, 2022
-====================================
-- Fix test failure with some compilers.
-- Fix Telugu and Kannada kerning regression.
-
-
-Overview of changes leading to 4.4.0
-Monday, June 27, 2022
-====================================
-- Caching of variable fonts shaping, in particular when using HarfBuzz’s own
- font loading functions (ot). Bringing performance of variable shaping in par
- with non-variable fonts shaping. (Behdad Esfahbod)
-- Caching of format 2 “Contextual Substitution” and “Chained Contexts
- Substitution” lookups. Resulting in up to 20% speedup of lookup-heavy fonts
- like Gulzar or Noto Nastaliq Urdu. (Behdad Esfahbod)
-- Improved ANSI output from hb-view. (Behdad Esfahbod)
-- Support for shaping legacy, pre-OpenType Windows 3.1-era, Arabic fonts that
- relied on a fixed PUA encoding. (Khaled Hosny, Behdad Esfahbod)
-- Sinhala script is now shaped by the USE shaper instead of “indic” one.
- (Behdad Esfahbod, David Corbett)
-- Thai shaper improvements. (David Corbett)
-- hb-ot-name API supports approximate BCP-47 language matching, for example
- asking for “en_US” in a font that has only “en” names will return them.
- (Behdad Esfahbod)
-- Optimized TrueType glyph shape loading. (Behdad Esfahbod)
-- Fix subsetting of HarfBuzz faces created via hb_face_create_for_tables().
- (Garret Rieger)
-- Add 32 bit var store support to the subsetter. (Garret Rieger)
-
-- New API
-+HB_BUFFER_FLAG_DEFINED
-+HB_BUFFER_SERIALIZE_FLAG_DEFINED
-+hb_font_changed()
-+hb_font_get_serial()
-+hb_ft_hb_font_changed()
-+hb_set_hash()
-+hb_map_copy()
-+hb_map_hash()
-
-
-Overview of changes leading to 4.3.0
-Friday, May 20, 2022
-====================================
-- Major speed up in loading and subsetting fonts, especially in
- handling CFF table. Subsetting some fonts is now 3 times faster.
- (Behdad Esfahbod, Garret Rieger)
-- Speed up blending CFF2 table. (Behdad Esfahbod)
-- Speed up hb_ot_tags_from_language(). (Behdad Esfahbod, David Corbett)
-- Fix USE classification of U+10A38 to fix multiple marks on single Kharoshthi
- base. (David Corbett)
-- Fix parsing of empty CFF Index. (Behdad Esfahbod)
-- Fix subsetting CPAL table with partial palette overlaps. (Garret Rieger)
-
-- New API
-+hb_map_is_equal() (Behdad Esfahbod)
-
-
-Overview of changes leading to 4.2.1
-Sunday, April 24, 2022
-====================================
-- Make sure hb_blob_create_from_file_or_fail() always returns nullptr in case
- of failure and not empty blob sometimes. (Khaled Hosny)
-- Add --passthrough-tables option to hb-subset. (Cosimo Lupo)
-- Reinstate a pause after basic features in Khmer shaper, fixing a regression
- introduced in previous release. (Behdad Esfahbod)
-- Better handling of Regional_Indicator when shaped with RTL-native scripts,
- reverting earlier fix that caused regressions in AAT shaping. (Behdad Esfahbod)
-
-
-Overview of changes leading to 4.2.0
-Wednesday, March 30, 2022
-====================================
-- Source code reorganization, splitting large hb-ot-layout files into smaller,
- per-subtable ones under OT/Layout/*. Code for more tables will follow suit in
- later releases. (Garret Rieger, Behdad Esfahbod)
-- Revert Indic shaper change in previous release that broke some fonts and
- instead make per-syllable restriction of “GSUB” application limited to
- script-specific Indic features, while applying them and discretionary
- features in one go. (Behdad Esfahbod)
-- Fix decoding of private in gvar table. (Behdad Esfahbod)
-- Fix handling of contextual lookups that delete too many glyphs. (Behdad Esfahbod)
-- Make “morx” deleted glyphs don’t block “GPOS” application. (Behdad Esfahbod)
-- Various build fixes. (Chun-wei Fan, Khaled Hosny)
-
-- New API
-+hb_set_next_many() (Andrew John)
-
-
-Overview of changes leading to 4.1.0
-Wednesday, March 23, 2022
-====================================
-- Various OSS-Fuzz fixes. (Behdad Esfahbod)
-- Make fallback vertical-origin match FreeType’s. (Behdad Esfahbod)
-- Treat visible viramas like dependent vowels in USE shaper. (David Corbett)
-- Apply presentation forms features and discretionary features in one go in
- Indic shaper, which seems to match Uniscribe and CoreText behaviour.
- (Behdad Esfahbod, David Corbett)
-- Various bug fixes.
-
-- New API
-+hb_set_add_sorted_array() (Andrew John)
-
-
-Overview of changes leading to 4.0.1
-Friday, March 11, 2022
-====================================
-- Update OpenType to AAT mappings for “hist” and “vrtr” features.
- (Florian Pircher)
-- Update IANA Language Subtag Registry to 2022-03-02. (David Corbett)
-- Update USE shaper to allow any non-numeric tail in a symbol cluster, and
- remove obsolete data overrides. (David Corbett)
-- Fix handling of baseline variations to return correctly scaled values.
- (Matthias Clasen)
-- A new experimental hb_subset_repack_or_fail() to repack an array of objects,
- eliminating offset overflows. The API is not available unless HarfBuzz is
- built with experimental APIs enabled. (Qunxin Liu)
-
-- New experimental API
-+hb_link_t
-+hb_object_t
-+hb_subset_repack_or_fail()
-
-
-Overview of changes leading to 4.0.0
-Tuesday, March 1, 2022
-====================================
-- New public API to create subset plan and gather information on things like
- glyph mappings in the final subset. The plan can then be passed on to perform
- the subsetting operation. (Garret Rieger)
-- Draw API for extracting glyph shapes have been extended and finalized and is
- no longer an experimental API. The draw API supports glyf, CFF and CFF2
- glyph outlines tables, and applies variation settings set on the font as well
- as synthetic slant. The new public API is not backward compatible with the
- previous, non-public, experimental API. (Behdad Esfahbod)
-- The hb-view tool will use HarfBuzz draw API to render the glyphs instead of
- cairo-ft when compiled with Cairo 1.17.5 or newer, setting HB_DRAW
- environment variable to 1 or 0 will force using or not use the draw API,
- respectively. (Behdad Esfahbod)
-- The hb-shape and hb-view tools now default to using HarfBuzz’s own font
- loading functions (ot) instead of FreeType ones (ft). They also have a new
- option, --font-slant, to apply synthetic slant to the font. (Behdad Esfahbod)
-- HarfBuzz now supports more than 65535 (the OpenType limit) glyph shapes and
- metrics. See https://github.com/be-fonts/boring-expansion-spec/issues/6 and
- https://github.com/be-fonts/boring-expansion-spec/issues/7 for details.
- (Behdad Esfahbod)
-- New API to get the dominant horizontal baseline tag for a given script.
- (Behdad Esfahbod)
-- New API to get the baseline positions from the font, and synthesize missing
- ones. As well as new API to get font metrics and synthesize missing ones.
- (Matthias Clasen)
-- Improvements to finding dependencies on Windows when building with Visual
- Studio. (Chun-wei Fan)
-- New buffer flag, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, that must be set
- during shaping for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT flag to be reliably
- produced. This is to limit the performance hit of producing this flag to when
- it is actually needed. (Behdad Esfahbod)
-- Documentation improvements. (Matthias Clasen)
-
-- New API
- - General:
- +HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
- +hb_var_num_t
-
- - Draw:
- +hb_draw_funcs_t
- +hb_draw_funcs_create()
- +hb_draw_funcs_reference()
- +hb_draw_funcs_destroy()
- +hb_draw_funcs_is_immutable()
- +hb_draw_funcs_make_immutable()
- +hb_draw_move_to_func_t
- +hb_draw_funcs_set_move_to_func()
- +hb_draw_line_to_func_t
- +hb_draw_funcs_set_line_to_func()
- +hb_draw_quadratic_to_func_t
- +hb_draw_funcs_set_quadratic_to_func()
- +hb_draw_cubic_to_func_t
- +hb_draw_funcs_set_cubic_to_func()
- +hb_draw_close_path_func_t
- +hb_draw_funcs_set_close_path_func()
- +hb_draw_state_t
- +HB_DRAW_STATE_DEFAULT
- +hb_draw_move_to()
- +hb_draw_line_to()
- +hb_draw_quadratic_to()
- +hb_draw_cubic_to()
- +hb_draw_close_path()
- +hb_font_get_glyph_shape_func_t
- +hb_font_funcs_set_glyph_shape_func()
- +hb_font_get_glyph_shape()
-
- - OpenType layout
- +HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
- +HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
- +hb_ot_layout_get_horizontal_baseline_tag_for_script()
- +hb_ot_layout_get_baseline_with_fallback()
-
- - Metrics:
- +hb_ot_metrics_get_position_with_fallback()
-
- - Subset:
- +hb_subset_plan_t
- +hb_subset_plan_create_or_fail()
- +hb_subset_plan_reference()
- +hb_subset_plan_destroy()
- +hb_subset_plan_set_user_data()
- +hb_subset_plan_get_user_data()
- +hb_subset_plan_execute_or_fail()
- +hb_subset_plan_unicode_to_old_glyph_mapping()
- +hb_subset_plan_new_to_old_glyph_mapping()
- +hb_subset_plan_old_to_new_glyph_mapping()
-
-
-Overview of changes leading to 3.4.0
-Sunday, February 13, 2022
-====================================
-- Perform sanity checks on shaping results is now part of “harfbuzz” library
- and can be enabled by setting the buffer flag HB_BUFFER_FLAG_VERIFY.
- (Behdad Esfahbod)
-- Arabic Mark Transient Reordering Algorithm have been updated to revision 6.
- (Khaled Hosny)
-- ISO 15924 code for mathematical notation, ‘Zmth’, now maps to the OpenType
- ‘math’ tag. (Alexis King)
-- It is now possible to get at once all math kerning values for a given glyph
- at a given corner. (Alexis King)
-- Fix locale_t portability issues on systems the typedef’s it to a void
- pointer. (Behdad Esfahbod)
-
-- New API:
-+HB_BUFFER_FLAG_VERIFY
-+HB_OT_TAG_MATH_SCRIPT
-+HB_SCRIPT_MATH
-+hb_ot_math_kern_entry_t
-+hb_ot_math_get_glyph_kernings()
-
-- Deprecated API
-+HB_OT_MATH_SCRIPT
-
-
-Overview of changes leading to 3.3.2
-Sunday, February 6, 2022
-====================================
-- Revert splitting of pair positioning values introduced in 3.3.0 as it proved
- problematic. (Behdad Esfahbod)
-
-
-Overview of changes leading to 3.3.1
-Monday, January 31, 2022
-====================================
-- Fix heap-use-after-free in harfbuzz-subset introduced in previous release.
- (Garret Rieger)
-
-
-Overview of changes leading to 3.3.0
-Monday, January 31, 2022
-====================================
-- Improved documentation. (Matthias Clasen)
-- Internal code cleanup, using C++ standard library more. (Behdad Esfahbod)
-- The low 16-bits of face index will be used by hb_face_create() to select a
- face inside a font collection file format, while the high 16-bits will be
- used by hb_font_create() to load the named instance. (Behdad Esfahbod)
-- Glyph positions and other font metrics now apply synthetic slant set by
- hb_font_set_synthetic_slant(), for improved positioning for synthetically
- slanted fonts. (Behdad Esfahbod)
-- Fixed unintentional locale dependency in hb_variation_to_string() for decimal
- point representation. (Matthias Clasen)
-- When applying pair positioning (kerning) the positioning value is split
- between the two sides of the pair for improved cursor positioning between
- such pairs. (Behdad Esfahbod)
-- Introduced new HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, to be used in conjunction
- with HB_GLYPH_FLAG_UNSAFE_TO_BREAK for optimizing re-shaping during line
- breaking. Check the documentation for further details. (Behdad Esfahbod)
-- Improved handling of macrolanguages when mapping BCP 47 codes to OpenType
- tags. (David Corbett)
-
-- New API:
-+HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
-+hb_segment_properties_overlay()
-+hb_buffer_create_similar()
-+hb_font_set_synthetic_slant()
-+hb_font_get_synthetic_slant()
-+hb_font_get_var_coords_design()
-
-
-Overview of changes leading to 3.2.0
-Friday, November 26, 2021
-====================================
-“harfbuzz” library improvements:
-- Fixed shaping of Apple Color Emoji flags in right-to-left context. (Behdad Esfahbod)
-- Fixed positioning of CFF fonts in HB_TINY profile. (Behdad Esfahbod)
-- OpenType 1.9 language tags update. (David Corbett)
-- Add HB_NO_VERTICAL config option.
-- Add HB_CONFIG_OVERRIDE_H for easier configuration. (Behdad Esfahbod)
-
-“harfbuzz-subset” library improvements:
-- Improved packing of cmap, loca, and Ligature tables. (Garret Rieger)
-- Significantly improved overflow-resolution strategy in the repacker. (Garret Rieger)
-
-
-Overview of changes leading to 3.1.2
-Friday, November 26, 2021
-====================================
-- hb-shape / hb-view: revert treating text on the commandline as single
- paragraph (was introduced in 3.0.0); add new --single-par to do that.
- (Behdad Esfahbod)
-- Subsetter bug fixes. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
-
-
-Overview of changes leading to 3.1.1
-Wednesday, November 8, 2021
-====================================
-- Work around GCC cast-align error/warning on some platforms. (Behdad Esfahbod)
-- Documentation improvements. (Matthias Clasen)
-
-
-Overview of changes leading to 3.1.0
-Wednesday, November 3, 2021
-====================================
-- Better offset-overflow handling in the subsetter library. (Garret Rieger)
-- Improved Unicode 14 properties in the USE shaper, and various other USE
- shaper fixes. (David Corbett)
-- MATH and COLR v1 tables subsetting support, and various other subsetter fixes.
- (Qunxin Liu)
-- Support for Pwo Karen / Ason Chin medial la. (Simon Cozens)
-- Apply GPOS positioning when substituting with morx table, if kerx is missing.
- (Behdad Esfahbod)
-- Apply calt and clig features across syllable boundaries in Indic shaper.
- (Behdad Esfahbod)
-- meson option for enabling Graphite 2 has been renamed to graphite2.
-- Build and documentation fixes.
-
-- New API:
-+hb_buffer_set_not_found_glyph()
-+hb_buffer_get_not_found_glyph()
-
-
-Overview of changes leading to 3.0.0
-Friday, September 17, 2021
-====================================
-- Unicode 14.0 support (David Corbett).
-- The hb-subset API and the harfbuzz-subset library's ABI are now declared
- stable. The harfbuzz-subset library would not have been possible without the
- work of Garret Rieger and Qunxin Liu from Google Fonts, and the earlier work
- of Michiharu Ariza from Adobe.
-- The hb-style API is now stable and no longer experimental.
-
-- New API:
-+hb_style_tag_t
-+hb_style_get_value()
-+hb_subset_input_t
-+hb_subset_flags_t
-+hb_subset_sets_t
-+hb_subset_input_create_or_fail()
-+hb_subset_input_reference()
-+hb_subset_input_destroy()
-+hb_subset_input_set_user_data()
-+hb_subset_input_get_user_data()
-+hb_subset_input_unicode_set()
-+hb_subset_input_glyph_set()
-+hb_subset_input_set()
-+hb_subset_input_get_flags()
-+hb_subset_input_set_flags()
-+hb_subset_or_fail()
-
-- Removed old unstable harfbuzz-subset API:
--hb_subset_input_nameid_set()
--hb_subset_input_namelangid_set()
--hb_subset_input_layout_features_set()
--hb_subset_input_no_subset_tables_set()
--hb_subset_input_drop_tables_set()
--hb_subset_input_set_drop_hints()
--hb_subset_input_get_drop_hints()
--hb_subset_input_set_desubroutinize()
--hb_subset_input_get_desubroutinize()
--hb_subset_input_set_retain_gids()
--hb_subset_input_get_retain_gids()
--hb_subset_input_set_name_legacy()
--hb_subset_input_get_name_legacy()
--hb_subset_input_set_overlaps_flag()
--hb_subset_input_get_overlaps_flag()
--hb_subset_input_set_notdef_outline()
--hb_subset_input_get_notdef_outline()
--hb_subset_input_set_no_prune_unicode_ranges()
--hb_subset_input_get_no_prune_unicode_ranges()
--hb_subset()
-
-
-Overview of changes leading to 2.9.1
-Tuesday, September 7, 2021
-====================================
-- Final subset API is in place and if no issues are discovered, it will be the
- stable subset API of HarfBuzz 3.0.0. Old API is kept to ease transition, but
- will be removed in 3.0.0.
-- Various fuzzer-found bug fixes.
-- hb_buffer_append() now handles the pre- and post-context which previously
- were left unchanged in the destination buffer.
-- hb-view / hb-shape now accept following new arguments:
- o --unicodes-before/after: takes a list of hex numbers that represent Unicode
- codepoints.
-- Undeprecated API:
- hb_set_invert()
-
-
-Overview of changes leading to 2.9.0
-Wednesday, August 18, 2021
-History Repeats Itself (Afghanistan)
-====================================
-- Subsetter API is being stabilized, with the first stable API to happen in
- 3.0.0 release (https://github.com/harfbuzz/harfbuzz/issues/3078).
-- Support multiple variation axes with same tag, aka HOI.
-- The “coretext” testing shaper now passes font variations to CoreText.
-- hb-shape/hb-view does not break line at new lines unless text is read from
- file.
-- hb-view and hb-subset has a --batch now, similar to hb-shape.
-- The --batch mode now uses ; as argument separator instead of : used previously.
-- The --batch in hb-shape does not expect 0th argument anymore. That is, the
- lines read are interpreted as argv[1:], instead of argv[0:].
-- The --batch option has been undocumented. We are ready to document it; send
- feedback if you find it useful.
-- hb-subset got arguments revamps. Added much-requested --gids-file, --glyphs,
- --glyphs-file, --unicodes-file, supporting ranges in --unicodes.
-- Various bug fixes.
-
-
-Overview of changes leading to 2.8.2
-Tuesday, July 8, 2021
-====================================
-- Shaping LTR digits for RTL scripts now makes the native direction of the
- digits LTR, applying shaping and positioning rules on the same glyph order as
- Uniscribe. (Jonathan Kew, Khaled Hosny).
-- Subsetting COLR v1 and CPAL tables is now supported. (Garret Rieger, Qunxin Liu)
-- Various fixes and improvements to the subsetter. (Garret Rieger, Qunxin Liu, Behdad)
-- When applying morx table, mark glyph widths should not be zeroed. (Jonathan Kew)
-- GPOS is preferred over kerx, if GSUB was applied. (Behdad)
-- Regional_Indicator pairs are grouped together when clustering. (Behdad)
-- New API:
-+hb_blob_create_or_fail()
-+hb_blob_create_from_file_or_fail()
-+hb_set_copy()
-
-
-Overview of changes leading to 2.8.1
-Tuesday, May 4, 2021
-====================================
-- Subsetter now fully supports GSUB/GPOS/GDEF tables (including variations); as
- such, layout tables are retained by subsetter by default. (Garret Rieger, Qunxin Liu)
-- Build scripts no longer check for FontConfig as HarfBuzz does not use it.
-- hb-view supports iTerm2 and kitty inline image protocols (Khaled Hosny),
- it can also use Chafa for terminal graphics if available (Hans Petter Jansson).
-
-Overview of changes leading to 2.8.0
-Tuesday, March 16, 2021
-====================================
-- Shape joining scripts other than Arabic/Syriac using the Universal Shaping Engine.
- Previously these were shaped using the generalized Arabic shaper. (David Corbett)
-- Fix regression in shaping of U+0B55 ORIYA SIGN OVERLINE. (David Corbett)
-- Update language tags. (David Corbett)
-- Variations: reduce error: do not round each interpolated delta. (Just van Rossum)
-- Documentation improvements. (Khaled Hosny, Nathan Willis)
-- Subsetter improvements: subsets most, if not all, lookup types now. (Garret Rieger, Qunxin Liu)
-- Fuzzer-found fixes and other improvements when memory failures happen. (Behdad)
-- Removed most atomic implementations now that we have C++11 atomic impl. (Behdad)
-- General codebase upkeep; using more C++11 features: constexpr constructors, etc. (Behdad)
-
-
-Overview of changes leading to 2.7.4
-Sunday, December 27, 2020
-====================================
-- Fix missing --enable-introspection configure option from previous release
- tarball.
-- Documentation updates.
-
-
-Overview of changes leading to 2.7.3
-Wednesday, December 23, 2020
-====================================
-- Update USE shaper to 2020-08-13 specification, and other improvements.
-- Don’t disable liga feature in myanmar shaper, to match Uniscribe.
-- Improvements to language and script tags handling.
-- Update language system tag registry to OpenType 1.8.4
-- Support for serializing and deserializing Unicode buffers. Serialized buffers
- are now delimited with `<>` or `[]` based on whether it is a Unicode or
- glyphs buffer.
-- Increase buffer work limits to handle fonts with many complex lookups.
-- Handle more shaping operations in trace output.
-- Memory access fixes.
-- More OOM fixes.
-- Improved documentation.
-- Build system improvements.
-- New API:
-+hb_buffer_has_positions()
-+hb_buffer_serialize()
-+hb_buffer_serialize_unicode()
-+hb_buffer_deserialize_unicode()
-
-
-Overview of changes leading to 2.7.2
-Saturday, August 29, 2020
-====================================
-- Fix a regression in the previous release that caused a crash with Kaithi.
-- More OOM fixes.
-
-
-Overview of changes leading to 2.7.1
-Thursday, August 13, 2020
-====================================
-- ot-funcs now handles variable empty glyphs better when hvar/vvar isn't present.
-- Reverted a GDEF processing regression.
-- A couple of fixes to handle OOM better.
-
-
-Overview of changes leading to 2.7.0
-Saturday, July 25, 2020
-====================================
-- Use an implementation for round that always rounds up, some minor fluctuations
- are expected on var font specially when hb-ot callback is used.
-- Fix an AAT's `kerx` issue on broken rendering of Devanagari Sangam MN.
-- Remove AAT's `lcar` table support from _get_ligature_carets API, not even much
- use on macOS installed fonts (only two files). GDEF support is the recommended
- one and expected to work properly after issues fixed two releases ago.
-- Minor memory fixes to handle OOM better specially in hb-ft.
-- Minor .so files versioning scheme change and remove stable/unstable scheme
- differences, was never used in practice (always default to stable scheme).
-- We are now suggesting careful packaging of the library using meson,
- https://github.com/harfbuzz/harfbuzz/wiki/Notes-on-migration-to-meson
- for more information.
-- Distribution package URL is changed, either use GitHub generated tarballs,
- `https://github.com/harfbuzz/harfbuzz/archive/$pkgver.tar.gz`
- or, even more preferably use commit hash of the release and git checkouts like,
- `git+https://github.com/harfbuzz/harfbuzz#commit=$commit`
-
-
-Overview of changes leading to 2.6.8
-Monday, June 22, 2020
-====================================
-- New API to fetch glyph alternates from GSUB table.
-- hb-coretext build fix for macOS < 10.10.
-- Meson build fixes, cmake port removal is postponed but please prepare for
- it and give us feedback.
- Autotools is still our main build system however please consider
- experimenting with meson also for packaging the library.
-- New API:
-+hb_ot_layout_lookup_get_glyph_alternates()
-
-
-Overview of changes leading to 2.6.7
-Wednesday, June 3, 2020
-====================================
-- Update to Unicode 13.0.0.
-- Fix hb_ot_layout_get_ligature_carets for fonts without lcar table, it was
- completely broken for all the other fonts since 2.1.2.
-- As a part of our migration to meson, this release will be the last one
- to provide cmake port files but autotools still is our main build system.
- There is a possibility that the next version or the after be released
- using meson.
-
-
-Overview of changes leading to 2.6.6
-Tuesday, May 12, 2020
-====================================
-- A fix in AAT kerning for Geeza Pro.
-- Better support for resource fork fonts on macOS.
-
-
-Overview of changes leading to 2.6.5
-Friday, April 17, 2020
-====================================
-- Add experimental meson build system. Autotools is still the primary
- and supported build system.
-- AAT is now always preferred for horizontal scripts when both AAT and OT
- layout tables exist at the same time.
-- Subsetter improvements.
-- New API:
-+hb_ft_font_lock_face()
-+hb_ft_font_unlock_face()
-
-
-Overview of changes leading to 2.6.4
-Monday, October 29, 2019
-====================================
-- Small bug fix.
-- Build fixes.
-
-
-Overview of changes leading to 2.6.3
-Monday, October 28, 2019
-====================================
-- Misc small fixes, mostly to build-related issues.
-- New API:
-+hb_font_get_nominal_glyphs()
-
-
-Overview of changes leading to 2.6.2
-Monday, September 30, 2019
-====================================
-- Misc small fixes, mostly to build-related issues.
-
-
-Overview of changes leading to 2.6.1
-Thursday, August 22, 2019
-====================================
-- Fix regression with hb_font_create_sub_font scaling introduced in 2.6.0.
-- Change interpretation of font PTEM size / CoreText font size handling.
- See https://github.com/harfbuzz/harfbuzz/pull/1484
-- hb-ot-font: Prefer symbol cmap subtable if present.
-- Apply 'dist'/'abvm'/'blwm' features to all scripts.
-- Drop experimental DirectWrite API.
-
-
-Overview of changes leading to 2.6.0
-Tuesday, August 13, 2019
-====================================
-- New OpenType metrics, baseline, and metadata table access APIs.
-- New API to set font variations to a named-instance.
-- New hb-gdi.h header and API for creating hb_face_t from HFONT.
-- Amalgam: Provide a single-file harfbuzz.cc file for easier alternate building.
-- More size-reduction configurable options, enabled by HB_TINY.
-- New API:
-+hb_font_set_var_named_instance()
-+hb_gdi_face_create()
-+hb_ot_layout_baseline_tag_t
-+hb_ot_layout_get_baseline()
-+hb_ot_meta_tag_t
-+hb_ot_meta_get_entry_tags()
-+hb_ot_meta_reference_entry()
-+hb_ot_metrics_tag_t
-+hb_ot_metrics_get_position()
-+hb_ot_metrics_get_variation()
-+hb_ot_metrics_get_x_variation()
-+hb_ot_metrics_get_y_variation()
-
-
-Overview of changes leading to 2.5.3
-Wednesday, June 26, 2019
-====================================
-- Fix UCD script data for Unicode 10+ scripts. This was broken since 2.5.0.
-- More optimizations for HB_TINY.
-
-
-Overview of changes leading to 2.5.2
-Thursday, June 20, 2019
-====================================
-- More hb-config.hh facilities to shrink library size, namely when built as
- HB_TINY.
-- New documentation of custom configurations in CONFIG.md.
-- Fix build on gcc 4.8. That's supported again.
-- Universal Shaping Engine improvements thanks to David Corbett.
-- API Changes: Undeprecate some horizontal-kerning API and re-enable in hb-ft,
- such that Type1 fonts will continue kerning.
-
-
-Overview of changes leading to 2.5.1
-Friday, May 31, 2019
-====================================
-- Fix build with various versions of Visual Studio.
-- Improved documentation, thanks to Nathan Willis.
-- Bugfix in subsetting glyf table.
-- Improved scripts for cross-compiling for Windows using mingw.
-- Rename HB_MATH_GLYPH_PART_FLAG_EXTENDER to HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER.
- A deprecated macro is added for backwards-compatibility.
-
-
-Overview of changes leading to 2.5.0
-Friday, May 24, 2019
-====================================
-- This release does not include much functional changes, but includes major internal
- code-base changes. We now require C++11. Support for gcc 4.8 and earlier has been
- dropped.
-- New hb-config.hh facility for compiling smaller library for embedded and web usecases.
-- New Unicode Character Database implementation that is half the size of previously-used
- UCDN.
-- Subsetter improvements.
-- Improved documentation, thanks to Nathan Willis.
-- Misc shaping fixes.
-
-
-Overview of changes leading to 2.4.0
-Monday, March 25, 2019
-====================================
-- Unicode 12.
-- Misc fixes.
-- Subsetter improvements.
-- New API:
-HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE
-hb_directwrite_face_create()
-
-
-Overview of changes leading to 2.3.1
-Wednesday, January 30, 2019
-====================================
-- AAT bug fixes.
-- Misc internal housekeeping cleanup.
-
-
-Overview of changes leading to 2.3.0
-Thursday, December 20, 2018
-====================================
-- Fix regression on big-endian architectures. Ouch!
-- Misc bug and build fixes.
-- Fix subsetting of simple GSUB/GDEF.
-- Merge CFF / CFF2 support contributed by Adobe. This mostly involves
- the subsetter, but also get_glyph_extents on CFF fonts.
-
-New API in hb-aat.h:
-+hb_aat_layout_has_substitution()
-+hb_aat_layout_has_positioning()
-+hb_aat_layout_has_tracking()
-
-
-Overview of changes leading to 2.2.0
-Thursday, November 29, 2018
-====================================
-- Misc shaping bug fixes.
-- Add font variations named-instance API.
-- Deprecate font variations axis enumeration API and add replacement.
-- AAT shaping improvements:
- o Fixed 'kern' table Format 2 implementation.
- o Implement 'feat' table API for feature detection.
- o Blacklist 'GSUB' table of fonts from 'MUTF' foundry that also have 'morx'.
-
-New API:
-+hb_aat_layout_feature_type_t
-+hb_aat_layout_feature_selector_t
-+hb_aat_layout_get_feature_types()
-+hb_aat_layout_feature_type_get_name_id
-+hb_aat_layout_feature_selector_info_t
-+HB_AAT_LAYOUT_NO_SELECTOR_INDEX
-+hb_aat_layout_feature_type_get_selector_infos()
-+hb_ot_var_axis_flags_t
-+hb_ot_var_axis_info_t
-+hb_ot_var_get_axis_infos()
-+hb_ot_var_find_axis_info()
-+hb_ot_var_get_named_instance_count()
-+hb_ot_var_named_instance_get_subfamily_name_id()
-+hb_ot_var_named_instance_get_postscript_name_id()
-+hb_ot_var_named_instance_get_design_coords()
-
-Deprecated API:
-+HB_OT_VAR_NO_AXIS_INDEX
-+hb_ot_var_axis_t
-+hb_ot_var_get_axes()
-+hb_ot_var_find_axis()
-
-
-Overview of changes leading to 2.1.3
-Friday, November 16, 2018
-====================================
-- Fix AAT 'mort' shaping, which was broken in 2.1.2
-
-
-Overview of changes leading to 2.1.2
-Friday, November 16, 2018
-====================================
-- Various internal changes.
-- AAT shaping improvements:
- o Implement kern table Format 1 state-machine-based kerning.
- o Implement cross-stream kerning (cursive positioning, etc).
- o Ignore emptyish GSUB tables (zero scripts) if morx present.
- o Don't apply GPOS if morx is being applied. Matches Apple.
-
-
--Overview of changes leading to 2.1.1
-Monday, November 5, 2018
-====================================
-- AAT improvements:
- o Implement 'mort' table.
- o Implement 'kern' subtables Format 1 and Format 3.
-
-
-Overview of changes leading to 2.1.0
-Tuesday, October 30, 2018
-====================================
-- AAT shaping improvements:
- o Allow user controlling AAT features, for whole buffer only currently.
- o Several 'morx' fixes.
- o Implement tuple-kerns in 'kerx'; Fixes kerning with Apple default
- San Francisco fonts.
-- Support for color fonts:
- o COLR/CPAL API to fetch color layers.
- o SVG table to fetch SVG documents.
- o CBDT/sbix API to fetch PNG images.
-- New 'name' table API.
-- hb-ot-font now uses 'VORG' table to correctly position CFF glyphs
- in vertical layout.
-- Various fuzzer-found bug fixes.
-
-Changed API:
-
-A type and a macro added in 2.0.0 were renamed:
-
-hb_name_id_t -> hb_ot_name_id_t
-HB_NAME_ID_INVALID -> HB_OT_NAME_ID_INVALID
-
-New API:
-
-+hb_color_t
-+HB_COLOR
-+hb_color_get_alpha()
-+hb_color_get_red()
-+hb_color_get_green()
-+hb_color_get_blue()
-+hb_ot_color_has_palettes()
-+hb_ot_color_palette_get_count()
-+hb_ot_color_palette_get_name_id()
-+hb_ot_color_palette_color_get_name_id()
-+hb_ot_color_palette_flags_t
-+hb_ot_color_palette_get_flags()
-+hb_ot_color_palette_get_colors()
-+hb_ot_color_has_layers()
-+hb_ot_color_layer_t
-+hb_ot_color_glyph_get_layers()
-+hb_ot_color_has_svg()
-+hb_ot_color_glyph_reference_svg()
-+hb_ot_color_has_png()
-+hb_ot_color_glyph_reference_png()
-
-+hb_ot_name_id_t
-+HB_OT_NAME_ID_INVALID
-+HB_OT_NAME_ID_COPYRIGHT
-+HB_OT_NAME_ID_FONT_FAMILY
-+HB_OT_NAME_ID_FONT_SUBFAMILY
-+HB_OT_NAME_ID_UNIQUE_ID
-+HB_OT_NAME_ID_FULL_NAME
-+HB_OT_NAME_ID_VERSION_STRING
-+HB_OT_NAME_ID_POSTSCRIPT_NAME
-+HB_OT_NAME_ID_TRADEMARK
-+HB_OT_NAME_ID_MANUFACTURER
-+HB_OT_NAME_ID_DESIGNER
-+HB_OT_NAME_ID_DESCRIPTION
-+HB_OT_NAME_ID_VENDOR_URL
-+HB_OT_NAME_ID_DESIGNER_URL
-+HB_OT_NAME_ID_LICENSE
-+HB_OT_NAME_ID_LICENSE_URL
-+HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY
-+HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY
-+HB_OT_NAME_ID_MAC_FULL_NAME
-+HB_OT_NAME_ID_SAMPLE_TEXT
-+HB_OT_NAME_ID_CID_FINDFONT_NAME
-+HB_OT_NAME_ID_WWS_FAMILY
-+HB_OT_NAME_ID_WWS_SUBFAMILY
-+HB_OT_NAME_ID_LIGHT_BACKGROUND
-+HB_OT_NAME_ID_DARK_BACKGROUND
-+HB_OT_NAME_ID_VARIATIONS_PS_PREFIX
-+hb_ot_name_entry_t
-+hb_ot_name_list_names()
-+hb_ot_name_get_utf8()
-+hb_ot_name_get_utf16()
-+hb_ot_name_get_utf32()
-
-
-Overview of changes leading to 2.0.2
-Saturday, October 20, 2018
-====================================
-- Fix two minor memory access issues in AAT tables.
-
-
-Overview of changes leading to 2.0.1
-Friday, October 19, 2018
-====================================
-- Fix hb-version.h reported release version that went wrong (1.8.0)
- with previous release.
-- Fix extrapolation in 'trak' table.
-- Fix hb-font infinite-recursion issue with some font funcs and
- subclassed fonts.
-- Implement variation-kerning format in kerx table, although without
- variation.
-- Fix return value of hb_map_is_empty().
-
-
-Overview of changes leading to 2.0.0
-Thursday, October 18, 2018
-====================================
-- Added AAT shaping support (morx/kerx/trak).
- Automatically used if GSUB/GPOS are not available respectively.
- Set HB_OPTIONS=aat env var to have morx/kerx preferred over
- GSUB/GPOS.
-- Apply TrueType kern table internally, instead of relying on
- hb_font_t callbacks.
-- Khmer shaper significantly rewritten to better match Uniscribe.
-- Indic3 tags ('dev3', etc) are passed to USE shaper.
-- .dfont Mac font containers implemented.
-- Script- and language-mapping revamped to better use BCP 47.
-- Misc USE and Indic fixes.
-- Misc everything fixes.
-- Too many things to list. Biggest release since 0.9.1, with
- over 500 commits in just over 5 weeks! Didn't intend it to
- be a big release. Just happened to become.
-- hb-ft now locks underlying FT_Face during use.
-
-API changes:
-
-- Newly-created hb_font_t's now have our internal "hb-ot-font"
- callbacks set on them, so they should work out of the box
- without any callbacks set. If callbacks are set, everything
- is back to what it was before, the fallback callbacks are
- null. If you to get the internal implementation modified,
- sub_font it.
-
-- New hb_font_funcs_set_nominal_glyphs_func() allows speeding
- up character to glyph mapping.
-
-New API:
-+HB_FEATURE_GLOBAL_START
-+HB_FEATURE_GLOBAL_END
-+hb_buffer_set_invisible_glyph()
-+hb_buffer_get_invisible_glyph()
-+hb_font_funcs_set_nominal_glyphs_func()
-+hb_ot_layout_table_select_script()
-+hb_ot_layout_script_select_language()
-+hb_ot_layout_feature_get_name_ids()
-+hb_ot_layout_feature_get_characters()
-+hb_name_id_t
-+HB_NAME_ID_INVALID
-+HB_OT_MAX_TAGS_PER_SCRIPT
-+hb_ot_tags_from_script_and_language()
-+hb_ot_tags_to_script_and_language()
-
-Deprecated API:
--hb_font_funcs_set_glyph_func()
--hb_unicode_eastasian_width_func_t
--hb_unicode_funcs_set_eastasian_width_func()
--hb_unicode_eastasian_width()
--hb_unicode_decompose_compatibility_func_t
--HB_UNICODE_MAX_DECOMPOSITION_LEN
--hb_unicode_funcs_set_decompose_compatibility_func()
--hb_unicode_decompose_compatibility()
--hb_font_funcs_set_glyph_h_kerning_func()
--hb_font_funcs_set_glyph_v_kerning_func()
--hb_font_get_glyph_h_kerning()
--hb_font_get_glyph_v_kerning()
--hb_font_get_glyph_kerning_for_direction()
--hb_ot_layout_table_choose_script()
--hb_ot_layout_script_find_language()
--hb_ot_tags_from_script()
--hb_ot_tag_from_language()
-
-
-Overview of changes leading to 1.9.0
-Monday, September 10, 2018
-====================================
-- Added 'cmap' API to hb_face_t.
-- Face-builder API.
-- hb-ot-font re-creation should be much leaner now, as the
- font tables it uses are cached on hb_face_t now.
-- Internal source header file name changes:
- hb-*-private.hh is renamed to hb-*.hh.
-
-New API:
-+HB_UNICODE_MAX
-+hb_face_collect_unicodes()
-+hb_face_collect_variation_selectors()
-+hb_face_collect_variation_unicodes()
-+hb_face_builder_create()
-+hb_face_builder_add_table()
-
-
-Overview of changes leading to 1.8.8
-Tuesday, August 14, 2018
-====================================
-- Fix hb-icu crash on architectures where compare_exchange_weak() can
- fail falsely. This bug was introduced in 1.8.4.
- https://bugs.chromium.org/p/chromium/issues/detail?id=873568
-- More internal refactoring of atomic operations and singletons.
-- API changes:
- The following functions do NOT reference their return value before
- returning:
- * hb_unicode_funcs_get_default()
- * hb_glib_get_unicode_funcs()
- * hb_icu_get_unicode_funcs()
- This is consistent with their naming ("get", instead of "reference")
- as well as how they are used in the wild (ie. no one calls destroy()
- on their return value.)
-
-
-Overview of changes leading to 1.8.7
-Wednesday, August 8, 2018
-====================================
-- Fix assertion failure with GDEF-blacklisted fonts.
-
-
-Overview of changes leading to 1.8.6
-Tuesday, August 7, 2018
-====================================
-- Internal code shuffling.
-- New API to speed up getting advance widths for implementations
- that have heavy overhead in get_h_advance callback:
-+hb_font_funcs_set_glyph_h_advances_func
-+hb_font_funcs_set_glyph_v_advances_func
-+hb_font_get_glyph_advances_for_direction
-+hb_font_get_glyph_h_advances
-+hb_font_get_glyph_h_advances_func_t
-+hb_font_get_glyph_v_advances
-+hb_font_get_glyph_v_advances_func_t
-
-
-Overview of changes leading to 1.8.5
-Wednesday, August 1, 2018
-====================================
-- Major Khmer shaper improvements to better match Microsoft.
-- Indic bug fixes.
-- Internal improvements to atomic operations.
-
-
-Overview of changes leading to 1.8.4
-Tuesday, July 17, 2018
-====================================
-- Fix build on non-C++11.
-- Use C++-style GCC atomics and C++11 atomics.
-
-
-Overview of changes leading to 1.8.3
-Wednesday, July 11, 2018
-====================================
-- A couple of Indic / USE bug fixes.
-- Disable vectorization, as it was causing unaligned access bus error on
- certain 32bit architectures.
-
-
-Overview of changes leading to 1.8.2
-Tuesday, July 3, 2018
-====================================
-- Fix infinite loop in Khmer shaper.
-- Improve hb_blob_create_from_file() for streams.
-
-
-Overview of changes leading to 1.8.1
-Tuesday, June 12, 2018
-====================================
-- Fix hb-version.h file generation; last two releases went out with wrong ones.
-- Add correctness bug in hb_set_t operations, introduced in 1.7.7.
-- Remove HB_SUBSET_BUILTIN build option. Not necessary.
-
-
-Overview of changes leading to 1.8.0
-Tuesday, June 5, 2018
-====================================
-- Update to Unicode 11.0.0.
-
-
-Overview of changes leading to 1.7.7
-Tuesday, June 5, 2018
-====================================
-- Lots of internal changes, but not yet exposed externally.
-- All HarfBuzz objects are significantly smaller in size now.
-- Sinhala: Position repha on top of post-consonant, not base.
- This better matches Windows 10 behavior, which was changed
- from previous Windows versions.
-- New build options:
- o New cpp macro HB_NO_ATEXIT
- o New cpp macro HB_SUBSET_BUILTIN
-- Significant libharfbuzz-subset changes. API subject to change.
-- New API in libharfbuzz:
-
-+hb_blob_create_from_file()
-+hb_face_count()
-
-A hashmap implementation:
-+hb-map.h
-+HB_MAP_VALUE_INVALID
-+hb_map_t
-+hb_map_create()
-+hb_map_get_empty()
-+hb_map_reference()
-+hb_map_destroy()
-+hb_map_set_user_data()
-+hb_map_get_user_data()
-+hb_map_allocation_successful()
-+hb_map_clear()
-+hb_map_is_empty()
-+hb_map_get_population()
-+hb_map_set()
-+hb_map_get()
-+hb_map_del()
-+hb_map_has()
-
-
-Overview of changes leading to 1.7.6
-Wednesday, March 7, 2018
-====================================
-
-- Fix to hb_set_t binary operations. Ouch.
-- New experimental harfbuzz-subset library. All of hb-subset.h
- is experimental right now and API WILL change.
-
-- New API:
-hb_blob_copy_writable_or_fail()
-HB_OT_TAG_BASE
-hb_set_previous()
-hb_set_previous_range()
-
-
-Overview of changes leading to 1.7.5
-Tuesday, January 30, 2018
-====================================
-
-- Separate Khmer shaper from Indic.
-- First stab at AAT morx. Not hooked up.
-- Misc bug fixes.
-
-
Overview of changes leading to 1.7.4
Wednesday, December 20, 2017
====================================
@@ -1863,7 +415,7 @@ Thursday, February 25, 2016
due to bug in glyph class of ASCII double-quote character. This should
address "regression" introduced in 1.2.0 when we switched mark zeroing
in most shapers from BY_UNICODE_LATE to BY_GDEF_LATE.
- This fourth release in a week should finally stabilize things...
+ This fourth release in a week should finally stablize things...
- hb-ot-font's get_glyph() implementation saw some optimizations. Though,
might be really hard to measure in real-world situations.
@@ -2911,7 +1463,7 @@ o Changed API:
- hb_buffer_create() takes zero arguments now.
Use hb_buffer_pre_allocate() to pre-allocate.
- - hb_buffer_add_utf*() now accept -1 for length parameters,
+ - hb_buffer_add_utf*() now accept -1 for length parameteres,
meaning "nul-terminated".
- hb_direction_t enum values changed.
diff --git a/src/3rdparty/harfbuzz-ng/THANKS b/src/3rdparty/harfbuzz-ng/THANKS
index 88cb7e9ea12..940cfde5c39 100644
--- a/src/3rdparty/harfbuzz-ng/THANKS
+++ b/src/3rdparty/harfbuzz-ng/THANKS
@@ -1,6 +1,6 @@
Bradley Grainger
+Khaled Hosny
Kenichi Ishibashi
-Ivan Kuckir <https://photopea.com/>
Ryan Lortie
Jeff Muizelaar
suzuki toshiya
diff --git a/src/3rdparty/harfbuzz-ng/config.h b/src/3rdparty/harfbuzz-ng/config.h
index 38087a71ef4..b8b6b3c0fe3 100644
--- a/src/3rdparty/harfbuzz-ng/config.h
+++ b/src/3rdparty/harfbuzz-ng/config.h
@@ -22,9 +22,6 @@
*
*/
-#ifndef QHARFBUZZ_CONFIG_H
-#define QHARFBUZZ_CONFIG_H
-
#include <QtCore/qatomic.h>
QT_USE_NAMESPACE
@@ -40,19 +37,11 @@ inline QAtomicPointer<T> *makeAtomicPointer(T * const &ptr)
return reinterpret_cast<QAtomicPointer<T> *>(const_cast<T **>(&ptr));
}
-static inline void _hb_memory_barrier ()
-{
- QAtomicInt a;
- a.ref(); // Ordered memory semantics, so imposes a memory barrier at this point
-}
-
} // namespace
typedef int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
-#define hb_atomic_int_impl_add(AI, V) reinterpret_cast<QAtomicInt *>(AI)->fetchAndAddOrdered(V)
+#define hb_atomic_int_impl_add(AI, V) reinterpret_cast<QAtomicInt &>(AI).fetchAndAddOrdered(V)
#define hb_atomic_ptr_impl_get(P) makeAtomicPointer(*(P))->loadAcquire()
#define hb_atomic_ptr_impl_cmpexch(P,O,N) makeAtomicPointer(*(P))->testAndSetOrdered((O), (N))
-
-#endif // QHARFBUZZ_CONFIG_H
diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
index f55b31fff4b..19699389321 100644
--- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
+++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
@@ -14,11 +14,11 @@ SHAPERS += opentype # HB's main shaper; enabling it should be enough most
# native shaper on Apple platforms; could be used alone to handle both OT and AAT fonts
darwin: SHAPERS += coretext
-# fallback shaper: not really useful with opentype or coretext shaper but needed for linking
-SHAPERS += fallback
+# fallback shaper: not really useful with opentype or coretext shaper
+#SHAPERS += fallback
DEFINES += HAVE_CONFIG_H
-DEFINES += HB_NO_UNICODE_FUNCS
+DEFINES += HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED
DEFINES += HB_NDEBUG
DEFINES += HB_EXTERN=
@@ -35,46 +35,35 @@ INCLUDEPATH += $$QT.core.includes
DEFINES += QT_NO_VERSION_TAGGING
SOURCES += \
- $$PWD/hb-dummy.cc \
- $$PWD/src/hb-aat-layout.cc \
- $$PWD/src/hb-aat-map.cc \
$$PWD/src/hb-blob.cc \
$$PWD/src/hb-buffer.cc \
$$PWD/src/hb-buffer-serialize.cc \
$$PWD/src/hb-common.cc \
- $$PWD/src/hb-draw.cc \
$$PWD/src/hb-face.cc \
- $$PWD/src/hb-face-builder.cc \
$$PWD/src/hb-font.cc \
- $$PWD/src/hb-map.cc \
- $$PWD/src/hb-number.cc \
$$PWD/src/hb-ot-tag.cc \
- $$PWD/src/hb-outline.cc \
- $$PWD/src/hb-paint.cc \
- $$PWD/src/hb-paint-extents.cc \
$$PWD/src/hb-set.cc \
$$PWD/src/hb-shape.cc \
$$PWD/src/hb-shape-plan.cc \
$$PWD/src/hb-shaper.cc \
- $$PWD/src/hb-style.cc \
- $$PWD/src/hb-subset.cc \
- $$PWD/src/hb-subset-cff-common.cc \
- $$PWD/src/hb-subset-cff1.cc \
- $$PWD/src/hb-subset-cff2.cc \
- $$PWD/src/hb-subset-input.cc \
- $$PWD/src/hb-subset-instancer-solver.cc \
- $$PWD/src/hb-subset-plan.cc \
- $$PWD/src/hb-subset-repacker.cc \
$$PWD/src/hb-unicode.cc \
- $$PWD/src/hb-buffer-verify.cc
+ $$PWD/src/hb-warning.cc
HEADERS += \
+ $$PWD/src/hb-atomic-private.hh \
+ $$PWD/src/hb-buffer-private.hh \
$$PWD/src/hb-buffer-deserialize-json.hh \
- $$PWD/src/hb-buffer-deserialize-text-glyphs.hh \
- $$PWD/src/hb-buffer-deserialize-text-unicode.hh \
+ $$PWD/src/hb-buffer-deserialize-text.hh \
+ $$PWD/src/hb-cache-private.hh \
$$PWD/src/hb-debug.hh \
- $$PWD/src/hb-face.hh \
- $$PWD/src/hb-mutex.hh \
+ $$PWD/src/hb-dsalgs.hh \
+ $$PWD/src/hb-face-private.hh \
+ $$PWD/src/hb-font-private.hh \
+ $$PWD/src/hb-mutex-private.hh \
+ $$PWD/src/hb-object-private.hh \
+ $$PWD/src/hb-open-file-private.hh \
+ $$PWD/src/hb-open-type-private.hh \
+ $$PWD/src/hb-ot-cbdt-table.hh \
$$PWD/src/hb-ot-cmap-table.hh \
$$PWD/src/hb-ot-glyf-table.hh \
$$PWD/src/hb-ot-head-table.hh \
@@ -84,119 +73,83 @@ HEADERS += \
$$PWD/src/hb-ot-name-table.hh \
$$PWD/src/hb-ot-os2-table.hh \
$$PWD/src/hb-ot-post-table.hh \
- $$PWD/src/hb-set.hh \
- $$PWD/src/hb-set-digest.hh \
- $$PWD/src/hb-shape-plan.hh \
- $$PWD/src/hb-shaper.hh \
- $$PWD/src/hb-shaper-impl.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-subset-repacker.h \
- $$PWD/src/hb-unicode.hh
+ $$PWD/src/hb-unicode-private.hh \
+ $$PWD/src/hb-utf-private.hh
HEADERS += \
$$PWD/src/hb.h \
- $$PWD/src/hb-algs.hh \
- $$PWD/src/hb-atomic.hh \
$$PWD/src/hb-blob.h \
$$PWD/src/hb-buffer.h \
- $$PWD/src/hb-buffer.hh \
- $$PWD/src/hb-cache.hh \
$$PWD/src/hb-common.h \
$$PWD/src/hb-deprecated.h \
- $$PWD/src/hb-draw.h \
- $$PWD/src/hb-draw.hh \
$$PWD/src/hb-face.h \
$$PWD/src/hb-font.h \
- $$PWD/src/hb-font.hh \
- $$PWD/src/hb-ft-colr.hh \
- $$PWD/src/hb-limits.hh \
- $$PWD/src/hb-map.h \
- $$PWD/src/hb-map.hh \
- $$PWD/src/hb-object.hh \
- $$PWD/src/hb-open-file.hh \
- $$PWD/src/hb-open-type.hh \
- $$PWD/src/hb-ot-cff1-std-str.hh \
- $$PWD/src/hb-outline.hh \
- $$PWD/src/hb-paint.h \
- $$PWD/src/hb-paint.hh \
- $$PWD/src/hb-paint-extents.hh \
- $$PWD/src/hb-priority-queue.hh \
- $$PWD/src/hb-repacker.hh \
$$PWD/src/hb-set.h \
$$PWD/src/hb-shape.h \
$$PWD/src/hb-shape-plan.h \
- $$PWD/src/hb-style.h \
$$PWD/src/hb-unicode.h \
- $$PWD/src/hb-utf.hh \
$$PWD/src/hb-version.h
contains(SHAPERS, opentype) {
DEFINES += HAVE_OT
SOURCES += \
- $$PWD/src/hb-ot-cff1-table.cc \
- $$PWD/src/hb-ot-cff2-table.cc \
- $$PWD/src/hb-ot-color.cc \
- $$PWD/src/hb-ot-face.cc \
$$PWD/src/hb-ot-font.cc \
$$PWD/src/hb-ot-layout.cc \
$$PWD/src/hb-ot-map.cc \
$$PWD/src/hb-ot-math.cc \
- $$PWD/src/hb-ot-meta.cc \
- $$PWD/src/hb-ot-metrics.cc \
- $$PWD/src/hb-ot-name.cc \
$$PWD/src/hb-ot-shape.cc \
- $$PWD/src/hb-ot-shaper-arabic.cc \
- $$PWD/src/hb-ot-shaper-default.cc \
- $$PWD/src/hb-ot-shaper-hangul.cc \
- $$PWD/src/hb-ot-shaper-hebrew.cc \
- $$PWD/src/hb-ot-shaper-indic.cc \
- $$PWD/src/hb-ot-shaper-thai.cc \
+ $$PWD/src/hb-ot-shape-complex-arabic.cc \
+ $$PWD/src/hb-ot-shape-complex-default.cc \
+ $$PWD/src/hb-ot-shape-complex-hangul.cc \
+ $$PWD/src/hb-ot-shape-complex-hebrew.cc \
+ $$PWD/src/hb-ot-shape-complex-indic.cc \
+ $$PWD/src/hb-ot-shape-complex-indic-table.cc \
+ $$PWD/src/hb-ot-shape-complex-myanmar.cc \
+ $$PWD/src/hb-ot-shape-complex-thai.cc \
+ $$PWD/src/hb-ot-shape-complex-tibetan.cc \
+ $$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-shaper-indic-table.cc \
- $$PWD/src/hb-ot-shaper-khmer.cc \
- $$PWD/src/hb-ot-shaper-myanmar.cc \
- $$PWD/src/hb-ot-shaper-syllabic.cc \
- $$PWD/src/hb-ot-shaper-use.cc \
- $$PWD/src/hb-ot-shaper-vowel-constraints.cc \
- $$PWD/src/hb-ot-var.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 \
+ $$PWD/src/hb-ot-layout-gsubgpos-private.hh \
$$PWD/src/hb-ot-layout-gsub-table.hh \
$$PWD/src/hb-ot-layout-jstf-table.hh \
- $$PWD/src/hb-ot-layout.hh \
- $$PWD/src/hb-ot-map.hh \
+ $$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-post-table-v2subset.hh \
- $$PWD/src/hb-ot-shaper-arabic-joining-list.hh \
- $$PWD/src/hb-ot-shaper-arabic-pua.hh \
- $$PWD/src/hb-ot-shaper-indic-machine.hh \
- $$PWD/src/hb-ot-shaper-arabic-fallback.hh \
- $$PWD/src/hb-ot-shaper-arabic.hh \
- $$PWD/src/hb-ot-shaper-arabic-table.hh \
-# $$PWD/src/hb-ot-shaper-arabic-win1256.hh \ # disabled with HB_NO_WIN1256
- $$PWD/src/hb-ot-shaper.hh \
- $$PWD/src/hb-ot-shape-fallback.hh \
- $$PWD/src/hb-ot-shape-normalize.hh \
- $$PWD/src/hb-ot-shaper-indic.hh \
- $$PWD/src/hb-ot-shaper-khmer-machine.hh \
- $$PWD/src/hb-ot-shaper-myanmar-machine.hh \
- $$PWD/src/hb-ot-shaper-syllabic.hh \
- $$PWD/src/hb-ot-shaper-use-machine.hh \
- $$PWD/src/hb-ot-shaper-use-table.hh \
- $$PWD/src/hb-ot-shaper-vowel-constraints.hh \
- $$PWD/src/hb-subset-accelerator.hh \
- $$PWD/src/hb-ot-var-common.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 \
+# $$PWD/src/hb-ot-shape-complex-arabic-win1256.hh \ # disabled with HB_NO_WIN1256
+ $$PWD/src/hb-ot-shape-complex-indic-machine.hh \
+ $$PWD/src/hb-ot-shape-complex-indic-private.hh \
+ $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \
+ $$PWD/src/hb-ot-shape-complex-private.hh \
+ $$PWD/src/hb-ot-shape-complex-use-machine.hh \
+ $$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-var-avar-table.hh \
- $$PWD/src/hb-ot-var-cvar-table.hh \
$$PWD/src/hb-ot-var-fvar-table.hh \
- $$PWD/src/hb-ot-var-gvar-table.hh \
$$PWD/src/hb-ot-var-hvar-table.hh \
$$PWD/src/hb-ot-var-mvar-table.hh
@@ -206,17 +159,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-shape.hh \
- $$PWD/src/hb-ot-var.h \
- $$PWD/src/OT/Color/CBDT/CBDT.hh \
- $$PWD/src/OT/Color/COLR/COLR.hh \
- $$PWD/src/OT/Color/COLR/colrv1-closure.hh \
- $$PWD/src/OT/Color/CPAL/CPAL.hh \
- $$PWD/src/OT/Color/sbix/sbix.hh \
- $$PWD/src/OT/Color/svg/svg.hh \
- $$PWD/src/OT/Layout/GDEF/GDEF.hh \
- $$PWD/src/OT/name/name.hh
-
+ $$PWD/src/hb-ot-tag.h \
+ $$PWD/src/hb-ot-var.h
}
MODULE_EXT_HEADERS = $$HEADERS
@@ -225,7 +169,7 @@ contains(SHAPERS, coretext) {
DEFINES += HAVE_CORETEXT
SOURCES += \
- $$PWD/src/hb-coretext.cc
+ $$PWD/src/hb-coretext.mm
HEADERS += \
$$PWD/src/hb-coretext.h
diff --git a/src/3rdparty/harfbuzz-ng/hb-dummy.cc b/src/3rdparty/harfbuzz-ng/hb-dummy.cc
deleted file mode 100644
index 490b8ae35c8..00000000000
--- a/src/3rdparty/harfbuzz-ng/hb-dummy.cc
+++ /dev/null
@@ -1,8 +0,0 @@
-// Work-around for issue with qmake: Since hb-common.cc has #include "hb-static.cc" in it,
-// qmake will assume it is included and ignore it in the SOURCES list. But the #include
-// is protected inside an #ifdef and will not be used, so hb-static.cc ends up not being
-// linked at all and we get missing symbols. We work around this by including both in
-// the same compilation unit.
-
-#include "src/hb-common.cc"
-#include "src/hb-static.cc"
diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json
index d6807118963..2f1aed8a877 100644
--- a/src/3rdparty/harfbuzz-ng/qt_attribution.json
+++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json
@@ -3,31 +3,24 @@
"Name": "HarfBuzz-NG",
"QDocModule": "qtgui",
"QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz to force the use of the system library, or -qt-harfbuzz to link statically to the library that is bundled with your Qt version.",
- "SecurityCritical": true,
"Description": "HarfBuzz is an OpenType text shaping engine.",
"Homepage": "http://harfbuzz.org",
- "Version": "7.2.0",
- "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/7.1.0",
+ "Version": "1.7.4",
"License": "MIT License",
"LicenseId": "MIT",
"LicenseFile": "COPYING",
- "Copyright": "Copyright © 2010-2022 Google, Inc.
- Copyright © 2015-2020 Ebrahim Byagowi
- Copyright © 2019,2020 Facebook, Inc.
- Copyright © 2012,2015 Mozilla Foundation
- Copyright © 2011 Codethink Limited
- Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
- Copyright © 2009 Keith Stribley
- Copyright © 2011 Martin Hosken and SIL International
- Copyright © 2007 Chris Wilson
- Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod
- Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.
- Copyright © 1998-2005 David Turner and Werner Lemberg
- Copyright © 2016 Igalia S.L.
- Copyright © 2022 Matthias Clasen
- Copyright © 2018,2021 Khaled Hosny
- Copyright © 2018,2019,2020 Adobe, Inc
- Copyright © 2013-2015 Alexei Podtelezhnikov"
+ "Copyright": "Copyright © 2010,2011,2012 Google, Inc.
+Copyright © 2012 Mozilla Foundation
+Copyright © 2011 Codethink Limited
+Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
+Copyright © 2009 Keith Stribley
+Copyright © 2009 Martin Hosken and SIL International
+Copyright © 2007 Chris Wilson
+Copyright © 2006 Behdad Esfahbod
+Copyright © 2005 David Turner
+Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
+Copyright © 1998-2004 David Turner and Werner Lemberg
+"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh
deleted file mode 100644
index b125052344f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CBDT/CBDT.hh
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * Copyright © 2016 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): Seigo Nonaka, Calder Kitagawa
- */
-
-#ifndef OT_COLOR_CBDT_CBDT_HH
-#define OT_COLOR_CBDT_CBDT_HH
-
-#include "../../../hb-open-type.hh"
-#include "../../../hb-paint.hh"
-
-/*
- * CBLC -- Color Bitmap Location
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc
- * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc
- * CBDT -- Color Bitmap Data
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
- * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt
- */
-#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
-#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
-
-
-namespace OT {
-
-struct cblc_bitmap_size_subset_context_t
-{
- const char *cbdt;
- unsigned int cbdt_length;
- hb_vector_t<char> *cbdt_prime;
- unsigned int size; /* INOUT
- * Input: old size of IndexSubtable
- * Output: new size of IndexSubtable
- */
- unsigned int num_tables; /* INOUT
- * Input: old number of subtables.
- * Output: new number of subtables.
- */
- hb_codepoint_t start_glyph; /* OUT */
- hb_codepoint_t end_glyph; /* OUT */
-};
-
-static inline bool
-_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime,
- const void *data,
- unsigned length)
-{
- unsigned int new_len = cbdt_prime->length + length;
- if (unlikely (!cbdt_prime->alloc (new_len))) return false;
- hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
- cbdt_prime->length = new_len;
- return true;
-}
-
-struct SmallGlyphMetrics
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const
- {
- extents->x_bearing = bearingX;
- extents->y_bearing = bearingY;
- extents->width = width;
- extents->height = -static_cast<int> (height);
-
- if (scale)
- font->scale_glyph_extents (extents);
- }
-
- HBUINT8 height;
- HBUINT8 width;
- HBINT8 bearingX;
- HBINT8 bearingY;
- HBUINT8 advance;
- public:
- DEFINE_SIZE_STATIC (5);
-};
-
-struct BigGlyphMetrics : SmallGlyphMetrics
-{
- HBINT8 vertBearingX;
- HBINT8 vertBearingY;
- HBUINT8 vertAdvance;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct SBitLineMetrics
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBINT8 ascender;
- HBINT8 decender;
- HBUINT8 widthMax;
- HBINT8 caretSlopeNumerator;
- HBINT8 caretSlopeDenominator;
- HBINT8 caretOffset;
- HBINT8 minOriginSB;
- HBINT8 minAdvanceSB;
- HBINT8 maxBeforeBL;
- HBINT8 minAfterBL;
- HBINT8 padding1;
- HBINT8 padding2;
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-
-/*
- * Index Subtables.
- */
-
-struct IndexSubtableHeader
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 indexFormat;
- HBUINT16 imageFormat;
- HBUINT32 imageDataOffset;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-template <typename OffsetType>
-struct IndexSubtableFormat1Or3
-{
- bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- offsetArrayZ.sanitize (c, glyph_count + 1));
- }
-
- bool get_image_data (unsigned int idx,
- unsigned int *offset,
- unsigned int *length) const
- {
- if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
- return false;
-
- *offset = header.imageDataOffset + offsetArrayZ[idx];
- *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
- return true;
- }
-
- bool add_offset (hb_serialize_context_t *c,
- unsigned int offset,
- unsigned int *size /* OUT (accumulated) */)
- {
- TRACE_SERIALIZE (this);
- Offset<OffsetType> embedded_offset;
- embedded_offset = offset;
- *size += sizeof (OffsetType);
- auto *o = c->embed (embedded_offset);
- return_trace ((bool) o);
- }
-
- IndexSubtableHeader header;
- UnsizedArrayOf<Offset<OffsetType>>
- offsetArrayZ;
- public:
- DEFINE_SIZE_ARRAY (8, offsetArrayZ);
-};
-
-struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
-struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
-
-struct IndexSubtable
-{
- bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
- {
- TRACE_SANITIZE (this);
- if (!u.header.sanitize (c)) return_trace (false);
- switch (u.header.indexFormat)
- {
- case 1: return_trace (u.format1.sanitize (c, glyph_count));
- case 3: return_trace (u.format3.sanitize (c, glyph_count));
- default:return_trace (true);
- }
- }
-
- bool
- finish_subtable (hb_serialize_context_t *c,
- unsigned int cbdt_prime_len,
- unsigned int num_glyphs,
- unsigned int *size /* OUT (accumulated) */)
- {
- TRACE_SERIALIZE (this);
-
- unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
- switch (u.header.indexFormat)
- {
- case 1: return_trace (u.format1.add_offset (c, local_offset, size));
- case 3: {
- if (!u.format3.add_offset (c, local_offset, size))
- return_trace (false);
- if (!(num_glyphs & 0x01)) // Pad to 32-bit alignment if needed.
- return_trace (u.format3.add_offset (c, 0, size));
- return_trace (true);
- }
- // TODO: implement 2, 4, 5.
- case 2: case 4: // No-op.
- case 5: // Pad to 32-bit aligned.
- default: return_trace (false);
- }
- }
-
- bool
- fill_missing_glyphs (hb_serialize_context_t *c,
- unsigned int cbdt_prime_len,
- unsigned int num_missing,
- unsigned int *size /* OUT (accumulated) */,
- unsigned int *num_glyphs /* OUT (accumulated) */)
- {
- TRACE_SERIALIZE (this);
-
- unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
- switch (u.header.indexFormat)
- {
- case 1: {
- for (unsigned int i = 0; i < num_missing; i++)
- {
- if (unlikely (!u.format1.add_offset (c, local_offset, size)))
- return_trace (false);
- *num_glyphs += 1;
- }
- return_trace (true);
- }
- case 3: {
- for (unsigned int i = 0; i < num_missing; i++)
- {
- if (unlikely (!u.format3.add_offset (c, local_offset, size)))
- return_trace (false);
- *num_glyphs += 1;
- }
- return_trace (true);
- }
- // TODO: implement 2, 4, 5.
- case 2: // Add empty space in cbdt_prime?.
- case 4: case 5: // No-op as sparse is supported.
- default: return_trace (false);
- }
- }
-
- bool
- copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx,
- const char *cbdt, unsigned int cbdt_length,
- hb_vector_t<char> *cbdt_prime /* INOUT */,
- IndexSubtable *subtable_prime /* INOUT */,
- unsigned int *size /* OUT (accumulated) */) const
- {
- TRACE_SERIALIZE (this);
-
- unsigned int offset, length, format;
- if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false);
- if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false);
-
- auto *header_prime = subtable_prime->get_header ();
- unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset;
- if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false);
-
- return_trace (subtable_prime->add_offset (c, new_local_offset, size));
- }
-
- bool
- add_offset (hb_serialize_context_t *c, unsigned int local_offset,
- unsigned int *size /* OUT (accumulated) */)
- {
- TRACE_SERIALIZE (this);
- switch (u.header.indexFormat)
- {
- case 1: return_trace (u.format1.add_offset (c, local_offset, size));
- case 3: return_trace (u.format3.add_offset (c, local_offset, size));
- // TODO: Implement tables 2, 4, 5
- case 2: // Should be a no-op.
- case 4: case 5: // Handle sparse cases.
- default: return_trace (false);
- }
- }
-
- bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const
- {
- switch (u.header.indexFormat)
- {
- case 2: case 5: /* TODO */
- case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
- default:return (false);
- }
- }
-
- bool
- get_image_data (unsigned int idx, unsigned int *offset,
- unsigned int *length, unsigned int *format) const
- {
- *format = u.header.imageFormat;
- switch (u.header.indexFormat)
- {
- case 1: return u.format1.get_image_data (idx, offset, length);
- case 3: return u.format3.get_image_data (idx, offset, length);
- default: return false;
- }
- }
-
- const IndexSubtableHeader* get_header () const { return &u.header; }
-
- void populate_header (unsigned index_format,
- unsigned image_format,
- unsigned int image_data_offset,
- unsigned int *size)
- {
- u.header.indexFormat = index_format;
- u.header.imageFormat = image_format;
- u.header.imageDataOffset = image_data_offset;
- switch (u.header.indexFormat)
- {
- case 1: *size += IndexSubtableFormat1::min_size; break;
- case 3: *size += IndexSubtableFormat3::min_size; break;
- }
- }
-
- protected:
- union {
- IndexSubtableHeader header;
- IndexSubtableFormat1 format1;
- IndexSubtableFormat3 format3;
- /* TODO: Format 2, 4, 5. */
- } u;
- public:
- DEFINE_SIZE_UNION (8, header);
-};
-
-struct IndexSubtableRecord
-{
- /* XXX Remove this and fix by not inserting it into vector. */
- IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
- {
- firstGlyphIndex = o.firstGlyphIndex;
- lastGlyphIndex = o.lastGlyphIndex;
- offsetToSubtable = (unsigned) o.offsetToSubtable;
- assert (offsetToSubtable.is_null ());
- return *this;
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- firstGlyphIndex <= lastGlyphIndex &&
- offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
- }
-
- const IndexSubtable* get_subtable (const void *base) const
- {
- return &(base+offsetToSubtable);
- }
-
- bool add_new_subtable (hb_subset_context_t* c,
- cblc_bitmap_size_subset_context_t *bitmap_size_context,
- IndexSubtableRecord *record,
- const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
- const void *base,
- unsigned int *start /* INOUT */) const
- {
- TRACE_SERIALIZE (this);
-
- auto *subtable = c->serializer->start_embed<IndexSubtable> ();
- if (unlikely (!subtable)) return_trace (false);
- if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
-
- auto *old_subtable = get_subtable (base);
- auto *old_header = old_subtable->get_header ();
-
- subtable->populate_header (old_header->indexFormat,
- old_header->imageFormat,
- bitmap_size_context->cbdt_prime->length,
- &bitmap_size_context->size);
-
- unsigned int num_glyphs = 0;
- bool early_exit = false;
- for (unsigned int i = *start; i < lookup->length; i++)
- {
- hb_codepoint_t new_gid = (*lookup)[i].first;
- const IndexSubtableRecord *next_record = (*lookup)[i].second;
- const IndexSubtable *next_subtable = next_record->get_subtable (base);
- auto *next_header = next_subtable->get_header ();
- if (next_header != old_header)
- {
- *start = i;
- early_exit = true;
- break;
- }
- unsigned int num_missing = record->add_glyph_for_subset (new_gid);
- if (unlikely (!subtable->fill_missing_glyphs (c->serializer,
- bitmap_size_context->cbdt_prime->length,
- num_missing,
- &bitmap_size_context->size,
- &num_glyphs)))
- return_trace (false);
-
- hb_codepoint_t old_gid = 0;
- c->plan->old_gid_for_new_gid (new_gid, &old_gid);
- if (old_gid < next_record->firstGlyphIndex)
- return_trace (false);
-
- unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex;
- if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer,
- old_idx,
- bitmap_size_context->cbdt,
- bitmap_size_context->cbdt_length,
- bitmap_size_context->cbdt_prime,
- subtable,
- &bitmap_size_context->size)))
- return_trace (false);
- num_glyphs += 1;
- }
- if (!early_exit)
- *start = lookup->length;
- if (unlikely (!subtable->finish_subtable (c->serializer,
- bitmap_size_context->cbdt_prime->length,
- num_glyphs,
- &bitmap_size_context->size)))
- return_trace (false);
- return_trace (true);
- }
-
- bool add_new_record (hb_subset_context_t *c,
- cblc_bitmap_size_subset_context_t *bitmap_size_context,
- const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
- const void *base,
- unsigned int *start, /* INOUT */
- hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const
- {
- TRACE_SERIALIZE (this);
- auto snap = c->serializer->snapshot ();
- unsigned int old_size = bitmap_size_context->size;
- unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
-
- // Set to invalid state to indicate filling glyphs is not yet started.
- if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
- return_trace (false);
-
- records->tail ().firstGlyphIndex = 1;
- records->tail ().lastGlyphIndex = 0;
- bitmap_size_context->size += IndexSubtableRecord::min_size;
-
- c->serializer->push ();
-
- if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
- {
- c->serializer->pop_discard ();
- c->serializer->revert (snap);
- bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length);
- bitmap_size_context->size = old_size;
- records->resize (records->length - 1);
- return_trace (false);
- }
-
- bitmap_size_context->num_tables += 1;
- return_trace (true);
- }
-
- unsigned int add_glyph_for_subset (hb_codepoint_t gid)
- {
- if (firstGlyphIndex > lastGlyphIndex)
- {
- firstGlyphIndex = gid;
- lastGlyphIndex = gid;
- return 0;
- }
- // TODO maybe assert? this shouldn't occur.
- if (lastGlyphIndex > gid)
- return 0;
- unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1);
- lastGlyphIndex = gid;
- return num_missing;
- }
-
- bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const
- { return (base+offsetToSubtable).get_extents (extents, scale); }
-
- bool get_image_data (unsigned int gid,
- const void *base,
- unsigned int *offset,
- unsigned int *length,
- unsigned int *format) const
- {
- if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
- return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
- offset, length, format);
- }
-
- HBGlyphID16 firstGlyphIndex;
- HBGlyphID16 lastGlyphIndex;
- Offset32To<IndexSubtable> offsetToSubtable;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct IndexSubtableArray
-{
- friend struct CBDT;
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
- {
- TRACE_SANITIZE (this);
- return_trace (indexSubtablesZ.sanitize (c, count, this));
- }
-
- void
- build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context,
- hb_vector_t<hb_pair_t<hb_codepoint_t,
- const IndexSubtableRecord*>> *lookup /* OUT */) const
- {
- bool start_glyph_is_set = false;
- for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
- {
- hb_codepoint_t old_gid;
- if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
-
- const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables);
- if (unlikely (!record)) continue;
-
- // Don't add gaps to the lookup. The best way to determine if a glyph is a
- // gap is that it has no image data.
- unsigned int offset, length, format;
- if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue;
-
- lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record));
-
- if (!start_glyph_is_set)
- {
- bitmap_size_context->start_glyph = new_gid;
- start_glyph_is_set = true;
- }
-
- bitmap_size_context->end_glyph = new_gid;
- }
- }
-
- bool
- subset (hb_subset_context_t *c,
- cblc_bitmap_size_subset_context_t *bitmap_size_context) const
- {
- TRACE_SUBSET (this);
-
- auto *dst = c->serializer->start_embed<IndexSubtableArray> ();
- if (unlikely (!dst)) return_trace (false);
-
- hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
- build_lookup (c, bitmap_size_context, &lookup);
- if (unlikely (!c->serializer->propagate_error (lookup)))
- return false;
-
- bitmap_size_context->size = 0;
- bitmap_size_context->num_tables = 0;
- hb_vector_t<IndexSubtableRecord> records;
- for (unsigned int start = 0; start < lookup.length;)
- {
- if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records)))
- {
- // Discard any leftover pushes to the serializer from successful records.
- for (unsigned int i = 0; i < records.length; i++)
- c->serializer->pop_discard ();
- return_trace (false);
- }
- }
-
- /* Workaround to ensure offset ordering is from least to greatest when
- * resolving links. */
- hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
- for (unsigned int i = 0; i < records.length; i++)
- objidxs.push (c->serializer->pop_pack ());
- for (unsigned int i = 0; i < records.length; i++)
- {
- IndexSubtableRecord* record = c->serializer->embed (records[i]);
- if (unlikely (!record)) return_trace (false);
- c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]);
- }
- return_trace (true);
- }
-
- public:
- const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
- {
- for (unsigned int i = 0; i < numTables; ++i)
- {
- unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
- unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
- if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
- return &indexSubtablesZ[i];
- }
- return nullptr;
- }
-
- protected:
- UnsizedArrayOf<IndexSubtableRecord> indexSubtablesZ;
-};
-
-struct BitmapSizeTable
-{
- friend struct CBLC;
- friend struct CBDT;
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
- horizontal.sanitize (c) &&
- vertical.sanitize (c));
- }
-
- const IndexSubtableRecord *
- find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const
- {
- *out_base = &(base+indexSubtableArrayOffset);
- return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
- }
-
- bool
- subset (hb_subset_context_t *c, const void *base,
- const char *cbdt, unsigned int cbdt_length,
- hb_vector_t<char> *cbdt_prime /* INOUT */) const
- {
- TRACE_SUBSET (this);
- auto *out_table = c->serializer->embed (this);
- if (unlikely (!out_table)) return_trace (false);
-
- cblc_bitmap_size_subset_context_t bitmap_size_context;
- bitmap_size_context.cbdt = cbdt;
- bitmap_size_context.cbdt_length = cbdt_length;
- bitmap_size_context.cbdt_prime = cbdt_prime;
- bitmap_size_context.size = indexTablesSize;
- bitmap_size_context.num_tables = numberOfIndexSubtables;
- bitmap_size_context.start_glyph = 1;
- bitmap_size_context.end_glyph = 0;
-
- if (!out_table->indexSubtableArrayOffset.serialize_subset (c,
- indexSubtableArrayOffset,
- base,
- &bitmap_size_context))
- return_trace (false);
- if (!bitmap_size_context.size ||
- !bitmap_size_context.num_tables ||
- bitmap_size_context.start_glyph > bitmap_size_context.end_glyph)
- return_trace (false);
-
- out_table->indexTablesSize = bitmap_size_context.size;
- out_table->numberOfIndexSubtables = bitmap_size_context.num_tables;
- out_table->startGlyphIndex = bitmap_size_context.start_glyph;
- out_table->endGlyphIndex = bitmap_size_context.end_glyph;
- return_trace (true);
- }
-
- protected:
- NNOffset32To<IndexSubtableArray>
- indexSubtableArrayOffset;
- HBUINT32 indexTablesSize;
- HBUINT32 numberOfIndexSubtables;
- HBUINT32 colorRef;
- SBitLineMetrics horizontal;
- SBitLineMetrics vertical;
- HBGlyphID16 startGlyphIndex;
- HBGlyphID16 endGlyphIndex;
- HBUINT8 ppemX;
- HBUINT8 ppemY;
- HBUINT8 bitDepth;
- HBINT8 flags;
- public:
- DEFINE_SIZE_STATIC (48);
-};
-
-
-/*
- * Glyph Bitmap Data Formats.
- */
-
-struct GlyphBitmapDataFormat17
-{
- SmallGlyphMetrics glyphMetrics;
- Array32Of<HBUINT8> data;
- public:
- DEFINE_SIZE_ARRAY (9, data);
-};
-
-struct GlyphBitmapDataFormat18
-{
- BigGlyphMetrics glyphMetrics;
- Array32Of<HBUINT8> data;
- public:
- DEFINE_SIZE_ARRAY (12, data);
-};
-
-struct GlyphBitmapDataFormat19
-{
- Array32Of<HBUINT8> data;
- public:
- DEFINE_SIZE_ARRAY (4, data);
-};
-
-struct CBLC
-{
- friend struct CBDT;
-
- static constexpr hb_tag_t tableTag = HB_OT_TAG_CBLC;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version.major == 2 || version.major == 3) &&
- sizeTables.sanitize (c, this));
- }
-
- static bool
- sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime)
- {
- hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ,
- cbdt_prime->length,
- HB_MEMORY_MODE_WRITABLE,
- cbdt_prime->arrayZ,
- hb_free);
- cbdt_prime->init (); // Leak arrayZ to the blob.
- bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob);
- hb_blob_destroy (cbdt_prime_blob);
- return ret;
- }
-
- bool
- subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table,
- const char *cbdt /* IN */, unsigned int cbdt_length,
- CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const
- {
- TRACE_SUBSET (this);
- cblc_prime->sizeTables.len++;
-
- auto snap = c->serializer->snapshot ();
- auto cbdt_prime_len = cbdt_prime->length;
-
- if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime))
- {
- cblc_prime->sizeTables.len--;
- c->serializer->revert (snap);
- cbdt_prime->shrink (cbdt_prime_len);
- return_trace (false);
- }
- return_trace (true);
- }
-
- // Implemented in cc file as it depends on definition of CBDT.
- HB_INTERNAL bool subset (hb_subset_context_t *c) const;
-
- protected:
- const BitmapSizeTable &choose_strike (hb_font_t *font) const
- {
- unsigned count = sizeTables.len;
- if (unlikely (!count))
- return Null (BitmapSizeTable);
-
- unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
- if (!requested_ppem)
- requested_ppem = 1<<30; /* Choose largest strike. */
- unsigned int best_i = 0;
- unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
-
- for (unsigned int i = 1; i < count; i++)
- {
- unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY);
- if ((requested_ppem <= ppem && ppem < best_ppem) ||
- (requested_ppem > best_ppem && ppem > best_ppem))
- {
- best_i = i;
- best_ppem = ppem;
- }
- }
-
- return sizeTables[best_i];
- }
-
- protected:
- FixedVersion<> version;
- Array32Of<BitmapSizeTable> sizeTables;
- public:
- DEFINE_SIZE_ARRAY (8, sizeTables);
-};
-
-struct CBDT
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_CBDT;
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
- this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
-
- upem = hb_face_get_upem (face);
- }
- ~accelerator_t ()
- {
- this->cblc.destroy ();
- this->cbdt.destroy ();
- }
-
- bool
- get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const
- {
- const void *base;
- const BitmapSizeTable &strike = this->cblc->choose_strike (font);
- const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
- if (!subtable_record || !strike.ppemX || !strike.ppemY)
- return false;
-
- if (subtable_record->get_extents (extents, base, scale))
- return true;
-
- unsigned int image_offset = 0, image_length = 0, image_format = 0;
- if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
- return false;
-
- unsigned int cbdt_len = cbdt.get_length ();
- 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;
- auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
- glyphFormat17.glyphMetrics.get_extents (font, extents, scale);
- break;
- }
- case 18: {
- if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
- return false;
- auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
- glyphFormat18.glyphMetrics.get_extents (font, extents, scale);
- break;
- }
- default: return false; /* TODO: Support other image formats. */
- }
-
- /* Convert to font units. */
- if (scale)
- {
- float x_scale = upem / (float) strike.ppemX;
- float y_scale = upem / (float) strike.ppemY;
- extents->x_bearing = roundf (extents->x_bearing * x_scale);
- extents->y_bearing = roundf (extents->y_bearing * y_scale);
- extents->width = roundf (extents->width * x_scale);
- extents->height = roundf (extents->height * y_scale);
- }
-
- return true;
- }
-
- hb_blob_t*
- reference_png (hb_font_t *font, hb_codepoint_t glyph) const
- {
- const void *base;
- const BitmapSizeTable &strike = this->cblc->choose_strike (font);
- const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
- if (!subtable_record || !strike.ppemX || !strike.ppemY)
- return hb_blob_get_empty ();
-
- unsigned int image_offset = 0, image_length = 0, image_format = 0;
- if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
- return hb_blob_get_empty ();
-
- unsigned int cbdt_len = cbdt.get_length ();
- if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
- return hb_blob_get_empty ();
-
- switch (image_format)
- {
- case 17:
- {
- if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
- return hb_blob_get_empty ();
- auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
- return hb_blob_create_sub_blob (cbdt.get_blob (),
- image_offset + GlyphBitmapDataFormat17::min_size,
- glyphFormat17.data.len);
- }
- case 18:
- {
- if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
- return hb_blob_get_empty ();
- auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
- return hb_blob_create_sub_blob (cbdt.get_blob (),
- image_offset + GlyphBitmapDataFormat18::min_size,
- glyphFormat18.data.len);
- }
- case 19:
- {
- if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
- return hb_blob_get_empty ();
- auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
- return hb_blob_create_sub_blob (cbdt.get_blob (),
- image_offset + GlyphBitmapDataFormat19::min_size,
- glyphFormat19.data.len);
- }
- default: return hb_blob_get_empty (); /* TODO: Support other image formats. */
- }
- }
-
- bool has_data () const { return cbdt.get_length (); }
-
- bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
- {
- hb_glyph_extents_t extents;
- hb_glyph_extents_t pixel_extents;
- hb_blob_t *blob = reference_png (font, glyph);
-
- if (unlikely (blob == hb_blob_get_empty ()))
- return false;
-
- if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents)))
- return false;
-
- if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
- return false;
-
- bool ret = funcs->image (data,
- blob,
- pixel_extents.width, -pixel_extents.height,
- HB_PAINT_IMAGE_FORMAT_PNG,
- font->slant_xy,
- &extents);
-
- hb_blob_destroy (blob);
- return ret;
- }
-
- private:
- hb_blob_ptr_t<CBLC> cblc;
- hb_blob_ptr_t<CBDT> cbdt;
-
- unsigned int upem;
- };
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version.major == 2 || version.major == 3));
- }
-
- protected:
- FixedVersion<> version;
- UnsizedArrayOf<HBUINT8> dataZ;
- public:
- DEFINE_SIZE_ARRAY (4, dataZ);
-};
-
-inline bool
-CBLC::subset (hb_subset_context_t *c) const
-{
- TRACE_SUBSET (this);
-
- auto *cblc_prime = c->serializer->start_embed<CBLC> ();
-
- // Use a vector as a secondary buffer as the tables need to be built in parallel.
- hb_vector_t<char> cbdt_prime;
-
- if (unlikely (!cblc_prime)) return_trace (false);
- if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
- cblc_prime->version = version;
-
- hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source);
- unsigned int cbdt_length;
- CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length);
- if (unlikely (cbdt_length < CBDT::min_size))
- {
- hb_blob_destroy (cbdt_blob);
- return_trace (false);
- }
- _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size);
-
- for (const BitmapSizeTable& table : + sizeTables.iter ())
- subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime);
-
- hb_blob_destroy (cbdt_blob);
-
- return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
-}
-
-struct CBDT_accelerator_t : CBDT::accelerator_t {
- CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
-};
-
-
-} /* namespace OT */
-
-#endif /* OT_COLOR_CBDT_CBDT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
deleted file mode 100644
index 191812f48ee..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
+++ /dev/null
@@ -1,2436 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- * Copyright © 2020 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): Calder Kitagawa
- */
-
-#ifndef OT_COLOR_COLR_COLR_HH
-#define OT_COLOR_COLR_COLR_HH
-
-#include "../../../hb.hh"
-#include "../../../hb-open-type.hh"
-#include "../../../hb-ot-var-common.hh"
-#include "../../../hb-paint.hh"
-#include "../../../hb-paint-extents.hh"
-
-/*
- * COLR -- Color
- * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
- */
-#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
-
-namespace OT {
-struct hb_paint_context_t;
-}
-
-namespace OT {
-
-struct COLR;
-
-struct Paint;
-
-struct hb_paint_context_t :
- hb_dispatch_context_t<hb_paint_context_t>
-{
- template <typename T>
- return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
- static return_t default_return_value () { return hb_empty_t (); }
-
- const COLR* get_colr_table () const
- { return reinterpret_cast<const COLR *> (base); }
-
-public:
- const void *base;
- hb_paint_funcs_t *funcs;
- void *data;
- hb_font_t *font;
- unsigned int palette_index;
- hb_color_t foreground;
- VarStoreInstancer &instancer;
- int depth_left = HB_MAX_NESTING_LEVEL;
- int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
-
- hb_paint_context_t (const void *base_,
- hb_paint_funcs_t *funcs_,
- void *data_,
- hb_font_t *font_,
- unsigned int palette_,
- hb_color_t foreground_,
- VarStoreInstancer &instancer_) :
- base (base_),
- funcs (funcs_),
- data (data_),
- font (font_),
- palette_index (palette_),
- foreground (foreground_),
- instancer (instancer_)
- { }
-
- hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground)
- {
- hb_color_t color = foreground;
-
- *is_foreground = true;
-
- if (color_index != 0xffff)
- {
- if (!funcs->custom_palette_color (data, color_index, &color))
- {
- unsigned int clen = 1;
- hb_face_t *face = hb_font_get_face (font);
-
- hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
- }
-
- *is_foreground = false;
- }
-
- return HB_COLOR (hb_color_get_blue (color),
- hb_color_get_green (color),
- hb_color_get_red (color),
- hb_color_get_alpha (color) * alpha);
- }
-
- inline void recurse (const Paint &paint);
-};
-
-struct hb_colrv1_closure_context_t :
- hb_dispatch_context_t<hb_colrv1_closure_context_t>
-{
- template <typename T>
- return_t dispatch (const T &obj)
- {
- if (unlikely (nesting_level_left == 0))
- return hb_empty_t ();
-
- if (paint_visited (&obj))
- return hb_empty_t ();
-
- nesting_level_left--;
- obj.closurev1 (this);
- nesting_level_left++;
- return hb_empty_t ();
- }
- static return_t default_return_value () { return hb_empty_t (); }
-
- bool paint_visited (const void *paint)
- {
- hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
- if (visited_paint.in_error() || visited_paint.has (delta))
- return true;
-
- visited_paint.add (delta);
- return false;
- }
-
- const COLR* get_colr_table () const
- { return reinterpret_cast<const COLR *> (base); }
-
- void add_glyph (unsigned glyph_id)
- { glyphs->add (glyph_id); }
-
- void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
- { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
-
- void add_palette_index (unsigned palette_index)
- { palette_indices->add (palette_index); }
-
- public:
- const void *base;
- hb_set_t visited_paint;
- hb_set_t *glyphs;
- hb_set_t *layer_indices;
- hb_set_t *palette_indices;
- unsigned nesting_level_left;
-
- hb_colrv1_closure_context_t (const void *base_,
- hb_set_t *glyphs_,
- hb_set_t *layer_indices_,
- hb_set_t *palette_indices_,
- unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
- base (base_),
- glyphs (glyphs_),
- layer_indices (layer_indices_),
- palette_indices (palette_indices_),
- nesting_level_left (nesting_level_left_)
- {}
-};
-
-struct LayerRecord
-{
- operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBGlyphID16 glyphId; /* Glyph ID of layer glyph */
- Index colorIdx; /* Index value to use with a
- * selected color palette.
- * An index value of 0xFFFF
- * is a special case indicating
- * that the text foreground
- * color (defined by a
- * higher-level client) should
- * be used and shall not be
- * treated as actual index
- * into CPAL ColorRecord array. */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct BaseGlyphRecord
-{
- int cmp (hb_codepoint_t g) const
- { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBGlyphID16 glyphId; /* Glyph ID of reference glyph */
- HBUINT16 firstLayerIdx; /* Index (from beginning of
- * the Layer Records) to the
- * layer record. There will be
- * numLayers consecutive entries
- * for this base glyph. */
- HBUINT16 numLayers; /* Number of color layers
- * associated with this glyph */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-template <typename T>
-struct Variable
-{
- static constexpr bool is_variable = true;
-
- Variable<T>* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed (this));
- }
-
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { value.closurev1 (c); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- if (!value.subset (c, instancer, varIdxBase)) return_trace (false);
- if (c->plan->all_axes_pinned)
- return_trace (true);
-
- //TODO: update varIdxBase for partial-instancing
- return_trace (c->serializer->embed (varIdxBase));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c));
- }
-
- void paint_glyph (hb_paint_context_t *c) const
- {
- value.paint_glyph (c, varIdxBase);
- }
-
- void get_color_stop (hb_paint_context_t *c,
- hb_color_stop_t *stop,
- const VarStoreInstancer &instancer) const
- {
- value.get_color_stop (c, stop, varIdxBase, instancer);
- }
-
- hb_paint_extend_t get_extend () const
- {
- return value.get_extend ();
- }
-
- protected:
- T value;
- public:
- VarIdx varIdxBase;
- public:
- DEFINE_SIZE_STATIC (4 + T::static_size);
-};
-
-template <typename T>
-struct NoVariable
-{
- static constexpr bool is_variable = false;
-
- static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
-
- NoVariable<T>* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed (this));
- }
-
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { value.closurev1 (c); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- return_trace (value.subset (c, instancer, varIdxBase));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c));
- }
-
- void paint_glyph (hb_paint_context_t *c) const
- {
- value.paint_glyph (c, varIdxBase);
- }
-
- void get_color_stop (hb_paint_context_t *c,
- hb_color_stop_t *stop,
- const VarStoreInstancer &instancer) const
- {
- value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer);
- }
-
- hb_paint_extend_t get_extend () const
- {
- return value.get_extend ();
- }
-
- T value;
- public:
- DEFINE_SIZE_STATIC (T::static_size);
-};
-
-// Color structures
-
-struct ColorStop
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { c->add_palette_index (paletteIndex); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->stopOffset.set_float (stopOffset.to_float(instancer (varIdxBase, 0)));
- out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 1)));
- }
-
- return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void get_color_stop (hb_paint_context_t *c,
- hb_color_stop_t *out,
- uint32_t varIdx,
- const VarStoreInstancer &instancer) const
- {
- out->offset = stopOffset.to_float(instancer (varIdx, 0));
- out->color = c->get_color (paletteIndex,
- alpha.to_float (instancer (varIdx, 1)),
- &out->is_foreground);
- }
-
- F2DOT14 stopOffset;
- HBUINT16 paletteIndex;
- F2DOT14 alpha;
- public:
- DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
-};
-
-struct Extend : HBUINT8
-{
- enum {
- EXTEND_PAD = 0,
- EXTEND_REPEAT = 1,
- EXTEND_REFLECT = 2,
- };
- public:
- DEFINE_SIZE_STATIC (1);
-};
-
-template <template<typename> class Var>
-struct ColorLine
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- {
- for (const auto &stop : stops.iter ())
- stop.closurev1 (c);
- }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out)) return_trace (false);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
- if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false);
-
- for (const auto& stop : stops.iter ())
- {
- if (!stop.subset (c, instancer)) return_trace (false);
- }
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- stops.sanitize (c));
- }
-
- /* get up to count stops from start */
- unsigned int
- get_color_stops (hb_paint_context_t *c,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops,
- const VarStoreInstancer &instancer) const
- {
- unsigned int len = stops.len;
-
- if (count && color_stops)
- {
- unsigned int i;
- for (i = 0; i < *count && start + i < len; i++)
- stops[start + i].get_color_stop (c, &color_stops[i], instancer);
- *count = i;
- }
-
- return len;
- }
-
- HB_INTERNAL static unsigned int static_get_color_stops (hb_color_line_t *color_line,
- void *color_line_data,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops,
- void *user_data)
- {
- const ColorLine *thiz = (const ColorLine *) color_line_data;
- hb_paint_context_t *c = (hb_paint_context_t *) user_data;
- return thiz->get_color_stops (c, start, count, color_stops, c->instancer);
- }
-
- hb_paint_extend_t get_extend () const
- {
- return (hb_paint_extend_t) (unsigned int) extend;
- }
-
- HB_INTERNAL static hb_paint_extend_t static_get_extend (hb_color_line_t *color_line,
- void *color_line_data,
- void *user_data)
- {
- const ColorLine *thiz = (const ColorLine *) color_line_data;
- return thiz->get_extend ();
- }
-
- Extend extend;
- Array16Of<Var<ColorStop>> stops;
- public:
- DEFINE_SIZE_ARRAY_SIZED (3, stops);
-};
-
-// Composition modes
-
-// Compositing modes are taken from https://www.w3.org/TR/compositing-1/
-// NOTE: a brief audit of major implementations suggests most support most
-// or all of the specified modes.
-struct CompositeMode : HBUINT8
-{
- enum {
- // Porter-Duff modes
- // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators
- COMPOSITE_CLEAR = 0, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear
- COMPOSITE_SRC = 1, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src
- COMPOSITE_DEST = 2, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst
- COMPOSITE_SRC_OVER = 3, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover
- COMPOSITE_DEST_OVER = 4, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover
- COMPOSITE_SRC_IN = 5, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin
- COMPOSITE_DEST_IN = 6, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin
- COMPOSITE_SRC_OUT = 7, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout
- COMPOSITE_DEST_OUT = 8, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout
- COMPOSITE_SRC_ATOP = 9, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop
- COMPOSITE_DEST_ATOP = 10, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop
- COMPOSITE_XOR = 11, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor
- COMPOSITE_PLUS = 12, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus
-
- // Blend modes
- // https://www.w3.org/TR/compositing-1/#blending
- COMPOSITE_SCREEN = 13, // https://www.w3.org/TR/compositing-1/#blendingscreen
- COMPOSITE_OVERLAY = 14, // https://www.w3.org/TR/compositing-1/#blendingoverlay
- COMPOSITE_DARKEN = 15, // https://www.w3.org/TR/compositing-1/#blendingdarken
- COMPOSITE_LIGHTEN = 16, // https://www.w3.org/TR/compositing-1/#blendinglighten
- COMPOSITE_COLOR_DODGE = 17, // https://www.w3.org/TR/compositing-1/#blendingcolordodge
- COMPOSITE_COLOR_BURN = 18, // https://www.w3.org/TR/compositing-1/#blendingcolorburn
- COMPOSITE_HARD_LIGHT = 19, // https://www.w3.org/TR/compositing-1/#blendinghardlight
- COMPOSITE_SOFT_LIGHT = 20, // https://www.w3.org/TR/compositing-1/#blendingsoftlight
- COMPOSITE_DIFFERENCE = 21, // https://www.w3.org/TR/compositing-1/#blendingdifference
- COMPOSITE_EXCLUSION = 22, // https://www.w3.org/TR/compositing-1/#blendingexclusion
- COMPOSITE_MULTIPLY = 23, // https://www.w3.org/TR/compositing-1/#blendingmultiply
-
- // Modes that, uniquely, do not operate on components
- // https://www.w3.org/TR/compositing-1/#blendingnonseparable
- COMPOSITE_HSL_HUE = 24, // https://www.w3.org/TR/compositing-1/#blendinghue
- COMPOSITE_HSL_SATURATION = 25, // https://www.w3.org/TR/compositing-1/#blendingsaturation
- COMPOSITE_HSL_COLOR = 26, // https://www.w3.org/TR/compositing-1/#blendingcolor
- COMPOSITE_HSL_LUMINOSITY = 27, // https://www.w3.org/TR/compositing-1/#blendingluminosity
- };
- public:
- DEFINE_SIZE_STATIC (1);
-};
-
-struct Affine2x3
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->xx.set_float (xx.to_float(instancer (varIdxBase, 0)));
- out->yx.set_float (yx.to_float(instancer (varIdxBase, 1)));
- out->xy.set_float (xy.to_float(instancer (varIdxBase, 2)));
- out->yy.set_float (yy.to_float(instancer (varIdxBase, 3)));
- out->dx.set_float (dx.to_float(instancer (varIdxBase, 4)));
- out->dy.set_float (dy.to_float(instancer (varIdxBase, 5)));
- }
- return_trace (true);
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- c->funcs->push_transform (c->data,
- xx.to_float (c->instancer (varIdxBase, 0)),
- yx.to_float (c->instancer (varIdxBase, 1)),
- xy.to_float (c->instancer (varIdxBase, 2)),
- yy.to_float (c->instancer (varIdxBase, 3)),
- dx.to_float (c->instancer (varIdxBase, 4)),
- dy.to_float (c->instancer (varIdxBase, 5)));
- }
-
- F16DOT16 xx;
- F16DOT16 yx;
- F16DOT16 xy;
- F16DOT16 yy;
- F16DOT16 dx;
- F16DOT16 dy;
- public:
- DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
-};
-
-struct PaintColrLayers
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer HB_UNUSED) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
- return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- inline void paint_glyph (hb_paint_context_t *c) const;
-
- HBUINT8 format; /* format = 1 */
- HBUINT8 numLayers;
- HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct PaintSolid
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { c->add_palette_index (paletteIndex); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 0)));
-
- if (format == 3 && c->plan->all_axes_pinned)
- out->format = 2;
-
- return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- hb_bool_t is_foreground;
- hb_color_t color;
-
- color = c->get_color (paletteIndex,
- alpha.to_float (c->instancer (varIdxBase, 0)),
- &is_foreground);
- c->funcs->color (c->data, is_foreground, color);
- }
-
- HBUINT8 format; /* format = 2(noVar) or 3(Var)*/
- HBUINT16 paletteIndex;
- F2DOT14 alpha;
- public:
- DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintLinearGradient
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { (this+colorLine).closurev1 (c); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
- out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
- out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2));
- out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3));
- out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4));
- out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5));
- }
-
- if (format == 5 && c->plan->all_axes_pinned)
- out->format = 4;
-
- return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- hb_color_line_t cl = {
- (void *) &(this+colorLine),
- (this+colorLine).static_get_color_stops, c,
- (this+colorLine).static_get_extend, nullptr
- };
-
- c->funcs->linear_gradient (c->data, &cl,
- x0 + c->instancer (varIdxBase, 0),
- y0 + c->instancer (varIdxBase, 1),
- x1 + c->instancer (varIdxBase, 2),
- y1 + c->instancer (varIdxBase, 3),
- x2 + c->instancer (varIdxBase, 4),
- y2 + c->instancer (varIdxBase, 5));
- }
-
- HBUINT8 format; /* format = 4(noVar) or 5 (Var) */
- Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintLinearGradient
- * table) to ColorLine subtable. */
- FWORD x0;
- FWORD y0;
- FWORD x1;
- FWORD y1;
- FWORD x2;
- FWORD y2;
- public:
- DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintRadialGradient
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { (this+colorLine).closurev1 (c); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
- out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
- out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2));
- out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3));
- out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4));
- out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5));
- }
-
- if (format == 7 && c->plan->all_axes_pinned)
- out->format = 6;
-
- return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- hb_color_line_t cl = {
- (void *) &(this+colorLine),
- (this+colorLine).static_get_color_stops, c,
- (this+colorLine).static_get_extend, nullptr
- };
-
- c->funcs->radial_gradient (c->data, &cl,
- x0 + c->instancer (varIdxBase, 0),
- y0 + c->instancer (varIdxBase, 1),
- radius0 + c->instancer (varIdxBase, 2),
- x1 + c->instancer (varIdxBase, 3),
- y1 + c->instancer (varIdxBase, 4),
- radius1 + c->instancer (varIdxBase, 5));
- }
-
- HBUINT8 format; /* format = 6(noVar) or 7 (Var) */
- Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintRadialGradient
- * table) to ColorLine subtable. */
- FWORD x0;
- FWORD y0;
- UFWORD radius0;
- FWORD x1;
- FWORD y1;
- UFWORD radius1;
- public:
- DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintSweepGradient
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const
- { (this+colorLine).closurev1 (c); }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0));
- out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1));
- out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2)));
- out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3)));
- }
-
- if (format == 9 && c->plan->all_axes_pinned)
- out->format = 8;
-
- return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- hb_color_line_t cl = {
- (void *) &(this+colorLine),
- (this+colorLine).static_get_color_stops, c,
- (this+colorLine).static_get_extend, nullptr
- };
-
- c->funcs->sweep_gradient (c->data, &cl,
- centerX + c->instancer (varIdxBase, 0),
- centerY + c->instancer (varIdxBase, 1),
- (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * HB_PI,
- (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * HB_PI);
- }
-
- HBUINT8 format; /* format = 8(noVar) or 9 (Var) */
- Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintSweepGradient
- * table) to ColorLine subtable. */
- FWORD centerX;
- FWORD centerY;
- F2DOT14 startAngle;
- F2DOT14 endAngle;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
-};
-
-// Paint a non-COLR glyph, filled as indicated by paint.
-struct PaintGlyph
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- return_trace (out->paint.serialize_subset (c, paint, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && paint.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c) const
- {
- c->funcs->push_inverse_root_transform (c->data, c->font);
- c->funcs->push_clip_glyph (c->data, gid, c->font);
- c->funcs->push_root_transform (c->data, c->font);
- c->recurse (this+paint);
- c->funcs->pop_transform (c->data);
- c->funcs->pop_clip (c->data);
- c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 10 */
- Offset24To<Paint> paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
- HBUINT16 gid;
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct PaintColrGlyph
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer HB_UNUSED) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- inline void paint_glyph (hb_paint_context_t *c) const;
-
- HBUINT8 format; /* format = 11 */
- HBUINT16 gid;
- public:
- DEFINE_SIZE_STATIC (3);
-};
-
-template <template<typename> class Var>
-struct PaintTransform
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
- if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false);
- if (format == 13 && c->plan->all_axes_pinned)
- out->format = 12;
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- src.sanitize (c, this) &&
- transform.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c) const
- {
- (this+transform).paint_glyph (c);
- c->recurse (this+src);
- c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 12(noVar) or 13 (Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
- Offset24To<Var<Affine2x3>> transform;
- public:
- DEFINE_SIZE_STATIC (7);
-};
-
-struct PaintTranslate
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
- out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
- }
-
- if (format == 15 && c->plan->all_axes_pinned)
- out->format = 14;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float ddx = dx + c->instancer (varIdxBase, 0);
- float ddy = dy + c->instancer (varIdxBase, 1);
-
- bool p1 = c->funcs->push_translate (c->data, ddx, ddy);
- c->recurse (this+src);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 14(noVar) or 15 (Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
- FWORD dx;
- FWORD dy;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
-};
-
-struct PaintScale
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
- out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
- }
-
- if (format == 17 && c->plan->all_axes_pinned)
- out->format = 16;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
- float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
-
- bool p1 = c->funcs->push_scale (c->data, sx, sy);
- c->recurse (this+src);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 16 (noVar) or 17(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
- F2DOT14 scaleX;
- F2DOT14 scaleY;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
-};
-
-struct PaintScaleAroundCenter
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
- out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
- out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
- out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
- }
-
- if (format == 19 && c->plan->all_axes_pinned)
- out->format = 18;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
- float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
- float tCenterX = centerX + c->instancer (varIdxBase, 2);
- float tCenterY = centerY + c->instancer (varIdxBase, 3);
-
- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
- bool p2 = c->funcs->push_scale (c->data, sx, sy);
- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
- c->recurse (this+src);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 18 (noVar) or 19(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
- F2DOT14 scaleX;
- F2DOT14 scaleY;
- FWORD centerX;
- FWORD centerY;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintScaleUniform
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
-
- if (format == 21 && c->plan->all_axes_pinned)
- out->format = 20;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float s = scale.to_float (c->instancer (varIdxBase, 0));
-
- bool p1 = c->funcs->push_scale (c->data, s, s);
- c->recurse (this+src);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 20 (noVar) or 21(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
- F2DOT14 scale;
- public:
- DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
-};
-
-struct PaintScaleUniformAroundCenter
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
- out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
- out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
- }
-
- if (format == 23 && c->plan->all_axes_pinned)
- out->format = 22;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float s = scale.to_float (c->instancer (varIdxBase, 0));
- float tCenterX = centerX + c->instancer (varIdxBase, 1);
- float tCenterY = centerY + c->instancer (varIdxBase, 2);
-
- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
- bool p2 = c->funcs->push_scale (c->data, s, s);
- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
- c->recurse (this+src);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 22 (noVar) or 23(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
- F2DOT14 scale;
- FWORD centerX;
- FWORD centerY;
- public:
- DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintRotate
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
-
- if (format == 25 && c->plan->all_axes_pinned)
- out->format = 24;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float a = angle.to_float (c->instancer (varIdxBase, 0));
-
- bool p1 = c->funcs->push_rotate (c->data, a);
- c->recurse (this+src);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 24 (noVar) or 25(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
- F2DOT14 angle;
- public:
- DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
-};
-
-struct PaintRotateAroundCenter
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
- out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
- out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
- }
-
- if (format ==27 && c->plan->all_axes_pinned)
- out->format = 26;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float a = angle.to_float (c->instancer (varIdxBase, 0));
- float tCenterX = centerX + c->instancer (varIdxBase, 1);
- float tCenterY = centerY + c->instancer (varIdxBase, 2);
-
- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
- bool p2 = c->funcs->push_rotate (c->data, a);
- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
- c->recurse (this+src);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 26 (noVar) or 27(Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
- F2DOT14 angle;
- FWORD centerX;
- FWORD centerY;
- public:
- DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintSkew
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
- out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
- }
-
- if (format == 29 && c->plan->all_axes_pinned)
- out->format = 28;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
- float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
-
- bool p1 = c->funcs->push_skew (c->data, sx, sy);
- c->recurse (this+src);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 28(noVar) or 29 (Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
- F2DOT14 xSkewAngle;
- F2DOT14 ySkewAngle;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
-};
-
-struct PaintSkewAroundCenter
-{
- HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
- out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
- out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
- out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
- }
-
- if (format == 31 && c->plan->all_axes_pinned)
- out->format = 30;
-
- return_trace (out->src.serialize_subset (c, src, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && src.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
- {
- float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
- float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
- float tCenterX = centerX + c->instancer (varIdxBase, 2);
- float tCenterY = centerY + c->instancer (varIdxBase, 3);
-
- bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
- bool p2 = c->funcs->push_skew (c->data, sx, sy);
- bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
- c->recurse (this+src);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
-
- HBUINT8 format; /* format = 30(noVar) or 31 (Var) */
- Offset24To<Paint> src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
- F2DOT14 xSkewAngle;
- F2DOT14 ySkewAngle;
- FWORD centerX;
- FWORD centerY;
- public:
- DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintComposite
-{
- void closurev1 (hb_colrv1_closure_context_t* c) const;
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
- return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- src.sanitize (c, this) &&
- backdrop.sanitize (c, this));
- }
-
- void paint_glyph (hb_paint_context_t *c) const
- {
- c->recurse (this+backdrop);
- c->funcs->push_group (c->data);
- c->recurse (this+src);
- c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
- }
-
- HBUINT8 format; /* format = 32 */
- Offset24To<Paint> src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
- CompositeMode mode; /* If mode is unrecognized use COMPOSITE_CLEAR */
- Offset24To<Paint> backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct ClipBoxData
-{
- int xMin, yMin, xMax, yMax;
-};
-
-struct ClipBoxFormat1
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
- {
- clip_box.xMin = xMin;
- clip_box.yMin = yMin;
- clip_box.xMax = xMax;
- clip_box.yMax = yMax;
- }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- uint32_t varIdxBase) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
- {
- out->xMin = xMin + (int) roundf (instancer (varIdxBase, 0));
- out->yMin = yMin + (int) roundf (instancer (varIdxBase, 1));
- out->xMax = xMax + (int) roundf (instancer (varIdxBase, 2));
- out->yMax = yMax + (int) roundf (instancer (varIdxBase, 3));
- }
-
- if (format == 2 && c->plan->all_axes_pinned)
- out->format = 1;
-
- return_trace (true);
- }
-
- public:
- HBUINT8 format; /* format = 1(noVar) or 2(Var)*/
- FWORD xMin;
- FWORD yMin;
- FWORD xMax;
- FWORD yMax;
- public:
- DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
-};
-
-struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
-{
- void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
- {
- value.get_clip_box(clip_box, instancer);
- if (instancer)
- {
- clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
- clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
- clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
- clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
- }
- }
-};
-
-struct ClipBox
-{
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- switch (u.format) {
- case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION));
- case 2: return_trace (u.format2.subset (c, instancer));
- default:return_trace (c->default_return_value ());
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- bool get_extents (hb_glyph_extents_t *extents,
- const VarStoreInstancer &instancer) const
- {
- ClipBoxData clip_box;
- switch (u.format) {
- case 1:
- u.format1.get_clip_box (clip_box, instancer);
- break;
- case 2:
- u.format2.get_clip_box (clip_box, instancer);
- break;
- default:
- return false;
- }
-
- extents->x_bearing = clip_box.xMin;
- extents->y_bearing = clip_box.yMax;
- extents->width = clip_box.xMax - clip_box.xMin;
- extents->height = clip_box.yMin - clip_box.yMax;
- return true;
- }
-
- protected:
- union {
- HBUINT8 format; /* Format identifier */
- ClipBoxFormat1 format1;
- ClipBoxFormat2 format2;
- } u;
-};
-
-struct ClipRecord
-{
- int cmp (hb_codepoint_t g) const
- { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
-
- bool subset (hb_subset_context_t *c,
- const void *base,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
- }
-
- bool get_extents (hb_glyph_extents_t *extents,
- const void *base,
- const VarStoreInstancer &instancer) const
- {
- return (base+clipBox).get_extents (extents, instancer);
- }
-
- public:
- HBUINT16 startGlyphID; // first gid clip applies to
- HBUINT16 endGlyphID; // last gid clip applies to, inclusive
- Offset24To<ClipBox> clipBox; // Box or VarBox
- public:
- DEFINE_SIZE_STATIC (7);
-};
-DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
-
-struct ClipList
-{
- unsigned serialize_clip_records (hb_subset_context_t *c,
- const VarStoreInstancer &instancer,
- const hb_set_t& gids,
- const hb_map_t& gid_offset_map) const
- {
- TRACE_SERIALIZE (this);
- if (gids.is_empty () ||
- gid_offset_map.get_population () != gids.get_population ())
- return_trace (0);
-
- unsigned count = 0;
-
- hb_codepoint_t start_gid= gids.get_min ();
- hb_codepoint_t prev_gid = start_gid;
-
- unsigned offset = gid_offset_map.get (start_gid);
- unsigned prev_offset = offset;
- for (const hb_codepoint_t _ : gids.iter ())
- {
- if (_ == start_gid) continue;
-
- offset = gid_offset_map.get (_);
- if (_ == prev_gid + 1 && offset == prev_offset)
- {
- prev_gid = _;
- continue;
- }
-
- ClipRecord record;
- record.startGlyphID = start_gid;
- record.endGlyphID = prev_gid;
- record.clipBox = prev_offset;
-
- if (!record.subset (c, this, instancer)) return_trace (0);
- count++;
-
- start_gid = _;
- prev_gid = _;
- prev_offset = offset;
- }
-
- //last one
- {
- ClipRecord record;
- record.startGlyphID = start_gid;
- record.endGlyphID = prev_gid;
- record.clipBox = prev_offset;
- if (!record.subset (c, this, instancer)) return_trace (0);
- count++;
- }
- return_trace (count);
- }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
-
- const hb_set_t& glyphset = c->plan->_glyphset_colred;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- hb_map_t new_gid_offset_map;
- hb_set_t new_gids;
- for (const ClipRecord& record : clips.iter ())
- {
- unsigned start_gid = record.startGlyphID;
- unsigned end_gid = record.endGlyphID;
- for (unsigned gid = start_gid; gid <= end_gid; gid++)
- {
- if (!glyphset.has (gid) || !glyph_map.has (gid)) continue;
- unsigned new_gid = glyph_map.get (gid);
- new_gid_offset_map.set (new_gid, record.clipBox);
- new_gids.add (new_gid);
- }
- }
-
- unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map);
- if (!count) return_trace (false);
- return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- // TODO Make a formatted struct!
- return_trace (c->check_struct (this) && clips.sanitize (c, this));
- }
-
- bool
- get_extents (hb_codepoint_t gid,
- hb_glyph_extents_t *extents,
- const VarStoreInstancer &instancer) const
- {
- auto *rec = clips.as_array ().bsearch (gid);
- if (rec)
- {
- rec->get_extents (extents, this, instancer);
- return true;
- }
- return false;
- }
-
- HBUINT8 format; // Set to 1.
- SortedArray32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID
- public:
- DEFINE_SIZE_ARRAY_SIZED (5, clips);
-};
-
-struct Paint
-{
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
-
- if (unlikely (!c->check_start_recursion (HB_MAX_NESTING_LEVEL)))
- return_trace (c->no_dispatch_return_value ());
-
- return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
- case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...));
- case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...));
- case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...));
- case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...));
- case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...));
- case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...));
- case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...));
- case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...));
- case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...));
- case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...));
- case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...));
- case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...));
- case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...));
- case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...));
- case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...));
- case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...));
- case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...));
- case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...));
- case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...));
- case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...));
- case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...));
- case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...));
- case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...));
- case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...));
- case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...));
- case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...));
- case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...));
- case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...));
- case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...));
- case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT8 format;
- PaintColrLayers paintformat1;
- NoVariable<PaintSolid> paintformat2;
- Variable<PaintSolid> paintformat3;
- NoVariable<PaintLinearGradient<NoVariable>> paintformat4;
- Variable<PaintLinearGradient<Variable>> paintformat5;
- NoVariable<PaintRadialGradient<NoVariable>> paintformat6;
- Variable<PaintRadialGradient<Variable>> paintformat7;
- NoVariable<PaintSweepGradient<NoVariable>> paintformat8;
- Variable<PaintSweepGradient<Variable>> paintformat9;
- PaintGlyph paintformat10;
- PaintColrGlyph paintformat11;
- PaintTransform<NoVariable> paintformat12;
- PaintTransform<Variable> paintformat13;
- NoVariable<PaintTranslate> paintformat14;
- Variable<PaintTranslate> paintformat15;
- NoVariable<PaintScale> paintformat16;
- Variable<PaintScale> paintformat17;
- NoVariable<PaintScaleAroundCenter> paintformat18;
- Variable<PaintScaleAroundCenter> paintformat19;
- NoVariable<PaintScaleUniform> paintformat20;
- Variable<PaintScaleUniform> paintformat21;
- NoVariable<PaintScaleUniformAroundCenter> paintformat22;
- Variable<PaintScaleUniformAroundCenter> paintformat23;
- NoVariable<PaintRotate> paintformat24;
- Variable<PaintRotate> paintformat25;
- NoVariable<PaintRotateAroundCenter> paintformat26;
- Variable<PaintRotateAroundCenter> paintformat27;
- NoVariable<PaintSkew> paintformat28;
- Variable<PaintSkew> paintformat29;
- NoVariable<PaintSkewAroundCenter> paintformat30;
- Variable<PaintSkewAroundCenter> paintformat31;
- PaintComposite paintformat32;
- } u;
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct BaseGlyphPaintRecord
-{
- int cmp (hb_codepoint_t g) const
- { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
-
- bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
- const void* src_base, hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SERIALIZE (this);
- auto *out = s->embed (this);
- if (unlikely (!out)) return_trace (false);
- if (!s->check_assign (out->glyphId, glyph_map->get (glyphId),
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) && paint.sanitize (c, base)));
- }
-
- public:
- HBGlyphID16 glyphId; /* Glyph ID of reference glyph */
- Offset32To<Paint> paint; /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
- * Typically PaintColrLayers */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
-{
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- const hb_set_t* glyphset = &c->plan->_glyphset_colred;
-
- for (const auto& _ : as_array ())
- {
- unsigned gid = _.glyphId;
- if (!glyphset->has (gid)) continue;
-
- if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
- else return_trace (false);
- }
-
- return_trace (out->len != 0);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
- }
-};
-
-struct LayerList : Array32OfOffset32To<Paint>
-{
- const Paint& get_paint (unsigned i) const
- { return this+(*this)[i]; }
-
- bool subset (hb_subset_context_t *c,
- const VarStoreInstancer &instancer) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const auto& _ : + hb_enumerate (*this)
- | hb_filter (c->plan->colrv1_layers, hb_first))
-
- {
- auto *o = out->serialize_append (c->serializer);
- if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
- return_trace (false);
- }
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (Array32OfOffset32To<Paint>::sanitize (c, this));
- }
-};
-
-struct COLR
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
-
- bool has_v0_data () const { return numBaseGlyphs; }
- bool has_v1_data () const
- {
- if (version == 1)
- return (this+baseGlyphList).len > 0;
-
- return false;
- }
-
- unsigned int get_glyph_layers (hb_codepoint_t glyph,
- unsigned int start_offset,
- unsigned int *count, /* IN/OUT. May be NULL. */
- hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const
- {
- const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
-
- hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
- hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
- record.numLayers);
- if (count)
- {
- + glyph_layers.sub_array (start_offset, count)
- | hb_sink (hb_array (layers, *count))
- ;
- }
- return glyph_layers.length;
- }
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
- ~accelerator_t () { this->colr.destroy (); }
-
- bool is_valid () { return colr.get_blob ()->length; }
-
- void closure_glyphs (hb_codepoint_t glyph,
- hb_set_t *related_ids /* OUT */) const
- { colr->closure_glyphs (glyph, related_ids); }
-
- void closure_V0palette_indices (const hb_set_t *glyphs,
- hb_set_t *palettes /* OUT */) const
- { colr->closure_V0palette_indices (glyphs, palettes); }
-
- void closure_forV1 (hb_set_t *glyphset,
- hb_set_t *layer_indices,
- hb_set_t *palette_indices) const
- { colr->closure_forV1 (glyphset, layer_indices, palette_indices); }
-
- private:
- hb_blob_ptr_t<COLR> colr;
- };
-
- void closure_glyphs (hb_codepoint_t glyph,
- hb_set_t *related_ids /* OUT */) const
- {
- const BaseGlyphRecord *record = get_base_glyph_record (glyph);
- if (!record) return;
-
- auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx,
- record->numLayers);
- if (!glyph_layers.length) return;
- related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
- }
-
- void closure_V0palette_indices (const hb_set_t *glyphs,
- hb_set_t *palettes /* OUT */) const
- {
- if (!numBaseGlyphs || !numLayers) return;
- hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs);
- hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
-
- for (const BaseGlyphRecord record : baseGlyphs)
- {
- if (!glyphs->has (record.glyphId)) continue;
- hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
- record.numLayers);
- for (const LayerRecord layer : glyph_layers)
- palettes->add (layer.colorIdx);
- }
- }
-
- void closure_forV1 (hb_set_t *glyphset,
- hb_set_t *layer_indices,
- hb_set_t *palette_indices) const
- {
- if (version != 1) return;
- hb_set_t visited_glyphs;
-
- hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
- const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
-
- for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
- {
- unsigned gid = baseglyph_paintrecord.glyphId;
- if (!glyphset->has (gid)) continue;
-
- const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
- paint.dispatch (&c);
- }
- hb_set_union (glyphset, &visited_glyphs);
- }
-
- const LayerList& get_layerList () const
- { return (this+layerList); }
-
- const BaseGlyphList& get_baseglyphList () const
- { return (this+baseGlyphList); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
- (this+layersZ).sanitize (c, numLayers) &&
- (version == 0 ||
- (version == 1 &&
- baseGlyphList.sanitize (c, this) &&
- layerList.sanitize (c, this) &&
- clipList.sanitize (c, this) &&
- varIdxMap.sanitize (c, this) &&
- varStore.sanitize (c, this))));
- }
-
- template<typename BaseIterator, typename LayerIterator,
- hb_requires (hb_is_iterator (BaseIterator)),
- hb_requires (hb_is_iterator (LayerIterator))>
- bool serialize_V0 (hb_serialize_context_t *c,
- unsigned version,
- BaseIterator base_it,
- LayerIterator layer_it)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (base_it.len () != layer_it.len ()))
- return_trace (false);
-
- this->version = version;
- numLayers = 0;
- numBaseGlyphs = base_it.len ();
- if (numBaseGlyphs == 0)
- {
- baseGlyphsZ = 0;
- layersZ = 0;
- return_trace (true);
- }
-
- c->push ();
- for (const hb_item_type<BaseIterator> _ : + base_it.iter ())
- {
- auto* record = c->embed (_);
- if (unlikely (!record)) return_trace (false);
- record->firstLayerIdx = numLayers;
- numLayers += record->numLayers;
- }
- c->add_link (baseGlyphsZ, c->pop_pack ());
-
- c->push ();
- for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
- _.as_array ().copy (c);
-
- c->add_link (layersZ, c->pop_pack ());
-
- return_trace (true);
- }
-
- const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
- {
- const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
- if (record == &Null (BaseGlyphRecord) ||
- (record && (hb_codepoint_t) record->glyphId != gid))
- record = nullptr;
- return record;
- }
-
- const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
- {
- const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
- if ((record && (hb_codepoint_t) record->glyphId != gid))
- record = nullptr;
- return record;
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
- const hb_set_t& glyphset = c->plan->_glyphset_colred;
-
- auto base_it =
- + hb_range (c->plan->num_output_glyphs ())
- | hb_filter ([&](hb_codepoint_t new_gid)
- {
- hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
- if (glyphset.has (old_gid)) return true;
- return false;
- })
- | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
- {
- hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
-
- const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
- if (unlikely (!old_record))
- return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
- BaseGlyphRecord new_record = {};
- new_record.glyphId = new_gid;
- new_record.numLayers = old_record->numLayers;
- return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);
- })
- | hb_filter (hb_first)
- | hb_map_retains_sorting (hb_second)
- ;
-
- auto layer_it =
- + hb_range (c->plan->num_output_glyphs ())
- | hb_map (reverse_glyph_map)
- | hb_filter (glyphset)
- | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
- {
- const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
- hb_vector_t<LayerRecord> out_layers;
-
- if (unlikely (!old_record ||
- old_record->firstLayerIdx >= numLayers ||
- old_record->firstLayerIdx + old_record->numLayers > numLayers))
- return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
-
- auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx,
- old_record->numLayers);
- out_layers.resize (layers.length);
- for (unsigned int i = 0; i < layers.length; i++) {
- out_layers[i] = layers[i];
- hb_codepoint_t new_gid = 0;
- if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
- return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
- out_layers[i].glyphId = new_gid;
- out_layers[i].colorIdx = c->plan->colr_palettes.get (layers[i].colorIdx);
- }
-
- return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
- })
- | hb_filter (hb_first)
- | hb_map_retains_sorting (hb_second)
- ;
-
- if (version == 0 && (!base_it || !layer_it))
- return_trace (false);
-
- COLR *colr_prime = c->serializer->start_embed<COLR> ();
- if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false);
-
- if (version == 0)
- return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it));
-
- auto snap = c->serializer->snapshot ();
- if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
-
- VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
- varIdxMap ? &(this+varIdxMap) : nullptr,
- c->plan->normalized_coords.as_array ());
-
- if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
- {
- if (c->serializer->in_error ()) return_trace (false);
- //no more COLRv1 glyphs: downgrade to version 0
- c->serializer->revert (snap);
- return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
- }
-
- if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
-
- colr_prime->layerList.serialize_subset (c, layerList, this, instancer);
- colr_prime->clipList.serialize_subset (c, clipList, this, instancer);
- if (!varStore || c->plan->all_axes_pinned)
- return_trace (true);
-
- colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
- colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
- return_trace (true);
- }
-
- const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const
- {
- const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
- const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph);
- if (record)
- {
- const Paint &paint = &baseglyph_paintrecords+record->paint;
- return &paint;
- }
- else
- return nullptr;
- }
-
-#ifndef HB_NO_PAINT
- bool
- get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
- {
- if (version != 1)
- return false;
-
- VarStoreInstancer instancer (&(this+varStore),
- &(this+varIdxMap),
- hb_array (font->coords, font->num_coords));
-
- if (get_clip (glyph, extents, instancer))
- {
- font->scale_glyph_extents (extents);
- return true;
- }
-
- auto *extents_funcs = hb_paint_extents_get_funcs ();
- hb_paint_extents_context_t extents_data;
- bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
-
- hb_extents_t e = extents_data.get_extents ();
- if (e.is_void ())
- {
- extents->x_bearing = 0;
- extents->y_bearing = 0;
- extents->width = 0;
- extents->height = 0;
- }
- else
- {
- extents->x_bearing = e.xmin;
- extents->y_bearing = e.ymax;
- extents->width = e.xmax - e.xmin;
- extents->height = e.ymin - e.ymax;
- }
-
- return ret;
- }
-#endif
-
- bool
- has_paint_for_glyph (hb_codepoint_t glyph) const
- {
- if (version == 1)
- {
- const Paint *paint = get_base_glyph_paint (glyph);
-
- return paint != nullptr;
- }
-
- return false;
- }
-
- bool get_clip (hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- const VarStoreInstancer instancer) const
- {
- return (this+clipList).get_extents (glyph,
- extents,
- instancer);
- }
-
-#ifndef HB_NO_PAINT
- bool
- paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
- {
- VarStoreInstancer instancer (&(this+varStore),
- &(this+varIdxMap),
- hb_array (font->coords, font->num_coords));
- hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
-
- if (version == 1)
- {
- const Paint *paint = get_base_glyph_paint (glyph);
- if (paint)
- {
- // COLRv1 glyph
-
- VarStoreInstancer instancer (&(this+varStore),
- &(this+varIdxMap),
- hb_array (font->coords, font->num_coords));
-
- bool is_bounded = true;
- if (clip)
- {
- hb_glyph_extents_t extents;
- if (get_clip (glyph, &extents, instancer))
- {
- font->scale_glyph_extents (&extents);
- c.funcs->push_clip_rectangle (c.data,
- extents.x_bearing,
- extents.y_bearing + extents.height,
- extents.x_bearing + extents.width,
- extents.y_bearing);
- }
- else
- {
- auto *extents_funcs = hb_paint_extents_get_funcs ();
- hb_paint_extents_context_t extents_data;
-
- paint_glyph (font, glyph,
- extents_funcs, &extents_data,
- palette_index, foreground,
- false);
-
- hb_extents_t extents = extents_data.get_extents ();
- is_bounded = extents_data.is_bounded ();
-
- c.funcs->push_clip_rectangle (c.data,
- extents.xmin,
- extents.ymin,
- extents.xmax,
- extents.ymax);
- }
- }
-
- c.funcs->push_root_transform (c.data, font);
-
- if (is_bounded)
- c.recurse (*paint);
-
- c.funcs->pop_transform (c.data);
-
- if (clip)
- c.funcs->pop_clip (c.data);
-
- return true;
- }
- }
-
- const BaseGlyphRecord *record = get_base_glyph_record (glyph);
- if (record && ((hb_codepoint_t) record->glyphId == glyph))
- {
- // COLRv0 glyph
- for (const auto &r : (this+layersZ).as_array (numLayers)
- .sub_array (record->firstLayerIdx, record->numLayers))
- {
- hb_bool_t is_foreground;
- hb_color_t color = c.get_color (r.colorIdx, 1., &is_foreground);
- c.funcs->push_clip_glyph (c.data, r.glyphId, c.font);
- c.funcs->color (c.data, is_foreground, color);
- c.funcs->pop_clip (c.data);
- }
-
- return true;
- }
-
- return false;
- }
-#endif
-
- protected:
- HBUINT16 version; /* Table version number (starts at 0). */
- HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */
- NNOffset32To<SortedUnsizedArrayOf<BaseGlyphRecord>>
- baseGlyphsZ; /* Offset to Base Glyph records. */
- NNOffset32To<UnsizedArrayOf<LayerRecord>>
- layersZ; /* Offset to Layer Records. */
- HBUINT16 numLayers; /* Number of Layer Records. */
- // Version-1 additions
- Offset32To<BaseGlyphList> baseGlyphList;
- Offset32To<LayerList> layerList;
- Offset32To<ClipList> clipList; // Offset to ClipList table (may be NULL)
- Offset32To<DeltaSetIndexMap> varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL)
- Offset32To<VariationStore> varStore;
- public:
- DEFINE_SIZE_MIN (14);
-};
-
-struct COLR_accelerator_t : COLR::accelerator_t {
- COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
-};
-
-void
-hb_paint_context_t::recurse (const Paint &paint)
-{
- if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
- depth_left--;
- edge_count--;
- paint.dispatch (this);
- depth_left++;
-}
-
-void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
-{
- const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
- for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
- {
- const Paint &paint = paint_offset_lists.get_paint (i);
- c->funcs->push_group (c->data);
- c->recurse (paint);
- c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
- }
-}
-
-void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
-{
- const COLR *colr_table = c->get_colr_table ();
- const Paint *paint = colr_table->get_base_glyph_paint (gid);
-
- hb_glyph_extents_t extents = {0};
- bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
-
- if (has_clip_box)
- c->funcs->push_clip_rectangle (c->data,
- extents.x_bearing,
- extents.y_bearing + extents.height,
- extents.x_bearing + extents.width,
- extents.y_bearing);
-
- if (paint)
- c->recurse (*paint);
-
- if (has_clip_box)
- c->funcs->pop_clip (c->data);
-}
-
-} /* namespace OT */
-
-#endif /* OT_COLOR_COLR_COLR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/colrv1-closure.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/colrv1-closure.hh
deleted file mode 100644
index 705863d4ade..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/colrv1-closure.hh
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- * Copyright © 2020 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.
- *
- */
-
-#ifndef OT_COLOR_COLR_COLRV1_CLOSURE_HH
-#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
-
-#include "../../../hb-open-type.hh"
-#include "COLR.hh"
-
-/*
- * COLR -- Color
- * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
- */
-namespace OT {
-
-HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
-{
- c->add_layer_indices (firstLayerIndex, numLayers);
- const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
- for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
- {
- const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
- paint.dispatch (c);
- }
-}
-
-HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
-{
- c->add_glyph (gid);
- (this+paint).dispatch (c);
-}
-
-HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
-{
- const COLR *colr_table = c->get_colr_table ();
- const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
- if (!baseglyph_paintrecord) return;
- c->add_glyph (gid);
-
- const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
- (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
-}
-
-template <template<typename> class Var>
-HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
-{
- (this+src).dispatch (c);
- (this+backdrop).dispatch (c);
-}
-
-} /* namespace OT */
-
-
-#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh
deleted file mode 100644
index c07716c1c98..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright © 2016 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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): Sascha Brawer
- */
-
-#ifndef OT_COLOR_CPAL_CPAL_HH
-#define OT_COLOR_CPAL_CPAL_HH
-
-#include "../../../hb-open-type.hh"
-#include "../../../hb-ot-color.h"
-#include "../../../hb-ot-name.h"
-
-
-/*
- * CPAL -- Color Palette
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
- */
-#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
-
-namespace OT {
-
-
-struct CPALV1Tail
-{
- friend struct CPAL;
-
- private:
- hb_ot_color_palette_flags_t get_palette_flags (const void *base,
- unsigned int palette_index,
- unsigned int palette_count) const
- {
- if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
- return (hb_ot_color_palette_flags_t) (uint32_t)
- (base+paletteFlagsZ).as_array (palette_count)[palette_index];
- }
-
- hb_ot_name_id_t get_palette_name_id (const void *base,
- unsigned int palette_index,
- unsigned int palette_count) const
- {
- if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID;
- return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
- }
-
- hb_ot_name_id_t get_color_name_id (const void *base,
- unsigned int color_index,
- unsigned int color_count) const
- {
- if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID;
- return (base+colorLabelsZ).as_array (color_count)[color_index];
- }
-
- public:
- void collect_name_ids (const void *base,
- unsigned palette_count,
- unsigned color_count,
- const hb_map_t *color_index_map,
- hb_set_t *nameids_to_retain /* OUT */) const
- {
- if (paletteLabelsZ)
- {
- + (base+paletteLabelsZ).as_array (palette_count)
- | hb_sink (nameids_to_retain)
- ;
- }
-
- if (colorLabelsZ)
- {
- const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
- for (unsigned i = 0; i < color_count; i++)
- {
- if (!color_index_map->has (i)) continue;
- nameids_to_retain->add (colorLabels[i]);
- }
- }
- }
-
- bool serialize (hb_serialize_context_t *c,
- unsigned palette_count,
- unsigned color_count,
- const void *base,
- const hb_map_t *color_index_map) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->allocate_size<CPALV1Tail> (static_size);
- if (unlikely (!out)) return_trace (false);
-
- out->paletteFlagsZ = 0;
- if (paletteFlagsZ)
- out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
-
- out->paletteLabelsZ = 0;
- if (paletteLabelsZ)
- out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
-
- const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
- if (colorLabelsZ)
- {
- c->push ();
- for (unsigned i = 0; i < color_count; i++)
- {
- if (!color_index_map->has (i)) continue;
- if (!c->copy<NameID> (colorLabels[i]))
- {
- c->pop_discard ();
- return_trace (false);
- }
- }
- c->add_link (out->colorLabelsZ, c->pop_pack ());
- }
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c,
- const void *base,
- unsigned int palette_count,
- unsigned int color_count) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- (!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
- (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
- (!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count)));
- }
-
- protected:
- // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
- // here. Currently they are needed since UnsizedArrayOf doesn't define null_size
- NNOffset32To<UnsizedArrayOf<HBUINT32>>
- paletteFlagsZ; /* Offset from the beginning of CPAL table to
- * the Palette Type Array. Set to 0 if no array
- * is provided. */
- NNOffset32To<UnsizedArrayOf<NameID>>
- paletteLabelsZ; /* Offset from the beginning of CPAL table to
- * the palette labels array. Set to 0 if no
- * array is provided. */
- NNOffset32To<UnsizedArrayOf<NameID>>
- colorLabelsZ; /* Offset from the beginning of CPAL table to
- * the color labels array. Set to 0
- * if no array is provided. */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-typedef HBUINT32 BGRAColor;
-
-struct CPAL
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
-
- bool has_data () const { return numPalettes; }
-
- unsigned int get_size () const
- { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
-
- unsigned int get_palette_count () const { return numPalettes; }
- unsigned int get_color_count () const { return numColors; }
-
- hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
- { return v1 ().get_palette_flags (this, palette_index, numPalettes); }
-
- hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
- { return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
-
- hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
- { return v1 ().get_color_name_id (this, color_index, numColors); }
-
- unsigned int get_palette_colors (unsigned int palette_index,
- unsigned int start_offset,
- unsigned int *color_count, /* IN/OUT. May be NULL. */
- hb_color_t *colors /* OUT. May be NULL. */) const
- {
- if (unlikely (palette_index >= numPalettes))
- {
- if (color_count) *color_count = 0;
- return 0;
- }
- unsigned int start_index = colorRecordIndicesZ[palette_index];
- hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
- hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
- numColors);
- if (color_count)
- {
- + palette_colors.sub_array (start_offset, color_count)
- | hb_sink (hb_array (colors, *color_count))
- ;
- }
- return numColors;
- }
-
- void collect_name_ids (const hb_map_t *color_index_map,
- hb_set_t *nameids_to_retain /* OUT */) const
- {
- if (version == 1)
- v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain);
- }
-
- private:
- const CPALV1Tail& v1 () const
- {
- if (version == 0) return Null (CPALV1Tail);
- return StructAfter<CPALV1Tail> (*this);
- }
-
- public:
- bool serialize (hb_serialize_context_t *c,
- const hb_array_t<const HBUINT16> &color_record_indices,
- const hb_array_t<const BGRAColor> &color_records,
- const hb_vector_t<unsigned>& first_color_index_for_layer,
- const hb_map_t& first_color_to_layer_index,
- const hb_set_t &retained_color_indices) const
- {
- TRACE_SERIALIZE (this);
-
- // TODO(grieger): limit total final size.
-
- for (const auto idx : color_record_indices)
- {
- hb_codepoint_t layer_index = first_color_to_layer_index[idx];
-
- HBUINT16 new_idx;
- new_idx = layer_index * retained_color_indices.get_population ();
- if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
- }
-
- c->push ();
- for (unsigned first_color_index : first_color_index_for_layer)
- {
- for (hb_codepoint_t color_index : retained_color_indices)
- {
- if (!c->copy<BGRAColor> (color_records[first_color_index + color_index]))
- {
- c->pop_discard ();
- return_trace (false);
- }
- }
- }
-
- c->add_link (colorRecordsZ, c->pop_pack ());
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- if (!numPalettes) return_trace (false);
-
- const hb_map_t *color_index_map = &c->plan->colr_palettes;
- if (color_index_map->is_empty ()) return_trace (false);
-
- hb_set_t retained_color_indices;
- for (const auto _ : color_index_map->keys ())
- {
- if (_ == 0xFFFF) continue;
- retained_color_indices.add (_);
- }
- if (retained_color_indices.is_empty ()) return_trace (false);
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-
- out->version = version;
- out->numColors = retained_color_indices.get_population ();
- out->numPalettes = numPalettes;
-
- hb_vector_t<unsigned> first_color_index_for_layer;
- hb_map_t first_color_to_layer_index;
-
- const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
- for (const auto first_color_record_idx : colorRecordIndices)
- {
- if (first_color_to_layer_index.has (first_color_record_idx)) continue;
-
- first_color_index_for_layer.push (first_color_record_idx);
- first_color_to_layer_index.set (first_color_record_idx,
- first_color_index_for_layer.length - 1);
- }
-
- out->numColorRecords = first_color_index_for_layer.length
- * retained_color_indices.get_population ();
-
- const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
- if (!out->serialize (c->serializer,
- colorRecordIndices,
- color_records,
- first_color_index_for_layer,
- first_color_to_layer_index,
- retained_color_indices))
- return_trace (false);
-
- if (version == 1)
- return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- (this+colorRecordsZ).sanitize (c, numColorRecords) &&
- colorRecordIndicesZ.sanitize (c, numPalettes) &&
- (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
- }
-
- protected:
- HBUINT16 version; /* Table version number */
- /* Version 0 */
- HBUINT16 numColors; /* Number of colors in each palette. */
- HBUINT16 numPalettes; /* Number of palettes in the table. */
- HBUINT16 numColorRecords; /* Total number of color records, combined for
- * all palettes. */
- NNOffset32To<UnsizedArrayOf<BGRAColor>>
- colorRecordsZ; /* Offset from the beginning of CPAL table to
- * the first ColorRecord. */
- UnsizedArrayOf<HBUINT16>
- colorRecordIndicesZ; /* Index of each palette’s first color record in
- * the combined color record array. */
-/*CPALV1Tail v1;*/
- public:
- DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
-};
-
-} /* namespace OT */
-
-
-#endif /* OT_COLOR_CPAL_CPAL_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh
deleted file mode 100644
index 46ad3fd58e1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/sbix/sbix.hh
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- * Copyright © 2020 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): Calder Kitagawa
- */
-
-#ifndef OT_COLOR_SBIX_SBIX_HH
-#define OT_COLOR_SBIX_SBIX_HH
-
-#include "../../../hb-open-type.hh"
-#include "../../../hb-paint.hh"
-
-/*
- * sbix -- Standard Bitmap Graphics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
- */
-#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
-
-
-namespace OT {
-
-
-struct SBIXGlyph
-{
- SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
- {
- TRACE_SERIALIZE (this);
- SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
- if (unlikely (!new_glyph)) return_trace (nullptr);
- if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
-
- new_glyph->xOffset = xOffset;
- new_glyph->yOffset = yOffset;
- new_glyph->graphicType = graphicType;
- data.copy (c, data_length);
- return_trace (new_glyph);
- }
-
- HBINT16 xOffset; /* The horizontal (x-axis) offset from the left
- * edge of the graphic to the glyph’s origin.
- * That is, the x-coordinate of the point on the
- * baseline at the left edge of the glyph. */
- HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom
- * edge of the graphic to the glyph’s origin.
- * That is, the y-coordinate of the point on the
- * baseline at the left edge of the glyph. */
- Tag graphicType; /* Indicates the format of the embedded graphic
- * data: one of 'jpg ', 'png ' or 'tiff', or the
- * special format 'dupe'. */
- UnsizedArrayOf<HBUINT8>
- data; /* The actual embedded graphic data. The total
- * length is inferred from sequential entries in
- * the glyphDataOffsets array and the fixed size
- * (8 bytes) of the preceding fields. */
- public:
- DEFINE_SIZE_ARRAY (8, data);
-};
-
-struct SBIXStrike
-{
- static unsigned int get_size (unsigned num_glyphs)
- { return min_size + num_glyphs * HBUINT32::static_size; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
- }
-
- hb_blob_t *get_glyph_blob (unsigned int glyph_id,
- hb_blob_t *sbix_blob,
- hb_tag_t file_type,
- int *x_offset,
- int *y_offset,
- unsigned int num_glyphs,
- unsigned int *strike_ppem) const
- {
- if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */
-
- unsigned int retry_count = 8;
- unsigned int sbix_len = sbix_blob->length;
- unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data;
- assert (strike_offset < sbix_len);
-
- retry:
- if (unlikely (glyph_id >= num_glyphs ||
- imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] ||
- imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size ||
- (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset))
- return hb_blob_get_empty ();
-
- unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size;
- unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
-
- const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
-
- if (glyph->graphicType == HB_TAG ('d','u','p','e'))
- {
- if (glyph_length >= 2)
- {
- glyph_id = *((HBUINT16 *) &glyph->data);
- if (retry_count--)
- goto retry;
- }
- return hb_blob_get_empty ();
- }
-
- if (unlikely (file_type != glyph->graphicType))
- return hb_blob_get_empty ();
-
- if (strike_ppem) *strike_ppem = ppem;
- if (x_offset) *x_offset = glyph->xOffset;
- if (y_offset) *y_offset = glyph->yOffset;
- return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
- }
-
- bool subset (hb_subset_context_t *c, unsigned int available_len) const
- {
- TRACE_SUBSET (this);
- unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
-
- auto* out = c->serializer->start_embed<SBIXStrike> ();
- if (unlikely (!out)) return_trace (false);
- auto snap = c->serializer->snapshot ();
- if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
- out->ppem = ppem;
- out->resolution = resolution;
- HBUINT32 head;
- head = get_size (num_output_glyphs + 1);
-
- bool has_glyphs = false;
- for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
- {
- hb_codepoint_t old_gid;
- if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
- unlikely (imageOffsetsZ[old_gid].is_null () ||
- imageOffsetsZ[old_gid + 1].is_null () ||
- imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
- imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
- (unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
- {
- out->imageOffsetsZ[new_gid] = head;
- continue;
- }
- has_glyphs = true;
- unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
- unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
- if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
- return_trace (false);
- out->imageOffsetsZ[new_gid] = head;
- head += delta;
- }
- if (has_glyphs)
- out->imageOffsetsZ[num_output_glyphs] = head;
- else
- c->serializer->revert (snap);
- return_trace (has_glyphs);
- }
-
- public:
- HBUINT16 ppem; /* The PPEM size for which this strike was designed. */
- HBUINT16 resolution; /* The device pixel density (in PPI) for which this
- * strike was designed. (E.g., 96 PPI, 192 PPI.) */
- protected:
- UnsizedArrayOf<Offset32To<SBIXGlyph>>
- imageOffsetsZ; /* Offset from the beginning of the strike data header
- * to bitmap data for an individual glyph ID. */
- public:
- DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
-};
-
-struct sbix
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix;
-
- bool has_data () const { return version; }
-
- const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; }
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- table = hb_sanitize_context_t ().reference_table<sbix> (face);
- num_glyphs = face->get_num_glyphs ();
- }
- ~accelerator_t () { table.destroy (); }
-
- bool has_data () const { return table->has_data (); }
-
- bool get_extents (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- bool scale = true) const
- {
- /* We only support PNG right now, and following function checks type. */
- return get_png_extents (font, glyph, extents, scale);
- }
-
- hb_blob_t *reference_png (hb_font_t *font,
- hb_codepoint_t glyph_id,
- int *x_offset,
- int *y_offset,
- unsigned int *available_ppem) const
- {
- return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
- HB_TAG ('p','n','g',' '),
- x_offset, y_offset,
- num_glyphs, available_ppem);
- }
-
- bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
- {
- if (!has_data ())
- return false;
-
- int x_offset = 0, y_offset = 0;
- unsigned int strike_ppem = 0;
- hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
- hb_glyph_extents_t extents;
- hb_glyph_extents_t pixel_extents;
-
- if (blob == hb_blob_get_empty ())
- return false;
-
- if (!hb_font_get_glyph_extents (font, glyph, &extents))
- return false;
-
- if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
- return false;
-
- bool ret = funcs->image (data,
- blob,
- pixel_extents.width, -pixel_extents.height,
- HB_PAINT_IMAGE_FORMAT_PNG,
- font->slant_xy,
- &extents);
-
- hb_blob_destroy (blob);
- return ret;
- }
-
- private:
-
- const SBIXStrike &choose_strike (hb_font_t *font) const
- {
- unsigned count = table->strikes.len;
- if (unlikely (!count))
- return Null (SBIXStrike);
-
- unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
- if (!requested_ppem)
- requested_ppem = 1<<30; /* Choose largest strike. */
- /* TODO Add DPI sensitivity as well? */
- unsigned int best_i = 0;
- unsigned int best_ppem = table->get_strike (0).ppem;
-
- for (unsigned int i = 1; i < count; i++)
- {
- unsigned int ppem = (table->get_strike (i)).ppem;
- if ((requested_ppem <= ppem && ppem < best_ppem) ||
- (requested_ppem > best_ppem && ppem > best_ppem))
- {
- best_i = i;
- best_ppem = ppem;
- }
- }
-
- return table->get_strike (best_i);
- }
-
- struct PNGHeader
- {
- HBUINT8 signature[8];
- struct
- {
- struct
- {
- HBUINT32 length;
- Tag type;
- } header;
- HBUINT32 width;
- HBUINT32 height;
- HBUINT8 bitDepth;
- HBUINT8 colorType;
- HBUINT8 compressionMethod;
- HBUINT8 filterMethod;
- HBUINT8 interlaceMethod;
- } IHDR;
-
- public:
- DEFINE_SIZE_STATIC (29);
- };
-
- bool get_png_extents (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- bool scale = true) const
- {
- /* Following code is safe to call even without data.
- * But faster to short-circuit. */
- if (!has_data ())
- return false;
-
- int x_offset = 0, y_offset = 0;
- unsigned int strike_ppem = 0;
- hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
-
- const PNGHeader &png = *blob->as<PNGHeader>();
-
- if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536)
- {
- hb_blob_destroy (blob);
- return false;
- }
-
- extents->x_bearing = x_offset;
- extents->y_bearing = png.IHDR.height + y_offset;
- extents->width = png.IHDR.width;
- extents->height = -1 * png.IHDR.height;
-
- /* Convert to font units. */
- if (strike_ppem && scale)
- {
- float scale = font->face->get_upem () / (float) strike_ppem;
- extents->x_bearing = roundf (extents->x_bearing * scale);
- extents->y_bearing = roundf (extents->y_bearing * scale);
- extents->width = roundf (extents->width * scale);
- extents->height = roundf (extents->height * scale);
- }
-
- if (scale)
- font->scale_glyph_extents (extents);
-
- hb_blob_destroy (blob);
-
- return strike_ppem;
- }
-
- private:
- hb_blob_ptr_t<sbix> table;
-
- unsigned int num_glyphs;
- };
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version >= 1 &&
- strikes.sanitize (c, this)));
- }
-
- bool
- add_strike (hb_subset_context_t *c, unsigned i) const
- {
- if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
- return false;
-
- return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
- }
-
- bool serialize_strike_offsets (hb_subset_context_t *c) const
- {
- TRACE_SERIALIZE (this);
-
- auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
- if (unlikely (!out)) return_trace (false);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
- hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
- for (int i = strikes.len - 1; i >= 0; --i)
- {
- auto* o = out->serialize_append (c->serializer);
- if (unlikely (!o)) return_trace (false);
- *o = 0;
- auto snap = c->serializer->snapshot ();
- c->serializer->push ();
- bool ret = add_strike (c, i);
- if (!ret)
- {
- c->serializer->pop_discard ();
- out->pop ();
- c->serializer->revert (snap);
- }
- else
- {
- objidxs.push (c->serializer->pop_pack ());
- new_strikes.push (o);
- }
- }
- for (unsigned int i = 0; i < new_strikes.length; ++i)
- c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t* c) const
- {
- TRACE_SUBSET (this);
-
- sbix *sbix_prime = c->serializer->start_embed<sbix> ();
- if (unlikely (!sbix_prime)) return_trace (false);
- if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
- if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
-
- return_trace (serialize_strike_offsets (c));
- }
-
- protected:
- HBUINT16 version; /* Table version number — set to 1 */
- HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines.
- * Bits 2 to 15: reserved (set to 0). */
- Array32OfOffset32To<SBIXStrike>
- strikes; /* Offsets from the beginning of the 'sbix'
- * table to data for each individual bitmap strike. */
- public:
- DEFINE_SIZE_ARRAY (8, strikes);
-};
-
-struct sbix_accelerator_t : sbix::accelerator_t {
- sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
-};
-
-
-} /* namespace OT */
-
-#endif /* OT_COLOR_SBIX_SBIX_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh
deleted file mode 100644
index c7d91b88ee0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/svg/svg.hh
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef OT_COLOR_SVG_SVG_HH
-#define OT_COLOR_SVG_SVG_HH
-
-#include "../../../hb-open-type.hh"
-#include "../../../hb-blob.hh"
-#include "../../../hb-paint.hh"
-
-/*
- * SVG -- SVG (Scalable Vector Graphics)
- * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
- */
-
-#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
-
-
-namespace OT {
-
-
-struct SVGDocumentIndexEntry
-{
- int cmp (hb_codepoint_t g) const
- { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
-
- hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
- {
- return hb_blob_create_sub_blob (svg_blob,
- index_offset + (unsigned int) svgDoc,
- svgDocLength);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- svgDoc.sanitize (c, base, svgDocLength));
- }
-
- protected:
- HBUINT16 startGlyphID; /* The first glyph ID in the range described by
- * this index entry. */
- HBUINT16 endGlyphID; /* The last glyph ID in the range described by
- * this index entry. Must be >= startGlyphID. */
- NNOffset32To<UnsizedArrayOf<HBUINT8>>
- svgDoc; /* Offset from the beginning of the SVG Document Index
- * to an SVG document. Must be non-zero. */
- HBUINT32 svgDocLength; /* Length of the SVG document.
- * Must be non-zero. */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct SVG
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG;
-
- bool has_data () const { return svgDocEntries; }
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
- ~accelerator_t () { table.destroy (); }
-
- hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
- {
- return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
- table->svgDocEntries);
- }
-
- bool has_data () const { return table->has_data (); }
-
- bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
- {
- if (!has_data ())
- return false;
-
- hb_blob_t *blob = reference_blob_for_glyph (glyph);
-
- if (blob == hb_blob_get_empty ())
- return false;
-
- funcs->image (data,
- blob,
- 0, 0,
- HB_PAINT_IMAGE_FORMAT_SVG,
- font->slant_xy,
- nullptr);
-
- hb_blob_destroy (blob);
- return true;
- }
-
- private:
- hb_blob_ptr_t<SVG> table;
- public:
- DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t<SVG>));
- };
-
- const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
- { return (this+svgDocEntries).bsearch (glyph_id); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (this+svgDocEntries).sanitize_shallow (c)));
- }
-
- protected:
- HBUINT16 version; /* Table version (starting at 0). */
- Offset32To<SortedArray16Of<SVGDocumentIndexEntry>>
- svgDocEntries; /* Offset (relative to the start of the SVG table) to the
- * SVG Documents Index. Must be non-zero. */
- /* Array of SVG Document Index Entries. */
- HBUINT32 reserved; /* Set to 0. */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-struct SVG_accelerator_t : SVG::accelerator_t {
- SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* OT_COLOR_SVG_SVG_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
deleted file mode 100644
index d35654e2457..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod, Garret Rieger
- */
-
-#ifndef OT_LAYOUT_COMMON_COVERAGE_HH
-#define OT_LAYOUT_COMMON_COVERAGE_HH
-
-#include "../types.hh"
-#include "CoverageFormat1.hh"
-#include "CoverageFormat2.hh"
-
-namespace OT {
-namespace Layout {
-namespace Common {
-
-template<typename Iterator>
-static inline void Coverage_serialize (hb_serialize_context_t *c,
- Iterator it);
-
-struct Coverage
-{
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- CoverageFormat1_3<SmallTypes> format1;
- CoverageFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BEYOND_64K
- CoverageFormat1_3<MediumTypes>format3;
- CoverageFormat2_4<MediumTypes>format4;
-#endif
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format)
- {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.sanitize (c));
- case 4: return_trace (u.format4.sanitize (c));
-#endif
- default:return_trace (true);
- }
- }
-
- /* Has interface. */
- unsigned operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; }
- /* Predicate. */
- bool operator () (hb_codepoint_t k) const { return has (k); }
-
- unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
- unsigned int get_coverage (hb_codepoint_t glyph_id) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage (glyph_id);
- case 2: return u.format2.get_coverage (glyph_id);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.get_coverage (glyph_id);
- case 4: return u.format4.get_coverage (glyph_id);
-#endif
- default:return NOT_COVERED;
- }
- }
-
- unsigned get_population () const
- {
- switch (u.format) {
- case 1: return u.format1.get_population ();
- case 2: return u.format2.get_population ();
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.get_population ();
- case 4: return u.format4.get_population ();
-#endif
- default:return NOT_COVERED;
- }
- }
-
- template <typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c, Iterator glyphs)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- unsigned count = 0;
- unsigned num_ranges = 0;
- hb_codepoint_t last = (hb_codepoint_t) -2;
- for (auto g: glyphs)
- {
- if (last + 1 != g)
- num_ranges++;
- last = g;
- count++;
- }
- u.format = count <= num_ranges * 3 ? 1 : 2;
-
-#ifndef HB_NO_BEYOND_64K
- if (count && last > 0xFFFFu)
- u.format += 2;
-#endif
-
- switch (u.format)
- {
- case 1: return_trace (u.format1.serialize (c, glyphs));
- case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.serialize (c, glyphs));
- case 4: return_trace (u.format4.serialize (c, glyphs));
-#endif
- default:return_trace (false);
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto it =
- + iter ()
- | hb_take (c->plan->source->get_num_glyphs ())
- | hb_filter (c->plan->glyph_map_gsub)
- | hb_map_retains_sorting (c->plan->glyph_map_gsub)
- ;
-
- // Cache the iterator result as it will be iterated multiple times
- // by the serialize code below.
- hb_sorted_vector_t<hb_codepoint_t> glyphs (it);
- Coverage_serialize (c->serializer, glyphs.iter ());
- return_trace (bool (glyphs));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- switch (u.format)
- {
- case 1: return u.format1.intersects (glyphs);
- case 2: return u.format2.intersects (glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersects (glyphs);
- case 4: return u.format4.intersects (glyphs);
-#endif
- default:return false;
- }
- }
- bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
- {
- switch (u.format)
- {
- case 1: return u.format1.intersects_coverage (glyphs, index);
- case 2: return u.format2.intersects_coverage (glyphs, index);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersects_coverage (glyphs, index);
- case 4: return u.format4.intersects_coverage (glyphs, index);
-#endif
- default:return false;
- }
- }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- {
- switch (u.format)
- {
- case 1: return u.format1.collect_coverage (glyphs);
- case 2: return u.format2.collect_coverage (glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.collect_coverage (glyphs);
- case 4: return u.format4.collect_coverage (glyphs);
-#endif
- default:return false;
- }
- }
-
- template <typename IterableOut,
- hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
- void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
- {
- switch (u.format)
- {
- case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
- case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
- case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
-#endif
- default:return ;
- }
- }
-
- struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
- {
- static constexpr bool is_sorted_iterator = true;
- iter_t (const Coverage &c_ = Null (Coverage))
- {
- hb_memset (this, 0, sizeof (*this));
- format = c_.u.format;
- switch (format)
- {
- case 1: u.format1.init (c_.u.format1); return;
- case 2: u.format2.init (c_.u.format2); return;
-#ifndef HB_NO_BEYOND_64K
- case 3: u.format3.init (c_.u.format3); return;
- case 4: u.format4.init (c_.u.format4); return;
-#endif
- default: return;
- }
- }
- bool __more__ () const
- {
- switch (format)
- {
- case 1: return u.format1.__more__ ();
- case 2: return u.format2.__more__ ();
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.__more__ ();
- case 4: return u.format4.__more__ ();
-#endif
- default:return false;
- }
- }
- void __next__ ()
- {
- switch (format)
- {
- case 1: u.format1.__next__ (); break;
- case 2: u.format2.__next__ (); break;
-#ifndef HB_NO_BEYOND_64K
- case 3: u.format3.__next__ (); break;
- case 4: u.format4.__next__ (); break;
-#endif
- default: break;
- }
- }
- typedef hb_codepoint_t __item_t__;
- __item_t__ __item__ () const { return get_glyph (); }
-
- hb_codepoint_t get_glyph () const
- {
- switch (format)
- {
- case 1: return u.format1.get_glyph ();
- case 2: return u.format2.get_glyph ();
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.get_glyph ();
- case 4: return u.format4.get_glyph ();
-#endif
- default:return 0;
- }
- }
- bool operator != (const iter_t& o) const
- {
- if (unlikely (format != o.format)) return true;
- switch (format)
- {
- case 1: return u.format1 != o.u.format1;
- case 2: return u.format2 != o.u.format2;
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3 != o.u.format3;
- case 4: return u.format4 != o.u.format4;
-#endif
- default:return false;
- }
- }
- iter_t __end__ () const
- {
- iter_t it = {};
- it.format = format;
- switch (format)
- {
- case 1: it.u.format1 = u.format1.__end__ (); break;
- case 2: it.u.format2 = u.format2.__end__ (); break;
-#ifndef HB_NO_BEYOND_64K
- case 3: it.u.format3 = u.format3.__end__ (); break;
- case 4: it.u.format4 = u.format4.__end__ (); break;
-#endif
- default: break;
- }
- return it;
- }
-
- private:
- unsigned int format;
- union {
-#ifndef HB_NO_BEYOND_64K
- CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */
- CoverageFormat1_3<MediumTypes>::iter_t format3;
-#endif
- CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */
- CoverageFormat1_3<SmallTypes>::iter_t format1;
- } u;
- };
- iter_t iter () const { return iter_t (*this); }
-};
-
-template<typename Iterator>
-static inline void
-Coverage_serialize (hb_serialize_context_t *c,
- Iterator it)
-{ c->start_embed<Coverage> ()->serialize (c, it); }
-
-}
-}
-}
-
-#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh
deleted file mode 100644
index 5d68e3d15e7..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod, Garret Rieger
- */
-
-
-#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
-#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
-
-namespace OT {
-namespace Layout {
-namespace Common {
-
-#define NOT_COVERED ((unsigned int) -1)
-
-template <typename Types>
-struct CoverageFormat1_3
-{
- friend struct Coverage;
-
- protected:
- HBUINT16 coverageFormat; /* Format identifier--format = 1 */
- SortedArray16Of<typename Types::HBGlyphID>
- glyphArray; /* Array of GlyphIDs--in numerical order */
- public:
- DEFINE_SIZE_ARRAY (4, glyphArray);
-
- private:
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (glyphArray.sanitize (c));
- }
-
- unsigned int get_coverage (hb_codepoint_t glyph_id) const
- {
- unsigned int i;
- glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED);
- return i;
- }
-
- unsigned get_population () const
- {
- return glyphArray.len;
- }
-
- template <typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c, Iterator glyphs)
- {
- TRACE_SERIALIZE (this);
- return_trace (glyphArray.serialize (c, glyphs));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
- {
- for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
- if (get_coverage (g) != NOT_COVERED)
- return true;
- return false;
- }
-
- for (const auto& g : glyphArray.as_array ())
- if (glyphs->has (g))
- return true;
- return false;
- }
- bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
- { return glyphs->has (glyphArray[index]); }
-
- template <typename IterableOut,
- hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
- void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
- {
- unsigned count = glyphArray.len;
- for (unsigned i = 0; i < count; i++)
- if (glyphs.has (glyphArray[i]))
- intersect_glyphs << glyphArray[i];
- }
-
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- { return glyphs->add_sorted_array (glyphArray.as_array ()); }
-
- public:
- /* Older compilers need this to be public. */
- struct iter_t
- {
- void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; }
- bool __more__ () const { return i < c->glyphArray.len; }
- void __next__ () { i++; }
- hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
- bool operator != (const iter_t& o) const
- { return i != o.i; }
- iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
-
- private:
- const struct CoverageFormat1_3 *c;
- unsigned int i;
- };
- private:
-};
-
-}
-}
-}
-
-#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh
deleted file mode 100644
index d7fcc352028..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod, Garret Rieger
- */
-
-#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
-#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
-
-#include "RangeRecord.hh"
-
-namespace OT {
-namespace Layout {
-namespace Common {
-
-template <typename Types>
-struct CoverageFormat2_4
-{
- friend struct Coverage;
-
- protected:
- HBUINT16 coverageFormat; /* Format identifier--format = 2 */
- SortedArray16Of<RangeRecord<Types>>
- rangeRecord; /* Array of glyph ranges--ordered by
- * Start GlyphID. rangeCount entries
- * long */
- public:
- DEFINE_SIZE_ARRAY (4, rangeRecord);
-
- private:
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (rangeRecord.sanitize (c));
- }
-
- unsigned int get_coverage (hb_codepoint_t glyph_id) const
- {
- const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id);
- return likely (range.first <= range.last)
- ? (unsigned int) range.value + (glyph_id - range.first)
- : NOT_COVERED;
- }
-
- unsigned get_population () const
- {
- typename Types::large_int ret = 0;
- for (const auto &r : rangeRecord)
- ret += r.get_population ();
- return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
- }
-
- template <typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c, Iterator glyphs)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- unsigned num_ranges = 0;
- hb_codepoint_t last = (hb_codepoint_t) -2;
- for (auto g: glyphs)
- {
- if (last + 1 != g)
- num_ranges++;
- last = g;
- }
-
- if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
- if (!num_ranges) return_trace (true);
-
- unsigned count = 0;
- unsigned range = (unsigned) -1;
- last = (hb_codepoint_t) -2;
- for (auto g: glyphs)
- {
- if (last + 1 != g)
- {
- range++;
- rangeRecord[range].first = g;
- rangeRecord[range].value = count;
- }
- rangeRecord[range].last = g;
- last = g;
- count++;
- }
-
- return_trace (true);
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
- {
- for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
- if (get_coverage (g) != NOT_COVERED)
- return true;
- return false;
- }
-
- return hb_any (+ hb_iter (rangeRecord)
- | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
- }
- bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
- {
- auto *range = rangeRecord.as_array ().bsearch (index);
- if (range)
- return range->intersects (*glyphs);
- return false;
- }
-
- template <typename IterableOut,
- hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
- void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
- {
- /* Break out of loop for overlapping, broken, tables,
- * to avoid fuzzer timouts. */
- hb_codepoint_t last = 0;
- for (const auto& range : rangeRecord)
- {
- if (unlikely (range.first < last))
- break;
- last = range.last;
- for (hb_codepoint_t g = range.first - 1;
- glyphs.next (&g) && g <= last;)
- intersect_glyphs << g;
- }
- }
-
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- {
- for (const auto& range: rangeRecord)
- if (unlikely (!range.collect_coverage (glyphs)))
- return false;
- return true;
- }
-
- public:
- /* Older compilers need this to be public. */
- struct iter_t
- {
- void init (const CoverageFormat2_4 &c_)
- {
- c = &c_;
- coverage = 0;
- i = 0;
- j = c->rangeRecord.len ? c->rangeRecord[0].first : 0;
- if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last))
- {
- /* Broken table. Skip. */
- i = c->rangeRecord.len;
- j = 0;
- }
- }
- bool __more__ () const { return i < c->rangeRecord.len; }
- void __next__ ()
- {
- if (j >= c->rangeRecord[i].last)
- {
- i++;
- if (__more__ ())
- {
- unsigned int old = coverage;
- j = c->rangeRecord[i].first;
- coverage = c->rangeRecord[i].value;
- if (unlikely (coverage != old + 1))
- {
- /* Broken table. Skip. Important to avoid DoS.
- * Also, our callers depend on coverage being
- * consecutive and monotonically increasing,
- * ie. iota(). */
- i = c->rangeRecord.len;
- j = 0;
- return;
- }
- }
- else
- j = 0;
- return;
- }
- coverage++;
- j++;
- }
- hb_codepoint_t get_glyph () const { return j; }
- bool operator != (const iter_t& o) const
- { return i != o.i || j != o.j; }
- iter_t __end__ () const
- {
- iter_t it;
- it.init (*c);
- it.i = c->rangeRecord.len;
- it.j = 0;
- return it;
- }
-
- private:
- const struct CoverageFormat2_4 *c;
- unsigned int i, coverage;
- hb_codepoint_t j;
- };
- private:
-};
-
-}
-}
-}
-
-#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh
deleted file mode 100644
index a62629fad34..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod, Garret Rieger
- */
-
-#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
-#define OT_LAYOUT_COMMON_RANGERECORD_HH
-
-namespace OT {
-namespace Layout {
-namespace Common {
-
-template <typename Types>
-struct RangeRecord
-{
- typename Types::HBGlyphID first; /* First GlyphID in the range */
- typename Types::HBGlyphID last; /* Last GlyphID in the range */
- HBUINT16 value; /* Value */
-
- DEFINE_SIZE_STATIC (2 + 2 * Types::size);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- int cmp (hb_codepoint_t g) const
- { return g < first ? -1 : g <= last ? 0 : +1; }
-
- unsigned get_population () const
- {
- if (unlikely (last < first)) return 0;
- return (last - first + 1);
- }
-
- bool intersects (const hb_set_t &glyphs) const
- { return glyphs.intersects (first, last); }
-
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- { return glyphs->add_range (first, last); }
-};
-
-}
-}
-}
-
-// TODO(garretrieger): This was previously implemented using
-// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9);
-// but that only works when there is only a single namespace level.
-// The macro should probably be fixed so it can work in this situation.
-extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9];
-template <typename Spec>
-struct Null<OT::Layout::Common::RangeRecord<Spec>> {
- static OT::Layout::Common::RangeRecord<Spec> const & get_null () {
- return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord);
- }
-};
-
-
-#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
deleted file mode 100644
index 0551fcf812a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
+++ /dev/null
@@ -1,918 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef OT_LAYOUT_GDEF_GDEF_HH
-#define OT_LAYOUT_GDEF_GDEF_HH
-
-#include "../../../hb-ot-layout-common.hh"
-
-#include "../../../hb-font.hh"
-
-
-namespace OT {
-
-
-/*
- * Attachment List Table
- */
-
-/* Array of contour point indices--in increasing numerical order */
-struct AttachPoint : Array16Of<HBUINT16>
-{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- return_trace (out->serialize (c->serializer, + iter ()));
- }
-};
-
-struct AttachList
-{
- unsigned int get_attach_points (hb_codepoint_t glyph_id,
- unsigned int start_offset,
- unsigned int *point_count /* IN/OUT */,
- unsigned int *point_array /* OUT */) const
- {
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (index == NOT_COVERED)
- {
- if (point_count)
- *point_count = 0;
- return 0;
- }
-
- const AttachPoint &points = this+attachPoint[index];
-
- if (point_count)
- {
- + points.as_array ().sub_array (start_offset, point_count)
- | hb_sink (hb_array (point_array, *point_count))
- ;
- }
-
- return points.len;
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, attachPoint)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
- }
-
- protected:
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table -- from
- * beginning of AttachList table */
- Array16OfOffset16To<AttachPoint>
- attachPoint; /* Array of AttachPoint tables
- * in Coverage Index order */
- public:
- DEFINE_SIZE_ARRAY (4, attachPoint);
-};
-
-/*
- * Ligature Caret Table
- */
-
-struct CaretValueFormat1
-{
- friend struct CaretValue;
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
- return_trace (true);
- }
-
- private:
- hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
- {
- return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 caretValueFormat; /* Format identifier--format = 1 */
- FWORD coordinate; /* X or Y value, in design units */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct CaretValueFormat2
-{
- friend struct CaretValue;
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
- return_trace (true);
- }
-
- private:
- hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
- {
- hb_position_t x, y;
- font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
- return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 caretValueFormat; /* Format identifier--format = 2 */
- HBUINT16 caretValuePoint; /* Contour point index on glyph */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct CaretValueFormat3
-{
- friend struct CaretValue;
-
- hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
- const VariationStore &var_store) const
- {
- return HB_DIRECTION_IS_HORIZONTAL (direction) ?
- font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
- font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
- if (!c->serializer->embed (caretValueFormat)) return_trace (false);
- if (!c->serializer->embed (coordinate)) return_trace (false);
-
- unsigned varidx = (this+deviceTable).get_variation_index ();
- if (c->plan->layout_variation_idx_delta_map.has (varidx))
- {
- int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
- if (delta != 0)
- {
- if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- }
- }
-
- if (c->plan->all_axes_pinned)
- return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
-
- if (!c->serializer->embed (deviceTable))
- return_trace (false);
-
- return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
- hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- { (this+deviceTable).collect_variation_indices (c); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
- }
-
- protected:
- HBUINT16 caretValueFormat; /* Format identifier--format = 3 */
- FWORD coordinate; /* X or Y value, in design units */
- Offset16To<Device>
- deviceTable; /* Offset to Device table for X or Y
- * value--from beginning of CaretValue
- * table */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct CaretValue
-{
- hb_position_t get_caret_value (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t glyph_id,
- const VariationStore &var_store) const
- {
- switch (u.format) {
- case 1: return u.format1.get_caret_value (font, direction);
- case 2: return u.format2.get_caret_value (font, direction, glyph_id);
- case 3: return u.format3.get_caret_value (font, direction, var_store);
- default:return 0;
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- switch (u.format) {
- case 1:
- case 2:
- return;
- case 3:
- u.format3.collect_variation_indices (c);
- return;
- default: return;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 3: return_trace (u.format3.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- CaretValueFormat1 format1;
- CaretValueFormat2 format2;
- CaretValueFormat3 format3;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-struct LigGlyph
-{
- unsigned get_lig_carets (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t glyph_id,
- const VariationStore &var_store,
- unsigned start_offset,
- unsigned *caret_count /* IN/OUT */,
- hb_position_t *caret_array /* OUT */) const
- {
- if (caret_count)
- {
- + carets.as_array ().sub_array (start_offset, caret_count)
- | hb_map (hb_add (this))
- | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
- | hb_sink (hb_array (caret_array, *caret_count))
- ;
- }
-
- return carets.len;
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- + hb_iter (carets)
- | hb_apply (subset_offset_array (c, out->carets, this))
- ;
-
- return_trace (bool (out->carets));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- for (const Offset16To<CaretValue>& offset : carets.iter ())
- (this+offset).collect_variation_indices (c);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (carets.sanitize (c, this));
- }
-
- protected:
- Array16OfOffset16To<CaretValue>
- carets; /* Offset array of CaretValue tables
- * --from beginning of LigGlyph table
- * --in increasing coordinate order */
- public:
- DEFINE_SIZE_ARRAY (2, carets);
-};
-
-struct LigCaretList
-{
- unsigned int get_lig_carets (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t glyph_id,
- const VariationStore &var_store,
- unsigned int start_offset,
- unsigned int *caret_count /* IN/OUT */,
- hb_position_t *caret_array /* OUT */) const
- {
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (index == NOT_COVERED)
- {
- if (caret_count)
- *caret_count = 0;
- return 0;
- }
- const LigGlyph &lig_glyph = this+ligGlyph[index];
- return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, ligGlyph)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+coverage, ligGlyph)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
- ;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
- }
-
- protected:
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of LigCaretList table */
- Array16OfOffset16To<LigGlyph>
- ligGlyph; /* Array of LigGlyph tables
- * in Coverage Index order */
- public:
- DEFINE_SIZE_ARRAY (4, ligGlyph);
-};
-
-
-struct MarkGlyphSetsFormat1
-{
- bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
- { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- bool ret = true;
- for (const Offset32To<Coverage>& offset : coverage.iter ())
- {
- auto *o = out->coverage.serialize_append (c->serializer);
- if (unlikely (!o))
- {
- ret = false;
- break;
- }
-
- //not using o->serialize_subset (c, offset, this, out) here because
- //OTS doesn't allow null offset.
- //See issue: https://github.com/khaledhosny/ots/issues/172
- c->serializer->push ();
- c->dispatch (this+offset);
- c->serializer->add_link (*o, c->serializer->pop_pack ());
- }
-
- return_trace (ret && out->coverage.len);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Array16Of<Offset32To<Coverage>>
- coverage; /* Array of long offsets to mark set
- * coverage tables */
- public:
- DEFINE_SIZE_ARRAY (4, coverage);
-};
-
-struct MarkGlyphSets
-{
- bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
- {
- switch (u.format) {
- case 1: return u.format1.covers (set_index, glyph_id);
- default:return false;
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- switch (u.format) {
- case 1: return_trace (u.format1.subset (c));
- default:return_trace (false);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkGlyphSetsFormat1 format1;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-
-/*
- * GDEF -- Glyph Definition
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
- */
-
-
-template <typename Types>
-struct GDEFVersion1_2
-{
- friend struct GDEF;
-
- protected:
- FixedVersion<>version; /* Version of the GDEF table--currently
- * 0x00010003u */
- typename Types::template OffsetTo<ClassDef>
- glyphClassDef; /* Offset to class definition table
- * for glyph type--from beginning of
- * GDEF header (may be Null) */
- typename Types::template OffsetTo<AttachList>
- attachList; /* Offset to list of glyphs with
- * attachment points--from beginning
- * of GDEF header (may be Null) */
- typename Types::template OffsetTo<LigCaretList>
- ligCaretList; /* Offset to list of positioning points
- * for ligature carets--from beginning
- * of GDEF header (may be Null) */
- typename Types::template OffsetTo<ClassDef>
- markAttachClassDef; /* Offset to class definition table for
- * mark attachment type--from beginning
- * of GDEF header (may be Null) */
- typename Types::template OffsetTo<MarkGlyphSets>
- markGlyphSetsDef; /* Offset to the table of mark set
- * definitions--from beginning of GDEF
- * header (may be NULL). Introduced
- * in version 0x00010002. */
- Offset32To<VariationStore>
- varStore; /* Offset to the table of Item Variation
- * Store--from beginning of GDEF
- * header (may be NULL). Introduced
- * in version 0x00010003. */
- public:
- DEFINE_SIZE_MIN (4 + 4 * Types::size);
-
- unsigned int get_size () const
- {
- return min_size +
- (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
- (version.to_int () >= 0x00010003u ? varStore.static_size : 0);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (version.sanitize (c) &&
- glyphClassDef.sanitize (c, this) &&
- attachList.sanitize (c, this) &&
- ligCaretList.sanitize (c, this) &&
- markAttachClassDef.sanitize (c, this) &&
- (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
- (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
- bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
- bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
- bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
-
- bool subset_markglyphsetsdef = false;
- if (version.to_int () >= 0x00010002u)
- {
- subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
- }
-
- bool subset_varstore = false;
- if (version.to_int () >= 0x00010003u)
- {
- if (c->plan->all_axes_pinned)
- out->varStore = 0;
- else
- subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
- }
-
- if (subset_varstore)
- {
- out->version.minor = 3;
- } else if (subset_markglyphsetsdef) {
- out->version.minor = 2;
- } else {
- out->version.minor = 0;
- }
-
- return_trace (subset_glyphclassdef || subset_attachlist ||
- subset_ligcaretlist || subset_markattachclassdef ||
- (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
- (out->version.to_int () >= 0x00010003u && subset_varstore));
- }
-};
-
-struct GDEF
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
-
- enum GlyphClasses {
- UnclassifiedGlyph = 0,
- BaseGlyph = 1,
- LigatureGlyph = 2,
- MarkGlyph = 3,
- ComponentGlyph = 4
- };
-
- unsigned int get_size () const
- {
- switch (u.version.major) {
- case 1: return u.version1.get_size ();
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.get_size ();
-#endif
- default: return u.version.static_size;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!u.version.sanitize (c))) return_trace (false);
- switch (u.version.major) {
- case 1: return_trace (u.version1.sanitize (c));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (u.version2.sanitize (c));
-#endif
- default: return_trace (true);
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- switch (u.version.major) {
- case 1: return u.version1.subset (c);
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.subset (c);
-#endif
- default: return false;
- }
- }
-
- bool has_glyph_classes () const
- {
- switch (u.version.major) {
- case 1: return u.version1.glyphClassDef != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.glyphClassDef != 0;
-#endif
- default: return false;
- }
- }
- const ClassDef &get_glyph_class_def () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.glyphClassDef;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.glyphClassDef;
-#endif
- default: return Null(ClassDef);
- }
- }
- bool has_attach_list () const
- {
- switch (u.version.major) {
- case 1: return u.version1.attachList != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.attachList != 0;
-#endif
- default: return false;
- }
- }
- const AttachList &get_attach_list () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.attachList;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.attachList;
-#endif
- default: return Null(AttachList);
- }
- }
- bool has_lig_carets () const
- {
- switch (u.version.major) {
- case 1: return u.version1.ligCaretList != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.ligCaretList != 0;
-#endif
- default: return false;
- }
- }
- const LigCaretList &get_lig_caret_list () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.ligCaretList;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.ligCaretList;
-#endif
- default: return Null(LigCaretList);
- }
- }
- bool has_mark_attachment_types () const
- {
- switch (u.version.major) {
- case 1: return u.version1.markAttachClassDef != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.markAttachClassDef != 0;
-#endif
- default: return false;
- }
- }
- const ClassDef &get_mark_attach_class_def () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.markAttachClassDef;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.markAttachClassDef;
-#endif
- default: return Null(ClassDef);
- }
- }
- bool has_mark_glyph_sets () const
- {
- switch (u.version.major) {
- case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.markGlyphSetsDef != 0;
-#endif
- default: return false;
- }
- }
- const MarkGlyphSets &get_mark_glyph_sets () const
- {
- switch (u.version.major) {
- case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.markGlyphSetsDef;
-#endif
- default: return Null(MarkGlyphSets);
- }
- }
- bool has_var_store () const
- {
- switch (u.version.major) {
- case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.varStore != 0;
-#endif
- default: return false;
- }
- }
- const VariationStore &get_var_store () const
- {
- switch (u.version.major) {
- case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore);
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.varStore;
-#endif
- default: return Null(VariationStore);
- }
- }
-
-
- bool has_data () const { return u.version.to_int (); }
- unsigned int get_glyph_class (hb_codepoint_t glyph) const
- { return get_glyph_class_def ().get_class (glyph); }
- void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
- { get_glyph_class_def ().collect_class (glyphs, klass); }
-
- unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
- { return get_mark_attach_class_def ().get_class (glyph); }
-
- unsigned int get_attach_points (hb_codepoint_t glyph_id,
- unsigned int start_offset,
- unsigned int *point_count /* IN/OUT */,
- unsigned int *point_array /* OUT */) const
- { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
-
- unsigned int get_lig_carets (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t glyph_id,
- unsigned int start_offset,
- unsigned int *caret_count /* IN/OUT */,
- hb_position_t *caret_array /* OUT */) const
- { return get_lig_caret_list ().get_lig_carets (font,
- direction, glyph_id, get_var_store(),
- start_offset, caret_count, caret_array); }
-
- bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
- { return get_mark_glyph_sets ().covers (set_index, glyph_id); }
-
- /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
- * glyph class and other bits, and high 8-bit the mark attachment type (if any).
- * Not to be confused with lookup_props which is very similar. */
- unsigned int get_glyph_props (hb_codepoint_t glyph) const
- {
- unsigned int klass = get_glyph_class (glyph);
-
- 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 HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
- case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
- case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
- case MarkGlyph:
- klass = get_mark_attachment_type (glyph);
- return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
- }
- }
-
- HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
- hb_face_t *face) const;
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- table = hb_sanitize_context_t ().reference_table<GDEF> (face);
- if (unlikely (table->is_blocklisted (table.get_blob (), face)))
- {
- hb_blob_destroy (table.get_blob ());
- table = hb_blob_get_empty ();
- }
- }
- ~accelerator_t () { table.destroy (); }
-
- hb_blob_ptr_t<GDEF> table;
- };
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- { get_lig_caret_list ().collect_variation_indices (c); }
-
- void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
- hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
- {
- if (!has_var_store ()) return;
- if (layout_variation_indices->is_empty ()) return;
-
- unsigned new_major = 0, new_minor = 0;
- unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
- for (unsigned idx : layout_variation_indices->iter ())
- {
- uint16_t major = idx >> 16;
- if (major >= get_var_store ().get_sub_table_count ()) break;
- if (major != last_major)
- {
- new_minor = 0;
- ++new_major;
- }
-
- unsigned new_idx = (new_major << 16) + new_minor;
- if (!layout_variation_idx_delta_map->has (idx))
- continue;
- int delta = hb_second (layout_variation_idx_delta_map->get (idx));
-
- layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
- ++new_minor;
- last_major = major;
- }
- }
-
- protected:
- union {
- FixedVersion<> version; /* Version identifier */
- GDEFVersion1_2<SmallTypes> version1;
-#ifndef HB_NO_BEYOND_64K
- GDEFVersion1_2<MediumTypes> version2;
-#endif
- } u;
- public:
- DEFINE_SIZE_MIN (4);
-};
-
-struct GDEF_accelerator_t : GDEF::accelerator_t {
- GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* OT_LAYOUT_GDEF_GDEF_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh
deleted file mode 100644
index 49e76e77509..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Anchor.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_ANCHOR_HH
-#define OT_LAYOUT_GPOS_ANCHOR_HH
-
-#include "AnchorFormat1.hh"
-#include "AnchorFormat2.hh"
-#include "AnchorFormat3.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct Anchor
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- AnchorFormat1 format1;
- AnchorFormat2 format2;
- AnchorFormat3 format3;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 3: return_trace (u.format3.sanitize (c));
- default:return_trace (true);
- }
- }
-
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
- float *x, float *y) const
- {
- *x = *y = 0;
- switch (u.format) {
- case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
- case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
- case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
- default: return;
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- switch (u.format) {
- case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
- case 2:
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- {
- // AnchorFormat 2 just containins extra hinting information, so
- // if hints are being dropped convert to format 1.
- return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
- }
- return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer))));
- case 3: return_trace (u.format3.subset (c));
- default:return_trace (false);
- }
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- switch (u.format) {
- case 1: case 2:
- return;
- case 3:
- u.format3.collect_variation_indices (c);
- return;
- default: return;
- }
- }
-};
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_ANCHOR_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat1.hh
deleted file mode 100644
index 738cc31bbfa..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat1.hh
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
-#define OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct AnchorFormat1
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- public:
- DEFINE_SIZE_STATIC (6);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
- }
-
- AnchorFormat1* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- AnchorFormat1* out = c->embed<AnchorFormat1> (this);
- if (!out) return_trace (out);
- out->format = 1;
- return_trace (out);
- }
-};
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat2.hh
deleted file mode 100644
index 70b4d19f53c..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat2.hh
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
-#define OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct AnchorFormat2
-{
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- HBUINT16 anchorPoint; /* Index to glyph contour point */
- public:
- DEFINE_SIZE_STATIC (8);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
-
-#ifdef HB_NO_HINTING
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
- return;
-#endif
-
- unsigned int x_ppem = font->x_ppem;
- unsigned int y_ppem = font->y_ppem;
- hb_position_t cx = 0, cy = 0;
- bool ret;
-
- ret = (x_ppem || y_ppem) &&
- font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
- *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
- *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
- }
-
- AnchorFormat2* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed<AnchorFormat2> (this));
- }
-};
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh
deleted file mode 100644
index e7e3c5c6d1e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorFormat3.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
-#define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct AnchorFormat3
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 3 */
- FWORD xCoordinate; /* Horizontal value--in design units */
- FWORD yCoordinate; /* Vertical value--in design units */
- Offset16To<Device>
- xDeviceTable; /* Offset to Device table for X
- * coordinate-- from beginning of
- * Anchor table (may be NULL) */
- Offset16To<Device>
- yDeviceTable; /* Offset to Device table for Y
- * coordinate-- from beginning of
- * Anchor table (may be NULL) */
- public:
- DEFINE_SIZE_STATIC (10);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
- }
-
- void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
- float *x, float *y) const
- {
- hb_font_t *font = c->font;
- *x = font->em_fscale_x (xCoordinate);
- *y = font->em_fscale_y (yCoordinate);
-
- if (font->x_ppem || font->num_coords)
- *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
- if (font->y_ppem || font->num_coords)
- *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
- if (unlikely (!c->serializer->embed (format))) return_trace (false);
- if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
- if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
-
- unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
- if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
- {
- int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
- if (delta != 0)
- {
- if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- }
- }
-
- unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
- if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
- {
- int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
- if (delta != 0)
- {
- if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- }
- }
-
- if (c->plan->all_axes_pinned)
- return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
-
- if (!c->serializer->embed (xDeviceTable)) return_trace (false);
- if (!c->serializer->embed (yDeviceTable)) return_trace (false);
-
- out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
- out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
- return_trace (out);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- (this+xDeviceTable).collect_variation_indices (c);
- (this+yDeviceTable).collect_variation_indices (c);
- }
-};
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh
deleted file mode 100644
index c442efa1eaa..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
-#define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct AnchorMatrix
-{
- HBUINT16 rows; /* Number of rows */
- UnsizedArrayOf<Offset16To<Anchor>>
- matrixZ; /* Matrix of offsets to Anchor tables--
- * from beginning of AnchorMatrix table */
- public:
- DEFINE_SIZE_ARRAY (2, matrixZ);
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
- {
- TRACE_SANITIZE (this);
- if (!c->check_struct (this)) return_trace (false);
- if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
- unsigned int count = rows * cols;
- if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
- for (unsigned int i = 0; i < count; i++)
- if (!matrixZ[i].sanitize (c, this)) return_trace (false);
- return_trace (true);
- }
-
- const Anchor& get_anchor (unsigned int row, unsigned int col,
- unsigned int cols, bool *found) const
- {
- *found = false;
- if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
- *found = !matrixZ[row * cols + col].is_null ();
- return this+matrixZ[row * cols + col];
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- Iterator index_iter) const
- {
- for (unsigned i : index_iter)
- (this+matrixZ[i]).collect_variation_indices (c);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- unsigned num_rows,
- Iterator index_iter) const
- {
- TRACE_SUBSET (this);
-
- auto *out = c->serializer->start_embed (this);
-
- if (!index_iter) return_trace (false);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- out->rows = num_rows;
- for (const unsigned i : index_iter)
- {
- auto *offset = c->serializer->embed (matrixZ[i]);
- if (!offset) return_trace (false);
- offset->serialize_subset (c, matrixZ[i], this);
- }
-
- return_trace (true);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ChainContextPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ChainContextPos.hh
deleted file mode 100644
index d551ac2a2be..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ChainContextPos.hh
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
-#define OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct ChainContextPos : ChainContext {};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh
deleted file mode 100644
index 408197454f1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/Common.hh
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_COMMON_HH
-#define OT_LAYOUT_GPOS_COMMON_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-enum attach_type_t {
- ATTACH_TYPE_NONE = 0X00,
-
- /* Each attachment should be either a mark or a cursive; can't be both. */
- ATTACH_TYPE_MARK = 0X01,
- ATTACH_TYPE_CURSIVE = 0X02,
-};
-
-/* buffer **position** var allocations */
-#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
-#define attach_type() var.u8[2] /* attachment type */
-/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
-
-template<typename Iterator, typename SrcLookup>
-static void SinglePos_serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
- bool all_axes_pinned);
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_COMMON_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ContextPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ContextPos.hh
deleted file mode 100644
index 2a01eaa3a68..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ContextPos.hh
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_CONTEXTPOS_HH
-#define OT_LAYOUT_GPOS_CONTEXTPOS_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct ContextPos : Context {};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_CONTEXTPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePos.hh
deleted file mode 100644
index 0105a9b8542..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePos.hh
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_CURSIVEPOS_HH
-#define OT_LAYOUT_GPOS_CURSIVEPOS_HH
-
-#include "CursivePosFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct CursivePos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- CursivePosFormat1 format1;
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_CURSIVEPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh
deleted file mode 100644
index ff255e090a2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ /dev/null
@@ -1,301 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
-
-#include "Anchor.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct EntryExitRecord
-{
- friend struct CursivePosFormat1;
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *src_base) const
- {
- (src_base+entryAnchor).collect_variation_indices (c);
- (src_base+exitAnchor).collect_variation_indices (c);
- }
-
- EntryExitRecord* subset (hb_subset_context_t *c,
- const void *src_base) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
- out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
- return_trace (out);
- }
-
- protected:
- Offset16To<Anchor>
- entryAnchor; /* Offset to EntryAnchor table--from
- * beginning of CursivePos
- * subtable--may be NULL */
- Offset16To<Anchor>
- exitAnchor; /* Offset to ExitAnchor table--from
- * beginning of CursivePos
- * subtable--may be NULL */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-static void
-reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) {
- int chain = pos[i].attach_chain(), type = pos[i].attach_type();
- if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
- return;
-
- pos[i].attach_chain() = 0;
-
- unsigned int j = (int) i + chain;
-
- /* Stop if we see new parent in the chain. */
- if (j == new_parent)
- return;
-
- reverse_cursive_minor_offset (pos, j, direction, new_parent);
-
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- pos[j].y_offset = -pos[i].y_offset;
- else
- pos[j].x_offset = -pos[i].x_offset;
-
- pos[j].attach_chain() = -chain;
- pos[j].attach_type() = type;
-}
-
-
-struct CursivePosFormat1
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- Array16Of<EntryExitRecord>
- entryExitRecord; /* Array of EntryExit records--in
- * Coverage Index order */
- public:
- DEFINE_SIZE_ARRAY (6, entryExitRecord);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+coverage, entryExitRecord)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
-
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
- if (!this_record.entryAnchor) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- unsigned unsafe_from;
- if (!skippy_iter.prev (&unsafe_from))
- {
- buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
- return_trace (false);
- }
-
- const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
- if (!prev_record.exitAnchor)
- {
- buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
- return_trace (false);
- }
-
- unsigned int i = skippy_iter.idx;
- unsigned int j = buffer->idx;
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "cursive attaching glyph at %u to glyph at %u",
- i, j);
- }
-
- buffer->unsafe_to_break (i, j + 1);
- float entry_x, entry_y, exit_x, exit_y;
- (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
- (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
-
- hb_glyph_position_t *pos = buffer->pos;
-
- hb_position_t d;
- /* Main-direction adjustment */
- switch (c->direction) {
- case HB_DIRECTION_LTR:
- pos[i].x_advance = roundf (exit_x) + pos[i].x_offset;
-
- d = roundf (entry_x) + pos[j].x_offset;
- pos[j].x_advance -= d;
- pos[j].x_offset -= d;
- break;
- case HB_DIRECTION_RTL:
- d = roundf (exit_x) + pos[i].x_offset;
- pos[i].x_advance -= d;
- pos[i].x_offset -= d;
-
- pos[j].x_advance = roundf (entry_x) + pos[j].x_offset;
- break;
- case HB_DIRECTION_TTB:
- pos[i].y_advance = roundf (exit_y) + pos[i].y_offset;
-
- d = roundf (entry_y) + pos[j].y_offset;
- pos[j].y_advance -= d;
- pos[j].y_offset -= d;
- break;
- case HB_DIRECTION_BTT:
- d = roundf (exit_y) + pos[i].y_offset;
- pos[i].y_advance -= d;
- pos[i].y_offset -= d;
-
- pos[j].y_advance = roundf (entry_y);
- break;
- case HB_DIRECTION_INVALID:
- default:
- break;
- }
-
- /* Cross-direction adjustment */
-
- /* We attach child to parent (think graph theory and rooted trees whereas
- * the root stays on baseline and each node aligns itself against its
- * parent.
- *
- * Optimize things for the case of RightToLeft, as that's most common in
- * Arabic. */
- unsigned int child = i;
- unsigned int parent = j;
- hb_position_t x_offset = entry_x - exit_x;
- hb_position_t y_offset = entry_y - exit_y;
- if (!(c->lookup_props & LookupFlag::RightToLeft))
- {
- unsigned int k = child;
- child = parent;
- parent = k;
- x_offset = -x_offset;
- y_offset = -y_offset;
- }
-
- /* If child was already connected to someone else, walk through its old
- * chain and reverse the link direction, such that the whole tree of its
- * previous connection now attaches to new parent. Watch out for case
- * where new parent is on the path from old chain...
- */
- reverse_cursive_minor_offset (pos, child, c->direction, parent);
-
- pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
- pos[child].attach_chain() = (int) parent - (int) child;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
- pos[child].y_offset = y_offset;
- else
- pos[child].x_offset = x_offset;
-
- /* If parent was attached to child, separate them.
- * https://github.com/harfbuzz/harfbuzz/issues/2469
- */
- if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
- {
- pos[parent].attach_chain() = 0;
- if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
- pos[parent].y_offset = 0;
- else
- pos[parent].x_offset = 0;
- }
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "cursive attached glyph at %u to glyph at %u",
- i, j);
- }
-
- buffer->idx++;
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_subset_context_t *c,
- Iterator it,
- const void *src_base)
- {
- if (unlikely (!c->serializer->extend_min ((*this)))) return;
- this->format = 1;
- this->entryExitRecord.len = it.len ();
-
- for (const EntryExitRecord& entry_record : + it
- | hb_map (hb_second))
- entry_record.subset (c, src_base);
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c->serializer, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- auto it =
- + hb_zip (this+coverage, entryExitRecord)
- | hb_filter (glyphset, hb_first)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
- { return hb_pair (glyph_map[p.first], p.second);})
- ;
-
- bool ret = bool (it);
- out->serialize (c, it, this);
- return_trace (ret);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ExtensionPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ExtensionPos.hh
deleted file mode 100644
index d1808adab40..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ExtensionPos.hh
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_EXTENSIONPOS_HH
-#define OT_LAYOUT_GPOS_EXTENSIONPOS_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct ExtensionPos : Extension<ExtensionPos>
-{
- typedef struct PosLookupSubTable SubTable;
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_EXTENSIONPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh
deleted file mode 100644
index 9493ec987e8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh
+++ /dev/null
@@ -1,171 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_GPOS_HH
-#define OT_LAYOUT_GPOS_GPOS_HH
-
-#include "../../../hb-ot-layout-common.hh"
-#include "../../../hb-ot-layout-gsubgpos.hh"
-#include "Common.hh"
-#include "PosLookup.hh"
-
-namespace OT {
-
-using Layout::GPOS_impl::PosLookup;
-
-namespace Layout {
-
-static void
-propagate_attachment_offsets (hb_glyph_position_t *pos,
- unsigned int len,
- unsigned int i,
- hb_direction_t direction,
- unsigned nesting_level = HB_MAX_NESTING_LEVEL);
-
-/*
- * GPOS -- Glyph Positioning
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
- */
-
-struct GPOS : GSUBGPOS
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
-
- using Lookup = PosLookup;
-
- const PosLookup& get_lookup (unsigned int i) const
- { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
-
- static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
- static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
- static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
-
- bool subset (hb_subset_context_t *c) const
- {
- hb_subset_layout_context_t l (c, tableTag);
- return GSUBGPOS::subset<PosLookup> (&l);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (GSUBGPOS::sanitize<PosLookup> (c));
- }
-
- HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
- hb_face_t *face) const;
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
- {
- if (!c->gpos_lookups->has (i)) continue;
- const PosLookup &l = get_lookup (i);
- l.dispatch (c);
- }
- }
-
- void closure_lookups (hb_face_t *face,
- const hb_set_t *glyphs,
- hb_set_t *lookup_indexes /* IN/OUT */) const
- { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
-
- typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
-};
-
-
-static void
-propagate_attachment_offsets (hb_glyph_position_t *pos,
- unsigned int len,
- unsigned int i,
- hb_direction_t direction,
- unsigned nesting_level)
-{
- /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
- * offset of glyph they are attached to. */
- int chain = pos[i].attach_chain(), type = pos[i].attach_type();
- if (likely (!chain))
- return;
-
- pos[i].attach_chain() = 0;
-
- unsigned int j = (int) i + chain;
-
- if (unlikely (j >= len))
- return;
-
- if (unlikely (!nesting_level))
- return;
-
- propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
-
- assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
-
- if (type & GPOS_impl::ATTACH_TYPE_CURSIVE)
- {
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- pos[i].y_offset += pos[j].y_offset;
- else
- pos[i].x_offset += pos[j].x_offset;
- }
- else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/
- {
- pos[i].x_offset += pos[j].x_offset;
- pos[i].y_offset += pos[j].y_offset;
-
- assert (j < i);
- if (HB_DIRECTION_IS_FORWARD (direction))
- for (unsigned int k = j; k < i; k++) {
- pos[i].x_offset -= pos[k].x_advance;
- pos[i].y_offset -= pos[k].y_advance;
- }
- else
- for (unsigned int k = j + 1; k < i + 1; k++) {
- pos[i].x_offset += pos[k].x_advance;
- pos[i].y_offset += pos[k].y_advance;
- }
- }
-}
-
-void
-GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
-{
- unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
-}
-
-void
-GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
-{
- //_hb_buffer_assert_gsubgpos_vars (buffer);
-}
-
-void
-GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
-{
- _hb_buffer_assert_gsubgpos_vars (buffer);
-
- unsigned int len;
- hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
- hb_direction_t direction = buffer->props.direction;
-
- /* Handle attachments */
- if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
- for (unsigned i = 0; i < len; i++)
- propagate_attachment_offsets (pos, len, i, direction);
-
- if (unlikely (font->slant))
- {
- for (unsigned i = 0; i < len; i++)
- if (unlikely (pos[i].y_offset))
- pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
- }
-}
-
-}
-
-struct GPOS_accelerator_t : Layout::GPOS::accelerator_t {
- GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {}
-};
-
-}
-
-#endif /* OT_LAYOUT_GPOS_GPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh
deleted file mode 100644
index a2d807cc320..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH
-#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-
-typedef AnchorMatrix LigatureAttach; /* component-major--
- * in order of writing direction--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
-struct LigatureArray : List16OfOffset16To<LigatureAttach>
-{
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- unsigned class_count,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const auto _ : + hb_zip (coverage, *this)
- | hb_filter (glyphset, hb_first))
- {
- auto *matrix = out->serialize_append (c->serializer);
- if (unlikely (!matrix)) return_trace (false);
-
- const LigatureAttach& src = (this + _.second);
- auto indexes =
- + hb_range (src.rows * class_count)
- | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
- ;
- matrix->serialize_subset (c,
- _.second,
- this,
- src.rows,
- indexes);
- }
- return_trace (this->len);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkArray.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkArray.hh
deleted file mode 100644
index ff43ffb8c57..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkArray.hh
+++ /dev/null
@@ -1,128 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKARRAY_HH
-#define OT_LAYOUT_GPOS_MARKARRAY_HH
-
-#include "AnchorMatrix.hh"
-#include "MarkRecord.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage order */
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (Array16Of<MarkRecord>::sanitize (c, this));
- }
-
- bool apply (hb_ot_apply_context_t *c,
- unsigned int mark_index, unsigned int glyph_index,
- const AnchorMatrix &anchors, unsigned int class_count,
- unsigned int glyph_pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index);
- unsigned int mark_class = record.klass;
-
- const Anchor& mark_anchor = this + record.markAnchor;
- bool found;
- const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
- /* If this subtable doesn't have an anchor for this base and this class,
- * return false such that the subsequent subtables have a chance at it. */
- if (unlikely (!found)) return_trace (false);
-
- float mark_x, mark_y, base_x, base_y;
-
- buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
- 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);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "attaching mark glyph at %u to glyph at %u",
- c->buffer->idx, glyph_pos);
- }
-
- hb_glyph_position_t &o = buffer->cur_pos();
- o.x_offset = roundf (base_x - mark_x);
- o.y_offset = roundf (base_y - mark_y);
- o.attach_type() = ATTACH_TYPE_MARK;
- o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "attached mark glyph at %u to glyph at %u",
- c->buffer->idx, glyph_pos);
- }
-
- buffer->idx++;
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto* out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- auto mark_iter =
- + hb_zip (coverage, this->iter ())
- | hb_filter (glyphset, hb_first)
- | hb_map (hb_second)
- ;
-
- unsigned new_length = 0;
- for (const auto& mark_record : mark_iter) {
- if (unlikely (!mark_record.subset (c, this, klass_mapping)))
- return_trace (false);
- new_length++;
- }
-
- if (unlikely (!c->serializer->check_assign (out->len, new_length,
- HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
- return_trace (false);
-
- return_trace (true);
- }
-};
-
-HB_INTERNAL inline
-void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
- const MarkArray &mark_array,
- const hb_set_t &glyphset,
- hb_map_t* klass_mapping /* INOUT */)
-{
- hb_set_t orig_classes;
-
- + hb_zip (mark_coverage, mark_array)
- | hb_filter (glyphset, hb_first)
- | hb_map (hb_second)
- | hb_map (&MarkRecord::get_class)
- | hb_sink (orig_classes)
- ;
-
- unsigned idx = 0;
- for (auto klass : orig_classes.iter ())
- {
- if (klass_mapping->has (klass)) continue;
- klass_mapping->set (klass, idx);
- idx++;
- }
-}
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKARRAY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePos.hh
deleted file mode 100644
index cd2fc7ccfdd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePos.hh
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKBASEPOS_HH
-#define OT_LAYOUT_GPOS_MARKBASEPOS_HH
-
-#include "MarkBasePosFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct MarkBasePos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkBasePosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- MarkBasePosFormat1_2<MediumTypes> format2;
-#endif
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKBASEPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
deleted file mode 100644
index eb4712049b1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ /dev/null
@@ -1,244 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
-
-#include "MarkArray.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-typedef AnchorMatrix BaseArray; /* base-major--
- * in order of BaseCoverage Index--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-template <typename Types>
-struct MarkBasePosFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- markCoverage; /* Offset to MarkCoverage table--from
- * beginning of MarkBasePos subtable */
- typename Types::template OffsetTo<Coverage>
- baseCoverage; /* Offset to BaseCoverage table--from
- * beginning of MarkBasePos subtable */
- HBUINT16 classCount; /* Number of classes defined for marks */
- typename Types::template OffsetTo<MarkArray>
- markArray; /* Offset to MarkArray table--from
- * beginning of MarkBasePos subtable */
- typename Types::template OffsetTo<BaseArray>
- baseArray; /* Offset to BaseArray table--from
- * beginning of MarkBasePos subtable */
-
- public:
- DEFINE_SIZE_STATIC (4 + 4 * Types::size);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- markCoverage.sanitize (c, this) &&
- baseCoverage.sanitize (c, this) &&
- markArray.sanitize (c, this) &&
- baseArray.sanitize (c, this, (unsigned int) classCount));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+markCoverage).intersects (glyphs) &&
- (this+baseCoverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
-
- unsigned basecount = (this+baseArray).rows;
- auto base_iter =
- + hb_zip (this+baseCoverage, hb_range (basecount))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- hb_sorted_vector_t<unsigned> base_indexes;
- for (const unsigned row : base_iter)
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (base_indexes)
- ;
- }
- (this+baseArray).collect_variation_indices (c, base_indexes.iter ());
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+markCoverage; }
-
- static inline bool accept (hb_buffer_t *buffer, unsigned idx)
- {
- /* We only want to attach to the first of a MultipleSubst sequence.
- * https://github.com/harfbuzz/harfbuzz/issues/740
- * Reject others...
- * ...but stop if we find a mark in the MultipleSubst sequence:
- * https://github.com/harfbuzz/harfbuzz/issues/1020 */
- return !_hb_glyph_info_multiplied (&buffer->info[idx]) ||
- 0 == _hb_glyph_info_get_lig_comp (&buffer->info[idx]) ||
- (idx == 0 ||
- _hb_glyph_info_is_mark (&buffer->info[idx - 1]) ||
- !_hb_glyph_info_multiplied (&buffer->info[idx - 1]) ||
- _hb_glyph_info_get_lig_id (&buffer->info[idx]) !=
- _hb_glyph_info_get_lig_id (&buffer->info[idx - 1]) ||
- _hb_glyph_info_get_lig_comp (&buffer->info[idx]) !=
- _hb_glyph_info_get_lig_comp (&buffer->info[idx - 1]) + 1
- );
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
-
- /* Now we search backwards for a non-mark glyph.
- * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
-
- if (c->last_base_until > buffer->idx)
- {
- c->last_base_until = 0;
- c->last_base = -1;
- }
- unsigned j;
- for (j = buffer->idx; j > c->last_base_until; j--)
- {
- auto match = skippy_iter.match (buffer->info[j - 1]);
- if (match == skippy_iter.MATCH)
- {
- // https://github.com/harfbuzz/harfbuzz/issues/4124
- if (!accept (buffer, j - 1) &&
- NOT_COVERED == (this+baseCoverage).get_coverage (buffer->info[j - 1].codepoint))
- match = skippy_iter.SKIP;
- }
- if (match == skippy_iter.MATCH)
- {
- c->last_base = (signed) j - 1;
- break;
- }
- }
- c->last_base_until = buffer->idx;
- if (c->last_base == -1)
- {
- buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
- return_trace (false);
- }
-
- unsigned idx = (unsigned) c->last_base;
-
- /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
- //if (!_hb_glyph_info_is_base_glyph (&buffer->info[idx])) { return_trace (false); }
-
- unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[idx].codepoint);
- if (base_index == NOT_COVERED)
- {
- buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
- return_trace (false);
- }
-
- return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark_iter =
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (glyphset, hb_first)
- ;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + mark_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- out->markArray.serialize_subset (c, markArray, this,
- (this+markCoverage).iter (),
- &klass_mapping);
-
- unsigned basecount = (this+baseArray).rows;
- auto base_iter =
- + hb_zip (this+baseCoverage, hb_range (basecount))
- | hb_filter (glyphset, hb_first)
- ;
-
- new_coverage.reset ();
- + base_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- hb_sorted_vector_t<unsigned> base_indexes;
- for (const unsigned row : + base_iter
- | hb_map (hb_second))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (base_indexes)
- ;
- }
-
- out->baseArray.serialize_subset (c, baseArray, this,
- base_iter.len (),
- base_indexes.iter ());
-
- return_trace (true);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPos.hh
deleted file mode 100644
index 739c325411c..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPos.hh
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKLIGPOS_HH
-#define OT_LAYOUT_GPOS_MARKLIGPOS_HH
-
-#include "MarkLigPosFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct MarkLigPos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkLigPosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- MarkLigPosFormat1_2<MediumTypes> format2;
-#endif
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKLIGPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
deleted file mode 100644
index 92e83a0e994..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ /dev/null
@@ -1,223 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
-
-#include "LigatureArray.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-
-template <typename Types>
-struct MarkLigPosFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- markCoverage; /* Offset to Mark Coverage table--from
- * beginning of MarkLigPos subtable */
- typename Types::template OffsetTo<Coverage>
- ligatureCoverage; /* Offset to Ligature Coverage
- * table--from beginning of MarkLigPos
- * subtable */
- HBUINT16 classCount; /* Number of defined mark classes */
- typename Types::template OffsetTo<MarkArray>
- markArray; /* Offset to MarkArray table--from
- * beginning of MarkLigPos subtable */
- typename Types::template OffsetTo<LigatureArray>
- ligatureArray; /* Offset to LigatureArray table--from
- * beginning of MarkLigPos subtable */
- public:
- DEFINE_SIZE_STATIC (4 + 4 * Types::size);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- markCoverage.sanitize (c, this) &&
- ligatureCoverage.sanitize (c, this) &&
- markArray.sanitize (c, this) &&
- ligatureArray.sanitize (c, this, (unsigned int) classCount));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+markCoverage).intersects (glyphs) &&
- (this+ligatureCoverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
-
- unsigned ligcount = (this+ligatureArray).len;
- auto lig_iter =
- + hb_zip (this+ligatureCoverage, hb_range (ligcount))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- const LigatureArray& lig_array = this+ligatureArray;
- for (const unsigned i : lig_iter)
- {
- hb_sorted_vector_t<unsigned> lig_indexes;
- unsigned row_count = lig_array[i].rows;
- for (unsigned row : + hb_range (row_count))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (lig_indexes)
- ;
- }
-
- lig_array[i].collect_variation_indices (c, lig_indexes.iter ());
- }
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+markCoverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark_index == NOT_COVERED)) return_trace (false);
-
- /* Now we search backwards for a non-mark glyph */
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
-
- if (c->last_base_until > buffer->idx)
- {
- c->last_base_until = 0;
- c->last_base = -1;
- }
- unsigned j;
- for (j = buffer->idx; j > c->last_base_until; j--)
- {
- auto match = skippy_iter.match (buffer->info[j - 1]);
- if (match == skippy_iter.MATCH)
- {
- c->last_base = (signed) j - 1;
- break;
- }
- }
- c->last_base_until = buffer->idx;
- if (c->last_base == -1)
- {
- buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
- return_trace (false);
- }
-
- unsigned idx = (unsigned) c->last_base;
-
- /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
- //if (!_hb_glyph_info_is_ligature (&buffer->info[idx])) { return_trace (false); }
-
- unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[idx].codepoint);
- if (lig_index == NOT_COVERED)
- {
- buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
- return_trace (false);
- }
-
- const LigatureArray& lig_array = this+ligatureArray;
- const LigatureAttach& lig_attach = lig_array[lig_index];
-
- /* Find component to attach to */
- unsigned int comp_count = lig_attach.rows;
- if (unlikely (!comp_count))
- {
- buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
- return_trace (false);
- }
-
- /* We must now check whether the ligature ID of the current mark glyph
- * is identical to the ligature ID of the found ligature. If yes, we
- * can directly use the component index. If not, we attach the mark
- * glyph to the last component of the ligature. */
- unsigned int comp_index;
- unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[idx]);
- unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
- unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
- if (lig_id && lig_id == mark_id && mark_comp > 0)
- comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
- else
- comp_index = comp_count - 1;
-
- return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark_iter =
- + hb_zip (this+markCoverage, this+markArray)
- | hb_filter (glyphset, hb_first)
- ;
-
- auto new_mark_coverage =
- + mark_iter
- | hb_map_retains_sorting (hb_first)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
- return_trace (false);
-
- out->markArray.serialize_subset (c, markArray, this,
- (this+markCoverage).iter (),
- &klass_mapping);
-
- auto new_ligature_coverage =
- + hb_iter (this + ligatureCoverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
- return_trace (false);
-
- out->ligatureArray.serialize_subset (c, ligatureArray, this,
- hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
-
- return_trace (true);
- }
-
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPos.hh
deleted file mode 100644
index cddd2a3d507..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPos.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKMARKPOS_HH
-#define OT_LAYOUT_GPOS_MARKMARKPOS_HH
-
-#include "MarkMarkPosFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct MarkMarkPos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MarkMarkPosFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- MarkMarkPosFormat1_2<MediumTypes> format2;
-#endif
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKMARKPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
deleted file mode 100644
index fbcebb80441..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ /dev/null
@@ -1,228 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
-
-#include "MarkMarkPosFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-typedef AnchorMatrix Mark2Array; /* mark2-major--
- * in order of Mark2Coverage Index--,
- * mark1-minor--
- * ordered by class--zero-based. */
-
-template <typename Types>
-struct MarkMarkPosFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- mark1Coverage; /* Offset to Combining Mark1 Coverage
- * table--from beginning of MarkMarkPos
- * subtable */
- typename Types::template OffsetTo<Coverage>
- mark2Coverage; /* Offset to Combining Mark2 Coverage
- * table--from beginning of MarkMarkPos
- * subtable */
- HBUINT16 classCount; /* Number of defined mark classes */
- typename Types::template OffsetTo<MarkArray>
- mark1Array; /* Offset to Mark1Array table--from
- * beginning of MarkMarkPos subtable */
- typename Types::template OffsetTo<Mark2Array>
- mark2Array; /* Offset to Mark2Array table--from
- * beginning of MarkMarkPos subtable */
- public:
- DEFINE_SIZE_STATIC (4 + 4 * Types::size);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- mark1Coverage.sanitize (c, this) &&
- mark2Coverage.sanitize (c, this) &&
- mark1Array.sanitize (c, this) &&
- mark2Array.sanitize (c, this, (unsigned int) classCount));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+mark1Coverage).intersects (glyphs) &&
- (this+mark2Coverage).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- + hb_zip (this+mark1Coverage, this+mark1Array)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })
- ;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping);
-
- unsigned mark2_count = (this+mark2Array).rows;
- auto mark2_iter =
- + hb_zip (this+mark2Coverage, hb_range (mark2_count))
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- hb_sorted_vector_t<unsigned> mark2_indexes;
- for (const unsigned row : mark2_iter)
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (mark2_indexes)
- ;
- }
- (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ());
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+mark1Coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
- if (likely (mark1_index == NOT_COVERED)) return_trace (false);
-
- /* now we search backwards for a suitable mark glyph until a non-mark glyph */
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
- unsigned unsafe_from;
- if (!skippy_iter.prev (&unsafe_from))
- {
- buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
- return_trace (false);
- }
-
- if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
- {
- buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
- return_trace (false);
- }
-
- unsigned int j = skippy_iter.idx;
-
- unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
- unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
- unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
- unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
-
- if (likely (id1 == id2))
- {
- if (id1 == 0) /* Marks belonging to the same base. */
- goto good;
- else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
- goto good;
- }
- else
- {
- /* If ligature ids don't match, it may be the case that one of the marks
- * itself is a ligature. In which case match. */
- if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
- goto good;
- }
-
- /* Didn't match. */
- buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
- return_trace (false);
-
- good:
- unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
- if (mark2_index == NOT_COVERED)
- {
- buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
- return_trace (false);
- }
-
- return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass_mapping;
- Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
-
- if (!klass_mapping.get_population ()) return_trace (false);
- out->classCount = klass_mapping.get_population ();
-
- auto mark1_iter =
- + hb_zip (this+mark1Coverage, this+mark1Array)
- | hb_filter (glyphset, hb_first)
- ;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + mark1_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- out->mark1Array.serialize_subset (c, mark1Array, this,
- (this+mark1Coverage).iter (),
- &klass_mapping);
-
- unsigned mark2count = (this+mark2Array).rows;
- auto mark2_iter =
- + hb_zip (this+mark2Coverage, hb_range (mark2count))
- | hb_filter (glyphset, hb_first)
- ;
-
- new_coverage.reset ();
- + mark2_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
- hb_sorted_vector_t<unsigned> mark2_indexes;
- for (const unsigned row : + mark2_iter
- | hb_map (hb_second))
- {
- + hb_range ((unsigned) classCount)
- | hb_filter (klass_mapping)
- | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
- | hb_sink (mark2_indexes)
- ;
- }
-
- out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
-
- return_trace (true);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkRecord.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkRecord.hh
deleted file mode 100644
index a7d489d2a51..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkRecord.hh
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_MARKRECORD_HH
-#define OT_LAYOUT_GPOS_MARKRECORD_HH
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct MarkRecord
-{
- friend struct MarkArray;
-
- public:
- HBUINT16 klass; /* Class defined for this mark */
- Offset16To<Anchor>
- markAnchor; /* Offset to Anchor table--from
- * beginning of MarkArray table */
- public:
- DEFINE_SIZE_STATIC (4);
-
- unsigned get_class () const { return (unsigned) klass; }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
- }
-
- MarkRecord *subset (hb_subset_context_t *c,
- const void *src_base,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- out->klass = klass_mapping->get (klass);
- out->markAnchor.serialize_subset (c, markAnchor, src_base);
- return_trace (out);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *src_base) const
- {
- (src_base+markAnchor).collect_variation_indices (c);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_MARKRECORD_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPos.hh
deleted file mode 100644
index c13d4f48941..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPos.hh
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_PAIRPOS_HH
-#define OT_LAYOUT_GPOS_PAIRPOS_HH
-
-#include "PairPosFormat1.hh"
-#include "PairPosFormat2.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct PairPos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- PairPosFormat1_3<SmallTypes> format1;
- PairPosFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BEYOND_64K
- PairPosFormat1_3<MediumTypes> format3;
- PairPosFormat2_4<MediumTypes> format4;
-#endif
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_PAIRPOS_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
deleted file mode 100644
index 4dada1c8301..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ /dev/null
@@ -1,217 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
-
-#include "PairSet.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-
-template <typename Types>
-struct PairPosFormat1_3
-{
- using PairSet = GPOS_impl::PairSet<Types>;
- using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat[2]; /* [0] Defines the types of data in
- * ValueRecord1--for the first glyph
- * in the pair--may be zero (0) */
- /* [1] Defines the types of data in
- * ValueRecord2--for the second glyph
- * in the pair--may be zero (0) */
- Array16Of<typename Types::template OffsetTo<PairSet>>
- pairSet; /* Array of PairSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (8 + Types::size, pairSet);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
-
- if (!c->check_struct (this)) return_trace (false);
-
- unsigned int len1 = valueFormat[0].get_len ();
- unsigned int len2 = valueFormat[1].get_len ();
- typename PairSet::sanitize_closure_t closure =
- {
- valueFormat,
- len1,
- PairSet::get_size (len1, len2)
- };
-
- return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- auto &cov = this+coverage;
-
- if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
- {
- for (hb_codepoint_t g : glyphs->iter())
- {
- unsigned i = cov.get_coverage (g);
- if ((this+pairSet[i]).intersects (glyphs, valueFormat))
- return true;
- }
- return false;
- }
-
- return
- + hb_zip (cov, pairSet)
- | hb_filter (*glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
- { return (this+_).intersects (glyphs, valueFormat); })
- | hb_any
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if ((!valueFormat[0].has_device ()) && (!valueFormat[1].has_device ())) return;
-
- auto it =
- + hb_zip (this+coverage, pairSet)
- | hb_filter (c->glyph_set, hb_first)
- | hb_map (hb_second)
- ;
-
- if (!it) return;
- + it
- | hb_map (hb_add (this))
- | hb_apply ([&] (const PairSet& _) { _.collect_variation_indices (c, valueFormat); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- unsigned int count = pairSet.len;
- for (unsigned int i = 0; i < count; i++)
- (this+pairSet[i]).collect_glyphs (c, valueFormat);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
- {
- buffer->unsafe_to_concat (buffer->idx, unsafe_to);
- return_trace (false);
- }
-
- return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
- out->valueFormat[0] = valueFormat[0];
- out->valueFormat[1] = valueFormat[1];
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- {
- hb_pair_t<unsigned, unsigned> newFormats = compute_effective_value_formats (glyphset);
- out->valueFormat[0] = newFormats.first;
- out->valueFormat[1] = newFormats.second;
- }
-
- if (c->plan->all_axes_pinned)
- {
- out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags ();
- out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags ();
- }
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
-
- + hb_zip (this+coverage, pairSet)
- | hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _)
- {
- auto snap = c->serializer->snapshot ();
- auto *o = out->pairSet.serialize_append (c->serializer);
- if (unlikely (!o)) return false;
- bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
- if (!ret)
- {
- out->pairSet.pop ();
- c->serializer->revert (snap);
- }
- return ret;
- },
- hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
-
- return_trace (bool (new_coverage));
- }
-
-
- hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
- {
- unsigned record_size = PairSet::get_size (valueFormat);
-
- unsigned format1 = 0;
- unsigned format2 = 0;
- for (const auto & _ :
- + hb_zip (this+coverage, pairSet)
- | hb_filter (glyphset, hb_first)
- | hb_map (hb_second)
- )
- {
- const PairSet& set = (this + _);
- const PairValueRecord *record = &set.firstPairValueRecord;
-
- unsigned count = set.len;
- for (unsigned i = 0; i < count; i++)
- {
- if (record->intersects (glyphset))
- {
- format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ());
- format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]));
- }
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
-
- if (format1 == valueFormat[0] && format2 == valueFormat[1])
- break;
- }
-
- return hb_pair (format1, format2);
- }
-};
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
deleted file mode 100644
index de15a29e3cf..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
-#define OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
-
-#include "ValueFormat.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-template <typename Types>
-struct PairPosFormat2_4
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat1; /* ValueRecord definition--for the
- * first glyph of the pair--may be zero
- * (0) */
- ValueFormat valueFormat2; /* ValueRecord definition--for the
- * second glyph of the pair--may be
- * zero (0) */
- typename Types::template OffsetTo<ClassDef>
- classDef1; /* Offset to ClassDef table--from
- * beginning of PairPos subtable--for
- * the first glyph of the pair */
- typename Types::template OffsetTo<ClassDef>
- classDef2; /* Offset to ClassDef table--from
- * beginning of PairPos subtable--for
- * the second glyph of the pair */
- HBUINT16 class1Count; /* Number of classes in ClassDef1
- * table--includes Class0 */
- HBUINT16 class2Count; /* Number of classes in ClassDef2
- * table--includes Class0 */
- ValueRecord values; /* Matrix of value pairs:
- * class1-major, class2-minor,
- * Each entry has value1 and value2 */
- public:
- DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && coverage.sanitize (c, this)
- && classDef1.sanitize (c, this)
- && classDef2.sanitize (c, this))) return_trace (false);
-
- unsigned int len1 = valueFormat1.get_len ();
- unsigned int len2 = valueFormat2.get_len ();
- unsigned int stride = HBUINT16::static_size * (len1 + len2);
- unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
- unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
- return_trace (c->check_range ((const void *) values,
- count,
- record_size) &&
- valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
- valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return (this+coverage).intersects (glyphs) &&
- (this+classDef2).intersects (glyphs);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!intersects (c->glyph_set)) return;
- if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return;
-
- hb_set_t klass1_glyphs, klass2_glyphs;
- if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return;
- if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return;
-
- hb_set_t class1_set, class2_set;
- for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage))
- {
- if (!klass1_glyphs.has (cp)) class1_set.add (0);
- else
- {
- unsigned klass1 = (this+classDef1).get (cp);
- class1_set.add (klass1);
- }
- }
-
- class2_set.add (0);
- for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs))
- {
- unsigned klass2 = (this+classDef2).get (cp);
- class2_set.add (klass2);
- }
-
- if (class1_set.is_empty ()
- || class2_set.is_empty ()
- || (class2_set.get_population() == 1 && class2_set.has(0)))
- return;
-
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
- const hb_array_t<const Value> values_array = values.as_array ((unsigned)class1Count * (unsigned) class2Count * (len1 + len2));
- for (const unsigned class1_idx : class1_set.iter ())
- {
- for (const unsigned class2_idx : class2_set.iter ())
- {
- unsigned start_offset = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
- if (valueFormat1.has_device ())
- valueFormat1.collect_variation_indices (c, this, values_array.sub_array (start_offset, len1));
-
- if (valueFormat2.has_device ())
- valueFormat2.collect_variation_indices (c, this, values_array.sub_array (start_offset+len1, len2));
- }
- }
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- if (unlikely (!(this+classDef2).collect_coverage (c->input))) return;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
- unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
- {
- buffer->unsafe_to_concat (buffer->idx, unsafe_to);
- return_trace (false);
- }
-
- unsigned int len1 = valueFormat1.get_len ();
- unsigned int len2 = valueFormat2.get_len ();
- unsigned int record_len = len1 + len2;
-
- unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
- unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
- if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
- {
- buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
- return_trace (false);
- }
-
- const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-
- bool applied_first = false, applied_second = false;
-
-
- /* Isolate simple kerning and apply it half to each side.
- * Results in better cursor positinoing / underline drawing.
- *
- * Disabled, because causes issues... :-(
- * https://github.com/harfbuzz/harfbuzz/issues/3408
- * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
- */
-#ifndef HB_SPLIT_KERN
- if (0)
-#endif
- {
- if (!len2)
- {
- const hb_direction_t dir = buffer->props.direction;
- const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
- const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
- unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
- if (backward)
- mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
- /* Add Devices. */
- mask |= mask << 4;
-
- if (valueFormat1 & ~mask)
- goto bail;
-
- /* Is simple kern. Apply value on an empty position slot,
- * then split it between sides. */
-
- hb_glyph_position_t pos{};
- if (valueFormat1.apply_value (c, this, v, pos))
- {
- hb_position_t *src = &pos.x_advance;
- hb_position_t *dst1 = &buffer->cur_pos().x_advance;
- hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
- unsigned i = horizontal ? 0 : 1;
-
- hb_position_t kern = src[i];
- hb_position_t kern1 = kern >> 1;
- hb_position_t kern2 = kern - kern1;
-
- if (!backward)
- {
- dst1[i] += kern1;
- dst2[i] += kern2;
- dst2[i + 2] += kern2;
- }
- else
- {
- dst1[i] += kern1;
- dst1[i + 2] += src[i + 2] - kern2;
- dst2[i] += kern2;
- }
-
- applied_first = applied_second = kern != 0;
- goto success;
- }
- goto boring;
- }
- }
- bail:
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "try kerning glyphs at %u,%u",
- c->buffer->idx, skippy_iter.idx);
- }
-
- applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
- applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
-
- if (applied_first || applied_second)
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "kerned glyphs at %u,%u",
- c->buffer->idx, skippy_iter.idx);
- }
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "tried kerning glyphs at %u,%u",
- c->buffer->idx, skippy_iter.idx);
- }
-
- success:
- if (applied_first || applied_second)
- buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
- else
- boring:
- buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
-
- if (len2)
- {
- skippy_iter.idx++;
- // https://github.com/harfbuzz/harfbuzz/issues/3824
- // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
- buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
- }
-
- buffer->idx = skippy_iter.idx;
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_map_t klass1_map;
- out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage));
- out->class1Count = klass1_map.get_population ();
-
- hb_map_t klass2_map;
- out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false);
- out->class2Count = klass2_map.get_population ();
-
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
-
- hb_pair_t<unsigned, unsigned> newFormats = hb_pair (valueFormat1, valueFormat2);
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- newFormats = compute_effective_value_formats (klass1_map, klass2_map);
-
- out->valueFormat1 = newFormats.first;
- out->valueFormat2 = newFormats.second;
-
- if (c->plan->all_axes_pinned)
- {
- out->valueFormat1 = out->valueFormat1.drop_device_table_flags ();
- out->valueFormat2 = out->valueFormat2.drop_device_table_flags ();
- }
-
- for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
- {
- for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
- {
- unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
- valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map);
- valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map);
- }
- }
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- out->coverage.serialize_serialize (c->serializer, it);
- return_trace (out->class1Count && out->class2Count && bool (it));
- }
-
-
- hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_map_t& klass1_map,
- const hb_map_t& klass2_map) const
- {
- unsigned len1 = valueFormat1.get_len ();
- unsigned len2 = valueFormat2.get_len ();
- unsigned record_size = len1 + len2;
-
- unsigned format1 = 0;
- unsigned format2 = 0;
-
- for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
- {
- for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
- {
- unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size;
- format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
- format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
- }
-
- if (format1 == valueFormat1 && format2 == valueFormat2)
- break;
- }
-
- return hb_pair (format1, format2);
- }
-};
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh
deleted file mode 100644
index 147b8e00ea6..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh
+++ /dev/null
@@ -1,207 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_PAIRSET_HH
-#define OT_LAYOUT_GPOS_PAIRSET_HH
-
-#include "PairValueRecord.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-
-template <typename Types>
-struct PairSet
-{
- template <typename Types2>
- friend struct PairPosFormat1_3;
-
- using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
-
- protected:
- HBUINT16 len; /* Number of PairValueRecords */
- PairValueRecord firstPairValueRecord;
- /* Array of PairValueRecords--ordered
- * by GlyphID of the second glyph */
- public:
- DEFINE_SIZE_MIN (2);
-
- static unsigned get_size (unsigned len1, unsigned len2)
- {
- return Types::HBGlyphID::static_size + Value::static_size * (len1 + len2);
- }
- static unsigned get_size (const ValueFormat valueFormats[2])
- {
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- return get_size (len1, len2);
- }
-
- struct sanitize_closure_t
- {
- const ValueFormat *valueFormats;
- unsigned int len1; /* valueFormats[0].get_len() */
- unsigned int stride; /* bytes */
- };
-
- bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && c->check_range (&firstPairValueRecord,
- len,
- closure->stride))) return_trace (false);
-
- unsigned int count = len;
- const PairValueRecord *record = &firstPairValueRecord;
- return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
- closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
- }
-
- bool intersects (const hb_set_t *glyphs,
- const ValueFormat *valueFormats) const
- {
- unsigned record_size = get_size (valueFormats);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (glyphs->has (record->secondGlyph))
- return true;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- return false;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned record_size = get_size (valueFormats);
-
- const PairValueRecord *record = &firstPairValueRecord;
- c->input->add_array (&record->secondGlyph, len, record_size);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned record_size = get_size (valueFormats);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len;
- for (unsigned i = 0; i < count; i++)
- {
- if (c->glyph_set->has (record->secondGlyph))
- { record->collect_variation_indices (c, valueFormats, this); }
-
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ValueFormat *valueFormats,
- unsigned int pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned record_size = get_size (len1, len2);
-
- const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
- &firstPairValueRecord,
- len,
- record_size);
- if (record)
- {
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "try kerning glyphs at %u,%u",
- c->buffer->idx, pos);
- }
-
- bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
- bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
-
- if (applied_first || applied_second)
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "kerned glyphs at %u,%u",
- c->buffer->idx, pos);
- }
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "tried kerning glyphs at %u,%u",
- c->buffer->idx, pos);
- }
-
- if (applied_first || applied_second)
- buffer->unsafe_to_break (buffer->idx, pos + 1);
-
- if (len2)
- {
- pos++;
- // https://github.com/harfbuzz/harfbuzz/issues/3824
- // https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
- buffer->unsafe_to_break (buffer->idx, pos + 1);
- }
-
- buffer->idx = pos;
- return_trace (true);
- }
- buffer->unsafe_to_concat (buffer->idx, pos + 1);
- return_trace (false);
- }
-
- bool subset (hb_subset_context_t *c,
- const ValueFormat valueFormats[2],
- const ValueFormat newFormats[2]) const
- {
- TRACE_SUBSET (this);
- auto snap = c->serializer->snapshot ();
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->len = 0;
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = get_size (len1, len2);
-
- typename PairValueRecord::context_t context =
- {
- this,
- valueFormats,
- newFormats,
- len1,
- &glyph_map,
- &c->plan->layout_variation_idx_delta_map
- };
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len, num = 0;
- for (unsigned i = 0; i < count; i++)
- {
- if (glyphset.has (record->secondGlyph)
- && record->subset (c, &context)) num++;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
-
- out->len = num;
- if (!num) c->serializer->revert (snap);
- return_trace (num);
- }
-};
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_PAIRSET_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh
deleted file mode 100644
index 3222477764a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairValueRecord.hh
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
-#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
-
-#include "ValueFormat.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-
-template <typename Types>
-struct PairValueRecord
-{
- template <typename Types2>
- friend struct PairSet;
-
- protected:
- typename Types::HBGlyphID
- secondGlyph; /* GlyphID of second glyph in the
- * pair--first glyph is listed in the
- * Coverage table */
- ValueRecord values; /* Positioning data for the first glyph
- * followed by for second glyph */
- public:
- DEFINE_SIZE_ARRAY (Types::size, values);
-
- int cmp (hb_codepoint_t k) const
- { return secondGlyph.cmp (k); }
-
- struct context_t
- {
- const void *base;
- const ValueFormat *valueFormats;
- const ValueFormat *newFormats;
- unsigned len1; /* valueFormats[0].get_len() */
- const hb_map_t *glyph_map;
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map;
- };
-
- bool subset (hb_subset_context_t *c,
- context_t *closure) const
- {
- TRACE_SERIALIZE (this);
- auto *s = c->serializer;
- auto *out = s->start_embed (*this);
- if (unlikely (!s->extend_min (out))) return_trace (false);
-
- out->secondGlyph = (*closure->glyph_map)[secondGlyph];
-
- closure->valueFormats[0].copy_values (s,
- closure->newFormats[0],
- closure->base, &values[0],
- closure->layout_variation_idx_delta_map);
- closure->valueFormats[1].copy_values (s,
- closure->newFormats[1],
- closure->base,
- &values[closure->len1],
- closure->layout_variation_idx_delta_map);
-
- return_trace (true);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats,
- const void *base) const
- {
- unsigned record1_len = valueFormats[0].get_len ();
- unsigned record2_len = valueFormats[1].get_len ();
- const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
-
- if (valueFormats[0].has_device ())
- valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
-
- if (valueFormats[1].has_device ())
- valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
- }
-
- bool intersects (const hb_set_t& glyphset) const
- {
- return glyphset.has(secondGlyph);
- }
-
- const Value* get_values_1 () const
- {
- return &values[0];
- }
-
- const Value* get_values_2 (ValueFormat format1) const
- {
- return &values[format1.get_len ()];
- }
-};
-
-
-}
-}
-}
-
-#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookup.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookup.hh
deleted file mode 100644
index c4e57bb5430..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookup.hh
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_POSLOOKUP_HH
-#define OT_LAYOUT_GPOS_POSLOOKUP_HH
-
-#include "PosLookupSubTable.hh"
-#include "../../../hb-ot-layout-common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct PosLookup : Lookup
-{
- using SubTable = PosLookupSubTable;
-
- const SubTable& get_subtable (unsigned int i) const
- { return Lookup::get_subtable<SubTable> (i); }
-
- bool is_reverse () const
- {
- return false;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- return_trace (dispatch (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c);
- }
-
- hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
- { return dispatch (c); }
-
- hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
- {
- if (c->is_lookup_visited (this_index))
- return hb_closure_lookups_context_t::default_return_value ();
-
- c->set_lookup_visited (this_index);
- if (!intersects (c->glyphs))
- {
- c->set_lookup_inactive (this_index);
- return hb_closure_lookups_context_t::default_return_value ();
- }
-
- hb_closure_lookups_context_t::return_t ret = dispatch (c);
- return ret;
- }
-
- template <typename set_t>
- void collect_coverage (set_t *glyphs) const
- {
- hb_collect_coverage_context_t<set_t> c (glyphs);
- dispatch (&c);
- }
-
- template <typename context_t>
- static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
-
- bool subset (hb_subset_context_t *c) const
- { return Lookup::subset<SubTable> (c); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- { return Lookup::sanitize<SubTable> (c); }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_POSLOOKUP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookupSubTable.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookupSubTable.hh
deleted file mode 100644
index c19fbc323ff..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PosLookupSubTable.hh
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
-#define OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
-
-#include "SinglePos.hh"
-#include "PairPos.hh"
-#include "CursivePos.hh"
-#include "MarkBasePos.hh"
-#include "MarkLigPos.hh"
-#include "MarkMarkPos.hh"
-#include "ContextPos.hh"
-#include "ChainContextPos.hh"
-#include "ExtensionPos.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct PosLookupSubTable
-{
- friend struct ::OT::Lookup;
- friend struct PosLookup;
-
- enum Type {
- Single = 1,
- Pair = 2,
- Cursive = 3,
- MarkBase = 4,
- MarkLig = 5,
- MarkMark = 6,
- Context = 7,
- ChainContext = 8,
- Extension = 9
- };
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, lookup_type);
- switch (lookup_type) {
- case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
- case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
- case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
- case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
- case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
- case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
- case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
- case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
- case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c, lookup_type);
- }
-
- protected:
- union {
- SinglePos single;
- PairPos pair;
- CursivePos cursive;
- MarkBasePos markBase;
- MarkLigPos markLig;
- MarkMarkPos markMark;
- ContextPos context;
- ChainContextPos chainContext;
- ExtensionPos extension;
- } u;
- public:
- DEFINE_SIZE_MIN (0);
-};
-
-}
-}
-}
-
-#endif /* HB_OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh
deleted file mode 100644
index 3af6c499659..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePos.hh
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_SINGLEPOS_HH
-#define OT_LAYOUT_GPOS_SINGLEPOS_HH
-
-#include "SinglePosFormat1.hh"
-#include "SinglePosFormat2.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct SinglePos
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- SinglePosFormat1 format1;
- SinglePosFormat2 format2;
- } u;
-
- public:
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- unsigned get_format (Iterator glyph_val_iter_pairs)
- {
- hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
-
- for (const auto iter : glyph_val_iter_pairs)
- for (const auto _ : hb_zip (iter.second, first_val_iter))
- if (_.first != _.second)
- return 2;
-
- return 1;
- }
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup* src,
- Iterator glyph_val_iter_pairs,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
- bool all_axes_pinned)
- {
- if (unlikely (!c->extend_min (u.format))) return;
- unsigned format = 2;
- ValueFormat new_format = src->get_value_format ();
-
- if (all_axes_pinned)
- new_format = new_format.drop_device_table_flags ();
-
- if (glyph_val_iter_pairs)
- format = get_format (glyph_val_iter_pairs);
-
- u.format = format;
- switch (u.format) {
- case 1: u.format1.serialize (c,
- src,
- glyph_val_iter_pairs,
- new_format,
- layout_variation_idx_delta_map);
- return;
- case 2: u.format2.serialize (c,
- src,
- glyph_val_iter_pairs,
- new_format,
- layout_variation_idx_delta_map);
- return;
- default:return;
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-
-template<typename Iterator, typename SrcLookup>
-static void
-SinglePos_serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
- bool all_axes_pinned)
-{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); }
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_SINGLEPOS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh
deleted file mode 100644
index 623e4e66b20..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat1.hh
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
-#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
-
-#include "Common.hh"
-#include "ValueFormat.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct SinglePosFormat1
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat; /* Defines the types of data in the
- * ValueRecord */
- ValueRecord values; /* Defines positioning
- * value(s)--applied to all glyphs in
- * the Coverage table */
- public:
- DEFINE_SIZE_ARRAY (6, values);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- coverage.sanitize (c, this) &&
- /* The coverage table may use a range to represent a set
- * of glyphs, which means a small number of bytes can
- * generate a large glyph set. Manually modify the
- * sanitizer max ops to take this into account.
- *
- * Note: This check *must* be right after coverage sanitize. */
- c->check_ops ((this + coverage).get_population () >> 1) &&
- valueFormat.sanitize_value (c, this, values));
-
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!valueFormat.has_device ()) return;
-
- hb_set_t intersection;
- (this+coverage).intersect_set (*c->glyph_set, intersection);
- if (!intersection) return;
-
- valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ()));
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- ValueFormat get_value_format () const { return valueFormat; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "positioning glyph at %u",
- c->buffer->idx);
- }
-
- valueFormat.apply_value (c, this, values, buffer->cur_pos());
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "positioned glyph at %u",
- c->buffer->idx);
- }
-
- buffer->idx++;
- return_trace (true);
- }
-
- bool
- position_single (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t gid,
- hb_glyph_position_t &pos) const
- {
- unsigned int index = (this+coverage).get_coverage (gid);
- if (likely (index == NOT_COVERED)) return false;
-
- /* This is ugly... */
- hb_buffer_t buffer;
- buffer.props.direction = direction;
- OT::hb_ot_apply_context_t c (1, font, &buffer);
-
- valueFormat.apply_value (&c, this, values, pos);
- return true;
- }
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- ValueFormat newFormat,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map)
- {
- if (unlikely (!c->extend_min (this))) return;
- if (unlikely (!c->check_assign (valueFormat,
- newFormat,
- HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
-
- for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
- {
- src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map);
- // Only serialize the first entry in the iterator, the rest are assumed to
- // be the same.
- break;
- }
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- hb_set_t intersection;
- (this+coverage).intersect_set (glyphset, intersection);
-
- auto it =
- + hb_iter (intersection)
- | hb_map_retains_sorting (glyph_map)
- | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
- ;
-
- bool ret = bool (it);
- SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
- return_trace (ret);
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh
deleted file mode 100644
index e8f2d7c2c6e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/SinglePosFormat2.hh
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
-#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-struct SinglePosFormat2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of subtable */
- ValueFormat valueFormat; /* Defines the types of data in the
- * ValueRecord */
- HBUINT16 valueCount; /* Number of ValueRecords */
- ValueRecord values; /* Array of ValueRecords--positioning
- * values applied to glyphs */
- public:
- DEFINE_SIZE_ARRAY (8, values);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- coverage.sanitize (c, this) &&
- valueFormat.sanitize_values (c, this, values, valueCount));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- if (!valueFormat.has_device ()) return;
-
- auto it =
- + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
- | hb_filter (c->glyph_set, hb_first)
- ;
-
- if (!it) return;
-
- unsigned sub_length = valueFormat.get_len ();
- const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length);
-
- for (unsigned i : + it
- | hb_map (hb_second))
- valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length));
-
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- ValueFormat get_value_format () const { return valueFormat; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- if (unlikely (index >= valueCount)) return_trace (false);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "positioning glyph at %u",
- c->buffer->idx);
- }
-
- valueFormat.apply_value (c, this,
- &values[index * valueFormat.get_len ()],
- buffer->cur_pos());
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "positioned glyph at %u",
- c->buffer->idx);
- }
-
- buffer->idx++;
- return_trace (true);
- }
-
- bool
- position_single (hb_font_t *font,
- hb_direction_t direction,
- hb_codepoint_t gid,
- hb_glyph_position_t &pos) const
- {
- unsigned int index = (this+coverage).get_coverage (gid);
- if (likely (index == NOT_COVERED)) return false;
- if (unlikely (index >= valueCount)) return false;
-
- /* This is ugly... */
- hb_buffer_t buffer;
- buffer.props.direction = direction;
- OT::hb_ot_apply_context_t c (1, font, &buffer);
-
- valueFormat.apply_value (&c, this,
- &values[index * valueFormat.get_len ()],
- pos);
- return true;
- }
-
-
- template<typename Iterator,
- typename SrcLookup,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- const SrcLookup *src,
- Iterator it,
- ValueFormat newFormat,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map)
- {
- auto out = c->extend_min (this);
- if (unlikely (!out)) return;
- if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
- if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
-
- + it
- | hb_map (hb_second)
- | hb_apply ([&] (hb_array_t<const Value> _)
- { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); })
- ;
-
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
-
- coverage.serialize_serialize (c, glyphs);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned sub_length = valueFormat.get_len ();
- auto values_array = values.as_array (valueCount * sub_length);
-
- auto it =
- + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
- | hb_filter (glyphset, hb_first)
- | hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
- {
- return hb_pair (glyph_map[_.first],
- values_array.sub_array (_.second * sub_length,
- sub_length));
- })
- ;
-
- bool ret = bool (it);
- SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
- return_trace (ret);
- }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh
deleted file mode 100644
index 1aa451abcc8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/ValueFormat.hh
+++ /dev/null
@@ -1,394 +0,0 @@
-#ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
-#define OT_LAYOUT_GPOS_VALUEFORMAT_HH
-
-#include "../../../hb-ot-layout-gsubgpos.hh"
-
-namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-
-typedef HBUINT16 Value;
-
-typedef UnsizedArrayOf<Value> ValueRecord;
-
-struct ValueFormat : HBUINT16
-{
- enum Flags {
- xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
- yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
- xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
- yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
- xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
- yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
- xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
- yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
- ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
- reserved = 0xF000u, /* For future use */
-
- devices = 0x00F0u /* Mask for having any Device table */
- };
-
-/* All fields are options. Only those available advance the value pointer. */
-#if 0
- HBINT16 xPlacement; /* Horizontal adjustment for
- * placement--in design units */
- HBINT16 yPlacement; /* Vertical adjustment for
- * placement--in design units */
- HBINT16 xAdvance; /* Horizontal adjustment for
- * advance--in design units (only used
- * for horizontal writing) */
- HBINT16 yAdvance; /* Vertical adjustment for advance--in
- * design units (only used for vertical
- * writing) */
- Offset16To<Device> xPlaDevice; /* Offset to Device table for
- * horizontal placement--measured from
- * beginning of PosTable (may be NULL) */
- Offset16To<Device> yPlaDevice; /* Offset to Device table for vertical
- * placement--measured from beginning
- * of PosTable (may be NULL) */
- Offset16To<Device> xAdvDevice; /* Offset to Device table for
- * horizontal advance--measured from
- * beginning of PosTable (may be NULL) */
- Offset16To<Device> yAdvDevice; /* Offset to Device table for vertical
- * advance--measured from beginning of
- * PosTable (may be NULL) */
-#endif
-
- IntType& operator = (uint16_t i) { v = i; return *this; }
-
- unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
- unsigned int get_size () const { return get_len () * Value::static_size; }
-
- hb_vector_t<unsigned> get_device_table_indices () const {
- unsigned i = 0;
- hb_vector_t<unsigned> result;
- unsigned format = *this;
-
- if (format & xPlacement) i++;
- if (format & yPlacement) i++;
- if (format & xAdvance) i++;
- if (format & yAdvance) i++;
-
- if (format & xPlaDevice) result.push (i++);
- if (format & yPlaDevice) result.push (i++);
- if (format & xAdvDevice) result.push (i++);
- if (format & yAdvDevice) result.push (i++);
-
- return result;
- }
-
- bool apply_value (hb_ot_apply_context_t *c,
- const void *base,
- const Value *values,
- hb_glyph_position_t &glyph_pos) const
- {
- bool ret = false;
- unsigned int format = *this;
- if (!format) return ret;
-
- hb_font_t *font = c->font;
- bool horizontal =
-#ifndef HB_NO_VERTICAL
- HB_DIRECTION_IS_HORIZONTAL (c->direction)
-#else
- true
-#endif
- ;
-
- if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
- if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
- if (format & xAdvance) {
- if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
- values++;
- }
- /* y_advance values grow downward but font-space grows upward, hence negation */
- if (format & yAdvance) {
- if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
- values++;
- }
-
- if (!has_device ()) return ret;
-
- bool use_x_device = font->x_ppem || font->num_coords;
- bool use_y_device = font->y_ppem || font->num_coords;
-
- if (!use_x_device && !use_y_device) return ret;
-
- const VariationStore &store = c->var_store;
- auto *cache = c->var_store_cache;
-
- /* pixel -> fractional pixel */
- if (format & xPlaDevice) {
- if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
- values++;
- }
- if (format & yPlaDevice) {
- if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store, cache);
- values++;
- }
- if (format & xAdvDevice) {
- if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
- values++;
- }
- if (format & yAdvDevice) {
- /* y_advance values grow downward but font-space grows upward, hence negation */
- if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache);
- values++;
- }
- return ret;
- }
-
- unsigned int get_effective_format (const Value *values) const
- {
- unsigned int format = *this;
- for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) {
- if (format & flag) should_drop (*values++, (Flags) flag, &format);
- }
-
- return format;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- unsigned int get_effective_format (Iterator it) const {
- unsigned int new_format = 0;
-
- for (const hb_array_t<const Value>& values : it)
- new_format = new_format | get_effective_format (&values);
-
- return new_format;
- }
-
- void copy_values (hb_serialize_context_t *c,
- unsigned int new_format,
- const void *base,
- const Value *values,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
- {
- unsigned int format = *this;
- if (!format) return;
-
- HBINT16 *x_placement = nullptr, *y_placement = nullptr, *x_adv = nullptr, *y_adv = nullptr;
- if (format & xPlacement) x_placement = copy_value (c, new_format, xPlacement, *values++);
- if (format & yPlacement) y_placement = copy_value (c, new_format, yPlacement, *values++);
- if (format & xAdvance) x_adv = copy_value (c, new_format, xAdvance, *values++);
- if (format & yAdvance) y_adv = copy_value (c, new_format, yAdvance, *values++);
-
- if (format & xPlaDevice)
- {
- add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map);
- copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xPlaDevice);
- }
-
- if (format & yPlaDevice)
- {
- add_delta_to_value (y_placement, base, values, layout_variation_idx_delta_map);
- copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yPlaDevice);
- }
-
- if (format & xAdvDevice)
- {
- add_delta_to_value (x_adv, base, values, layout_variation_idx_delta_map);
- copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xAdvDevice);
- }
-
- if (format & yAdvDevice)
- {
- add_delta_to_value (y_adv, base, values, layout_variation_idx_delta_map);
- copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yAdvDevice);
- }
- }
-
- HBINT16* copy_value (hb_serialize_context_t *c,
- unsigned int new_format,
- Flags flag,
- Value value) const
- {
- // Filter by new format.
- if (!(new_format & flag)) return nullptr;
- return reinterpret_cast<HBINT16 *> (c->copy (value));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const void *base,
- const hb_array_t<const Value>& values) const
- {
- unsigned format = *this;
- unsigned i = 0;
- if (format & xPlacement) i++;
- if (format & yPlacement) i++;
- if (format & xAdvance) i++;
- if (format & yAdvance) i++;
- if (format & xPlaDevice)
- {
- (base + get_device (&(values[i]))).collect_variation_indices (c);
- i++;
- }
-
- if (format & ValueFormat::yPlaDevice)
- {
- (base + get_device (&(values[i]))).collect_variation_indices (c);
- i++;
- }
-
- if (format & ValueFormat::xAdvDevice)
- {
-
- (base + get_device (&(values[i]))).collect_variation_indices (c);
- i++;
- }
-
- if (format & ValueFormat::yAdvDevice)
- {
-
- (base + get_device (&(values[i]))).collect_variation_indices (c);
- i++;
- }
- }
-
- unsigned drop_device_table_flags () const
- {
- unsigned format = *this;
- for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1)
- format = format & ~flag;
-
- return format;
- }
-
- private:
- bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
- {
- unsigned int format = *this;
-
- if (format & xPlacement) values++;
- if (format & yPlacement) values++;
- if (format & xAdvance) values++;
- if (format & yAdvance) values++;
-
- if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
- if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
-
- return true;
- }
-
- static inline Offset16To<Device>& get_device (Value* value)
- {
- return *static_cast<Offset16To<Device> *> (value);
- }
- static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr)
- {
- if (worked) *worked |= bool (*value);
- return *static_cast<const Offset16To<Device> *> (value);
- }
-
- void add_delta_to_value (HBINT16 *value,
- const void *base,
- const Value *src_value,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
- {
- if (!value) return;
- unsigned varidx = (base + get_device (src_value)).get_variation_index ();
- hb_pair_t<unsigned, int> *varidx_delta;
- if (!layout_variation_idx_delta_map->has (varidx, &varidx_delta)) return;
-
- *value += hb_second (*varidx_delta);
- }
-
- bool copy_device (hb_serialize_context_t *c, const void *base,
- const Value *src_value,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
- unsigned int new_format, Flags flag) const
- {
- // Filter by new format.
- if (!(new_format & flag)) return true;
-
- Value *dst_value = c->copy (*src_value);
-
- if (!dst_value) return false;
- if (*dst_value == 0) return true;
-
- *dst_value = 0;
- c->push ();
- if ((base + get_device (src_value)).copy (c, layout_variation_idx_delta_map))
- {
- c->add_link (*dst_value, c->pop_pack ());
- return true;
- }
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
- {
- if (worked) *worked |= bool (*value);
- return *reinterpret_cast<const HBINT16 *> (value);
- }
-
- public:
-
- bool has_device () const
- {
- unsigned int format = *this;
- return (format & devices) != 0;
- }
-
- bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
- }
-
- bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
- {
- TRACE_SANITIZE (this);
- unsigned int len = get_len ();
-
- if (!c->check_range (values, count, get_size ())) return_trace (false);
-
- if (!has_device ()) return_trace (true);
-
- for (unsigned int i = 0; i < count; i++) {
- if (!sanitize_value_devices (c, base, values))
- return_trace (false);
- values += len;
- }
-
- return_trace (true);
- }
-
- /* Just sanitize referenced Device tables. Doesn't check the values themselves. */
- bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
- {
- TRACE_SANITIZE (this);
-
- if (!has_device ()) return_trace (true);
-
- for (unsigned int i = 0; i < count; i++) {
- if (!sanitize_value_devices (c, base, values))
- return_trace (false);
- values = &StructAtOffset<const Value> (values, stride);
- }
-
- return_trace (true);
- }
-
- private:
-
- void should_drop (Value value, Flags flag, unsigned int* format) const
- {
- if (value) return;
- *format = *format & ~flag;
- }
-
-};
-
-}
-}
-}
-
-#endif // #ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSet.hh
deleted file mode 100644
index b4466119be0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSet.hh
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_ALTERNATESET_HH
-#define OT_LAYOUT_GSUB_ALTERNATESET_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct AlternateSet
-{
- protected:
- Array16Of<typename Types::HBGlyphID>
- alternates; /* Array of alternate GlyphIDs--in
- * arbitrary order */
- public:
- DEFINE_SIZE_ARRAY (2, alternates);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (alternates.sanitize (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return hb_any (alternates, glyphs); }
-
- void closure (hb_closure_context_t *c) const
- { c->output->add_array (alternates.arrayZ, alternates.len); }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { c->output->add_array (alternates.arrayZ, alternates.len); }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int count = alternates.len;
-
- if (unlikely (!count)) return_trace (false);
-
- hb_mask_t glyph_mask = c->buffer->cur().mask;
- hb_mask_t lookup_mask = c->lookup_mask;
-
- /* Note: This breaks badly if two features enabled this lookup together. */
- unsigned int shift = hb_ctz (lookup_mask);
- unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
-
- /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
- if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
- {
- /* Maybe we can do better than unsafe-to-break all; but since we are
- * changing random state, it would be hard to track that. Good 'nough. */
- c->buffer->unsafe_to_break (0, c->buffer->len);
- alt_index = c->random_number () % count + 1;
- }
-
- if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "replacing glyph at %u (alternate substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph (alternates[alt_index - 1]);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (alternate substitution)",
- c->buffer->idx - 1u);
- }
-
- return_trace (true);
- }
-
- unsigned
- get_alternates (unsigned start_offset,
- unsigned *alternate_count /* IN/OUT. May be NULL. */,
- hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
- {
- if (alternates.len && alternate_count)
- {
- + alternates.as_array ().sub_array (start_offset, alternate_count)
- | hb_sink (hb_array (alternate_glyphs, *alternate_count))
- ;
- }
- return alternates.len;
- }
-
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator alts)
- {
- TRACE_SERIALIZE (this);
- return_trace (alternates.serialize (c, alts));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_iter (alternates)
- | hb_filter (glyphset)
- | hb_map (glyph_map)
- ;
-
- auto *out = c->serializer->start_embed (*this);
- return_trace (out->serialize (c->serializer, it) &&
- out->alternates);
- }
-};
-
-}
-}
-}
-
-
-#endif /* OT_LAYOUT_GSUB_ALTERNATESET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubst.hh
deleted file mode 100644
index 04a052a7836..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubst.hh
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_ALTERNATESUBST_HH
-#define OT_LAYOUT_GSUB_ALTERNATESUBST_HH
-
-#include "AlternateSubstFormat1.hh"
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct AlternateSubst
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- AlternateSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- AlternateSubstFormat1_2<MediumTypes> format2;
-#endif
- } u;
- public:
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
- * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
- bool serialize (hb_serialize_context_t *c,
- hb_sorted_array_t<const HBGlyphID16> glyphs,
- hb_array_t<const unsigned int> alternate_len_list,
- hb_array_t<const HBGlyphID16> alternate_glyphs_list)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (u.format))) return_trace (false);
- unsigned int format = 1;
- u.format = format;
- switch (u.format) {
- case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
- default:return_trace (false);
- }
- }
-
- /* TODO subset() should choose format. */
-
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_ALTERNATESUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
deleted file mode 100644
index adec65d5864..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
+++ /dev/null
@@ -1,128 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
-#define OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
-
-#include "AlternateSet.hh"
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct AlternateSubstFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>>
- alternateSet; /* Array of AlternateSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- bool may_have_non_1to1 () const
- { return false; }
-
- void closure (hb_closure_context_t *c) const
- {
- + hb_zip (this+coverage, alternateSet)
- | hb_filter (c->parent_active_glyphs (), hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); })
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- + hb_zip (this+coverage, alternateSet)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); })
- ;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
- unsigned
- get_glyph_alternates (hb_codepoint_t gid,
- unsigned start_offset,
- unsigned *alternate_count /* IN/OUT. May be NULL. */,
- hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
- { return (this+alternateSet[(this+coverage).get_coverage (gid)])
- .get_alternates (start_offset, alternate_count, alternate_glyphs); }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- return_trace ((this+alternateSet[index]).apply (c));
- }
-
- bool serialize (hb_serialize_context_t *c,
- hb_sorted_array_t<const HBGlyphID16> glyphs,
- hb_array_t<const unsigned int> alternate_len_list,
- hb_array_t<const HBGlyphID16> alternate_glyphs_list)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- if (unlikely (!alternateSet.serialize (c, glyphs.length))) return_trace (false);
- for (unsigned int i = 0; i < glyphs.length; i++)
- {
- unsigned int alternate_len = alternate_len_list[i];
- if (unlikely (!alternateSet[i]
- .serialize_serialize (c, alternate_glyphs_list.sub_array (0, alternate_len))))
- return_trace (false);
- alternate_glyphs_list += alternate_len;
- }
- return_trace (coverage.serialize_serialize (c, glyphs));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, alternateSet)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->alternateSet, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ChainContextSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ChainContextSubst.hh
deleted file mode 100644
index 08fd779f730..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ChainContextSubst.hh
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH
-#define OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH
-
-// TODO(garretrieger): move to new layout.
-#include "../../../hb-ot-layout-gsubgpos.hh"
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct ChainContextSubst : ChainContext {};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_CHAINCONTEXTSUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Common.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Common.hh
deleted file mode 100644
index 968bba0481a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Common.hh
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_COMMON_HH
-#define OT_LAYOUT_GSUB_COMMON_HH
-
-#include "../../../hb-serialize.hh"
-#include "../../../hb-ot-layout-gsubgpos.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
-
-template<typename Iterator>
-static void SingleSubst_serialize (hb_serialize_context_t *c,
- Iterator it);
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ContextSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ContextSubst.hh
deleted file mode 100644
index 9f8cb46b5e2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ContextSubst.hh
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_CONTEXTSUBST_HH
-#define OT_LAYOUT_GSUB_CONTEXTSUBST_HH
-
-// TODO(garretrieger): move to new layout.
-#include "../../../hb-ot-layout-gsubgpos.hh"
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct ContextSubst : Context {};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_CONTEXTSUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ExtensionSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ExtensionSubst.hh
deleted file mode 100644
index 831a7dfa2d1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ExtensionSubst.hh
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_EXTENSIONSUBST_HH
-#define OT_LAYOUT_GSUB_EXTENSIONSUBST_HH
-
-// TODO(garretrieger): move to new layout.
-#include "../../../hb-ot-layout-gsubgpos.hh"
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct ExtensionSubst : Extension<ExtensionSubst>
-{
- typedef struct SubstLookupSubTable SubTable;
- bool is_reverse () const;
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_EXTENSIONSUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/GSUB.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/GSUB.hh
deleted file mode 100644
index 900cf603e45..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/GSUB.hh
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_GSUB_HH
-#define OT_LAYOUT_GSUB_GSUB_HH
-
-#include "../../../hb-ot-layout-gsubgpos.hh"
-#include "Common.hh"
-#include "SubstLookup.hh"
-
-namespace OT {
-
-using Layout::GSUB_impl::SubstLookup;
-
-namespace Layout {
-
-/*
- * GSUB -- Glyph Substitution
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gsub
- */
-
-struct GSUB : GSUBGPOS
-{
- using Lookup = SubstLookup;
-
- static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
-
- const SubstLookup& get_lookup (unsigned int i) const
- { return static_cast<const SubstLookup &> (GSUBGPOS::get_lookup (i)); }
-
- bool subset (hb_subset_context_t *c) const
- {
- hb_subset_layout_context_t l (c, tableTag);
- return GSUBGPOS::subset<SubstLookup> (&l);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (GSUBGPOS::sanitize<SubstLookup> (c));
- }
-
- HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
- hb_face_t *face) const;
-
- void closure_lookups (hb_face_t *face,
- const hb_set_t *glyphs,
- hb_set_t *lookup_indexes /* IN/OUT */) const
- { GSUBGPOS::closure_lookups<SubstLookup> (face, glyphs, lookup_indexes); }
-
- typedef GSUBGPOS::accelerator_t<GSUB> accelerator_t;
-};
-
-
-}
-
-struct GSUB_accelerator_t : Layout::GSUB::accelerator_t {
- GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {}
-};
-
-
-}
-
-#endif /* OT_LAYOUT_GSUB_GSUB_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh
deleted file mode 100644
index 38057cb60c9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh
+++ /dev/null
@@ -1,190 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_LIGATURE_HH
-#define OT_LAYOUT_GSUB_LIGATURE_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct Ligature
-{
- protected:
- typename Types::HBGlyphID
- ligGlyph; /* GlyphID of ligature to substitute */
- HeadlessArrayOf<typename Types::HBGlyphID>
- component; /* Array of component GlyphIDs--start
- * with the second component--ordered
- * in writing direction */
- public:
- DEFINE_SIZE_ARRAY (Types::size + 2, component);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return hb_all (component, glyphs); }
-
- bool intersects_lig_glyph (const hb_set_t *glyphs) const
- { return glyphs->has(ligGlyph); }
-
- void closure (hb_closure_context_t *c) const
- {
- if (!intersects (c->glyphs)) return;
- c->output->add (ligGlyph);
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- c->input->add_array (component.arrayZ, component.get_length ());
- c->output->add (ligGlyph);
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- if (c->len != component.lenP1)
- return false;
-
- for (unsigned int i = 1; i < c->len; i++)
- if (likely (c->glyphs[i] != component[i]))
- return false;
-
- return true;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int count = component.lenP1;
-
- if (unlikely (!count)) return_trace (false);
-
- /* Special-case to make it in-place and not consider this
- * as a "ligated" substitution. */
- if (unlikely (count == 1))
- {
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "replacing glyph at %u (ligature substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph (ligGlyph);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (ligature substitution)",
- c->buffer->idx - 1u);
- }
-
- return_trace (true);
- }
-
- unsigned int total_component_count = 0;
-
- unsigned int match_end = 0;
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
-
- if (likely (!match_input (c, count,
- &component[1],
- match_glyph,
- nullptr,
- &match_end,
- match_positions,
- &total_component_count)))
- {
- c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
- return_trace (false);
- }
-
- unsigned pos = 0;
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- unsigned delta = c->buffer->sync_so_far ();
-
- pos = c->buffer->idx;
-
- char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0};
- char *p = buf;
-
- match_end += delta;
- for (unsigned i = 0; i < count; i++)
- {
- match_positions[i] += delta;
- if (i)
- *p++ = ',';
- snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]);
- p += strlen(p);
- }
-
- c->buffer->message (c->font,
- "ligating glyphs at %s",
- buf);
- }
-
- ligate_input (c,
- count,
- match_positions,
- match_end,
- ligGlyph,
- total_component_count);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "ligated glyph at %u",
- pos);
- }
-
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- hb_codepoint_t ligature,
- Iterator components /* Starting from second */)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- ligGlyph = ligature;
- if (unlikely (!component.serialize (c, components))) return_trace (false);
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
- // Ensure Coverage table is always packed after this.
- c->serializer->add_virtual_link (coverage_idx);
-
- auto it =
- + hb_iter (component)
- | hb_map (glyph_map)
- ;
-
- auto *out = c->serializer->start_embed (*this);
- return_trace (out->serialize (c->serializer,
- glyph_map[ligGlyph],
- it)); }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_LIGATURE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
deleted file mode 100644
index 9db25cf567b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_LIGATURESET_HH
-#define OT_LAYOUT_GSUB_LIGATURESET_HH
-
-#include "Common.hh"
-#include "Ligature.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct LigatureSet
-{
- protected:
- Array16OfOffset16To<Ligature<Types>>
- ligature; /* Array LigatureSet tables
- * ordered by preference */
- public:
- DEFINE_SIZE_ARRAY (2, ligature);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (ligature.sanitize (c, this));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return
- + hb_iter (ligature)
- | hb_map (hb_add (this))
- | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
- | hb_any
- ;
- }
-
- bool intersects_lig_glyph (const hb_set_t *glyphs) const
- {
- return
- + hb_iter (ligature)
- | hb_map (hb_add (this))
- | hb_map ([glyphs] (const Ligature<Types> &_) {
- return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs);
- })
- | hb_any
- ;
- }
-
- void closure (hb_closure_context_t *c) const
- {
- + hb_iter (ligature)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- + hb_iter (ligature)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- return
- + hb_iter (ligature)
- | hb_map (hb_add (this))
- | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
- | hb_any
- ;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int num_ligs = ligature.len;
- for (unsigned int i = 0; i < num_ligs; i++)
- {
- const auto &lig = this+ligature[i];
- if (lig.apply (c)) return_trace (true);
- }
-
- return_trace (false);
- }
-
- bool serialize (hb_serialize_context_t *c,
- hb_array_t<const HBGlyphID16> ligatures,
- hb_array_t<const unsigned int> component_count_list,
- hb_array_t<const HBGlyphID16> &component_list /* Starting from second for each ligature */)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
- for (unsigned int i = 0; i < ligatures.length; i++)
- {
- unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
- if (unlikely (!ligature[i].serialize_serialize (c,
- ligatures[i],
- component_list.sub_array (0, component_count))))
- return_trace (false);
- component_list += component_count;
- }
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- + hb_iter (ligature)
- | hb_filter (subset_offset_array (c, out->ligature, this, coverage_idx))
- | hb_drain
- ;
-
- if (bool (out->ligature))
- // Ensure Coverage table is always packed after this.
- c->serializer->add_virtual_link (coverage_idx);
-
- return_trace (bool (out->ligature));
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_LIGATURESET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubst.hh
deleted file mode 100644
index 18f6e355816..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubst.hh
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_LIGATURESUBST_HH
-#define OT_LAYOUT_GSUB_LIGATURESUBST_HH
-
-#include "Common.hh"
-#include "LigatureSubstFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct LigatureSubst
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- LigatureSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- LigatureSubstFormat1_2<MediumTypes> format2;
-#endif
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- /* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should
- * be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t
- * instead. */
- bool serialize (hb_serialize_context_t *c,
- hb_sorted_array_t<const HBGlyphID16> first_glyphs,
- hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
- hb_array_t<const HBGlyphID16> ligatures_list,
- hb_array_t<const unsigned int> component_count_list,
- hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (u.format))) return_trace (false);
- unsigned int format = 1;
- u.format = format;
- switch (u.format) {
- case 1: return_trace (u.format1.serialize (c,
- first_glyphs,
- ligature_per_first_glyph_count_list,
- ligatures_list,
- component_count_list,
- component_list));
- default:return_trace (false);
- }
- }
-
- /* TODO subset() should choose format. */
-
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_LIGATURESUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
deleted file mode 100644
index 5c7df97d13a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
+++ /dev/null
@@ -1,166 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH
-#define OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH
-
-#include "Common.hh"
-#include "LigatureSet.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct LigatureSubstFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- Array16Of<typename Types::template OffsetTo<LigatureSet<Types>>>
- ligatureSet; /* Array LigatureSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- return
- + hb_zip (this+coverage, ligatureSet)
- | hb_filter (*glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map ([this, glyphs] (const typename Types::template OffsetTo<LigatureSet<Types>> &_)
- { return (this+_).intersects (glyphs); })
- | hb_any
- ;
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- + hb_zip (this+coverage, ligatureSet)
- | hb_filter (c->parent_active_glyphs (), hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const LigatureSet<Types> &_) { _.closure (c); })
- ;
-
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-
- + hb_zip (this+coverage, ligatureSet)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const LigatureSet<Types> &_) { _.collect_glyphs (c); })
- ;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
- if (likely (index == NOT_COVERED)) return false;
-
- const auto &lig_set = this+ligatureSet[index];
- return lig_set.would_apply (c);
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const auto &lig_set = this+ligatureSet[index];
- return_trace (lig_set.apply (c));
- }
-
- bool serialize (hb_serialize_context_t *c,
- hb_sorted_array_t<const HBGlyphID16> first_glyphs,
- hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
- hb_array_t<const HBGlyphID16> ligatures_list,
- hb_array_t<const unsigned int> component_count_list,
- hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- if (unlikely (!ligatureSet.serialize (c, first_glyphs.length))) return_trace (false);
- for (unsigned int i = 0; i < first_glyphs.length; i++)
- {
- unsigned int ligature_count = ligature_per_first_glyph_count_list[i];
- if (unlikely (!ligatureSet[i]
- .serialize_serialize (c,
- ligatures_list.sub_array (0, ligature_count),
- component_count_list.sub_array (0, ligature_count),
- component_list))) return_trace (false);
- ligatures_list += ligature_count;
- component_count_list += ligature_count;
- }
- return_trace (coverage.serialize_serialize (c, first_glyphs));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- // Due to a bug in some older versions of windows 7 the Coverage table must be
- // packed after the LigatureSet and Ligature tables, so serialize Coverage first
- // which places it last in the packed order.
- hb_set_t new_coverage;
- + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
- | hb_filter (glyphset, hb_first)
- | hb_filter ([&] (const LigatureSet<Types>& _) {
- return _.intersects_lig_glyph (&glyphset);
- }, hb_second)
- | hb_map (hb_first)
- | hb_sink (new_coverage);
-
- if (!c->serializer->push<Coverage> ()
- ->serialize (c->serializer,
- + new_coverage.iter () | hb_map_retains_sorting (glyph_map)))
- {
- c->serializer->pop_discard ();
- return_trace (false);
- }
-
- unsigned coverage_idx = c->serializer->pop_pack ();
- c->serializer->add_link (out->coverage, coverage_idx);
-
- + hb_zip (this+coverage, ligatureSet)
- | hb_filter (new_coverage, hb_first)
- | hb_map (hb_second)
- // to ensure that the repacker always orders the coverage table after the LigatureSet
- // and LigatureSubtable's they will be linked to the Coverage table via a virtual link
- // the coverage table object idx is passed down to facilitate this.
- | hb_apply (subset_offset_array (c, out->ligatureSet, this, coverage_idx))
- ;
-
- return_trace (bool (new_coverage));
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_LIGATURESUBSTFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubst.hh
deleted file mode 100644
index 742c8587ee3..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubst.hh
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_MULTIPLESUBST_HH
-#define OT_LAYOUT_GSUB_MULTIPLESUBST_HH
-
-#include "Common.hh"
-#include "MultipleSubstFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct MultipleSubst
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- MultipleSubstFormat1_2<SmallTypes> format1;
-#ifndef HB_NO_BEYOND_64K
- MultipleSubstFormat1_2<MediumTypes> format2;
-#endif
- } u;
-
- public:
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (u.format))) return_trace (false);
- unsigned int format = 1;
- u.format = format;
- switch (u.format) {
- case 1: return_trace (u.format1.serialize (c, it));
- default:return_trace (false);
- }
- }
-
- /* TODO subset() should choose format. */
-
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_MULTIPLESUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
deleted file mode 100644
index 3b4bd116949..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH
-#define OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH
-
-#include "Common.hh"
-#include "Sequence.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct MultipleSubstFormat1_2
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- Array16Of<typename Types::template OffsetTo<Sequence<Types>>>
- sequence; /* Array of Sequence tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (4 + Types::size, sequence);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- + hb_zip (this+coverage, sequence)
- | hb_filter (c->parent_active_glyphs (), hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const Sequence<Types> &_) { _.closure (c); })
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- + hb_zip (this+coverage, sequence)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([c] (const Sequence<Types> &_) { _.collect_glyphs (c); })
- ;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- return_trace ((this+sequence[index]).apply (c));
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- auto sequences =
- + it
- | hb_map (hb_second)
- ;
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- if (unlikely (!sequence.serialize (c, sequences.length))) return_trace (false);
-
- for (auto& pair : hb_zip (sequences, sequence))
- {
- if (unlikely (!pair.second
- .serialize_serialize (c, pair.first)))
- return_trace (false);
- }
-
- return_trace (coverage.serialize_serialize (c, glyphs));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, sequence)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->sequence, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-};
-
-}
-}
-}
-
-
-#endif /* OT_LAYOUT_GSUB_MULTIPLESUBSTFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
deleted file mode 100644
index 5ad463fea79..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH
-#define OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH
-
-#include "Common.hh"
-#include "ReverseChainSingleSubstFormat1.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct ReverseChainSingleSubst
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ReverseChainSingleSubstFormat1 format1;
- } u;
-
- public:
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-};
-
-}
-}
-}
-
-#endif /* HB_OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
deleted file mode 100644
index 2c2e1aa44fd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
+++ /dev/null
@@ -1,244 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
-#define OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct ReverseChainSingleSubstFormat1
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of table */
- Array16OfOffset16To<Coverage>
- backtrack; /* Array of coverage tables
- * in backtracking sequence, in glyph
- * sequence order */
- Array16OfOffset16To<Coverage>
- lookaheadX; /* Array of coverage tables
- * in lookahead sequence, in glyph
- * sequence order */
- Array16Of<HBGlyphID16>
- substituteX; /* Array of substitute
- * GlyphIDs--ordered by Coverage Index */
- public:
- DEFINE_SIZE_MIN (10);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
- return_trace (false);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
- if (!lookahead.sanitize (c, this))
- return_trace (false);
- const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
- return_trace (substitute.sanitize (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (!(this+coverage).intersects (glyphs))
- return false;
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
-
- unsigned int count;
-
- count = backtrack.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+backtrack[i]).intersects (glyphs))
- return false;
-
- count = lookahead.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+lookahead[i]).intersects (glyphs))
- return false;
-
- return true;
- }
-
- bool may_have_non_1to1 () const
- { return false; }
-
- void closure (hb_closure_context_t *c) const
- {
- if (!intersects (c->glyphs)) return;
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
- const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
-
- + hb_zip (this+coverage, substitute)
- | hb_filter (c->parent_active_glyphs (), hb_first)
- | hb_map (hb_second)
- | hb_sink (c->output)
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
-
- unsigned int count;
-
- count = backtrack.len;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return;
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
- count = lookahead.len;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
-
- const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
- count = substitute.len;
- c->output->add_array (substitute.arrayZ, substitute.len);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
- return_trace (false); /* No chaining to this type */
-
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
- const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
-
- if (unlikely (index >= substitute.len)) return_trace (false);
-
- unsigned int start_index = 0, end_index = 0;
- if (match_backtrack (c,
- backtrack.len, (HBUINT16 *) backtrack.arrayZ,
- match_coverage, this,
- &start_index) &&
- match_lookahead (c,
- lookahead.len, (HBUINT16 *) lookahead.arrayZ,
- match_coverage, this,
- c->buffer->idx + 1, &end_index))
- {
- c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replacing glyph at %u (reverse chaining substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph_inplace (substitute[index]);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (reverse chaining substitution)",
- c->buffer->idx);
- }
-
- /* Note: We DON'T decrease buffer->idx. The main loop does it
- * for us. This is useful for preventing surprises if someone
- * calls us through a Context lookup. */
- return_trace (true);
- }
- else
- {
- c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
- return_trace (false);
- }
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize_coverage_offset_array (hb_subset_context_t *c, Iterator it) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> ();
-
- if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size)))
- return_trace (false);
-
- for (auto& offset : it) {
- auto *o = out->serialize_append (c->serializer);
- if (unlikely (!o) || !o->serialize_subset (c, offset, this))
- return_trace (false);
- }
-
- return_trace (true);
- }
-
- template<typename Iterator, typename BacktrackIterator, typename LookaheadIterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_pair_t)),
- hb_requires (hb_is_iterator (BacktrackIterator)),
- hb_requires (hb_is_iterator (LookaheadIterator))>
- bool serialize (hb_subset_context_t *c,
- Iterator coverage_subst_iter,
- BacktrackIterator backtrack_iter,
- LookaheadIterator lookahead_iter) const
- {
- TRACE_SERIALIZE (this);
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->check_success (out))) return_trace (false);
- if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
- if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false);
-
- if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false);
- if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false);
-
- auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID16>> ();
- auto substitutes =
- + coverage_subst_iter
- | hb_map (hb_second)
- ;
-
- auto glyphs =
- + coverage_subst_iter
- | hb_map_retains_sorting (hb_first)
- ;
- if (unlikely (! c->serializer->check_success (substitute_out->serialize (c->serializer, substitutes))))
- return_trace (false);
-
- if (unlikely (!out->coverage.serialize_serialize (c->serializer, glyphs)))
- return_trace (false);
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
- const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
-
- auto it =
- + hb_zip (this+coverage, substitute)
- | hb_filter (glyphset, hb_first)
- | hb_filter (glyphset, hb_second)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
- { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
- ;
-
- return_trace (bool (it) && serialize (c, it, backtrack.iter (), lookahead.iter ()));
- }
-};
-
-}
-}
-}
-
-#endif /* HB_OT_LAYOUT_GSUB_REVERSECHAINSINGLESUBSTFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Sequence.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Sequence.hh
deleted file mode 100644
index ae3292f3295..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Sequence.hh
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SEQUENCE_HH
-#define OT_LAYOUT_GSUB_SEQUENCE_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct Sequence
-{
- protected:
- Array16Of<typename Types::HBGlyphID>
- substitute; /* String of GlyphIDs to substitute */
- public:
- DEFINE_SIZE_ARRAY (2, substitute);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (substitute.sanitize (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return hb_all (substitute, glyphs); }
-
- void closure (hb_closure_context_t *c) const
- { c->output->add_array (substitute.arrayZ, substitute.len); }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- { c->output->add_array (substitute.arrayZ, substitute.len); }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int count = substitute.len;
-
- /* Special-case to make it in-place and not consider this
- * as a "multiplied" substitution. */
- if (unlikely (count == 1))
- {
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "replacing glyph at %u (multiple substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph (substitute.arrayZ[0]);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (multiple subtitution)",
- c->buffer->idx - 1u);
- }
-
- return_trace (true);
- }
- /* Spec disallows this, but Uniscribe allows it.
- * https://github.com/harfbuzz/harfbuzz/issues/253 */
- else if (unlikely (count == 0))
- {
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "deleting glyph at %u (multiple substitution)",
- c->buffer->idx);
- }
-
- c->buffer->delete_glyph ();
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "deleted glyph at %u (multiple substitution)",
- c->buffer->idx);
- }
-
- return_trace (true);
- }
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "multiplying glyph at %u",
- c->buffer->idx);
- }
-
- unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
- unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
-
- for (unsigned int i = 0; i < count; i++)
- {
- /* If is attached to a ligature, don't disturb that.
- * https://github.com/harfbuzz/harfbuzz/issues/3069 */
- if (!lig_id)
- _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
- c->output_glyph_for_component (substitute.arrayZ[i], klass);
- }
- c->buffer->skip_glyph ();
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
-
- char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0};
- char *p = buf;
-
- for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++)
- {
- if (buf < p)
- *p++ = ',';
- snprintf (p, sizeof(buf) - (p - buf), "%u", i);
- p += strlen(p);
- }
-
- c->buffer->message (c->font,
- "multiplied glyphs at %s",
- buf);
- }
-
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator subst)
- {
- TRACE_SERIALIZE (this);
- return_trace (substitute.serialize (c, subst));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- if (!intersects (&glyphset)) return_trace (false);
-
- auto it =
- + hb_iter (substitute)
- | hb_map (glyph_map)
- ;
-
- auto *out = c->serializer->start_embed (*this);
- return_trace (out->serialize (c->serializer, it));
- }
-};
-
-
-}
-}
-}
-
-
-#endif /* OT_LAYOUT_GSUB_SEQUENCE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh
deleted file mode 100644
index 4529927ba6d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SINGLESUBST_HH
-#define OT_LAYOUT_GSUB_SINGLESUBST_HH
-
-#include "Common.hh"
-#include "SingleSubstFormat1.hh"
-#include "SingleSubstFormat2.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct SingleSubst
-{
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- SingleSubstFormat1_3<SmallTypes> format1;
- SingleSubstFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BEYOND_64K
- SingleSubstFormat1_3<MediumTypes> format3;
- SingleSubstFormat2_4<MediumTypes> format4;
-#endif
- } u;
-
- public:
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator,
- const hb_codepoint_pair_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator glyphs)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (u.format))) return_trace (false);
- unsigned format = 2;
- unsigned delta = 0;
- if (glyphs)
- {
- format = 1;
- hb_codepoint_t mask = 0xFFFFu;
-
-#ifndef HB_NO_BEYOND_64K
- if (+ glyphs
- | hb_map_retains_sorting (hb_first)
- | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
- {
- format += 2;
- mask = 0xFFFFFFu;
- }
-#endif
-
- auto get_delta = [=] (hb_codepoint_pair_t _)
- { return (unsigned) (_.second - _.first) & mask; };
- delta = get_delta (*glyphs);
- if (!hb_all (++(+glyphs), delta, get_delta)) format += 1;
- }
-
- u.format = format;
- switch (u.format) {
- case 1: return_trace (u.format1.serialize (c,
- + glyphs
- | hb_map_retains_sorting (hb_first),
- delta));
- case 2: return_trace (u.format2.serialize (c, glyphs));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.serialize (c,
- + glyphs
- | hb_map_retains_sorting (hb_first),
- delta));
- case 4: return_trace (u.format4.serialize (c, glyphs));
-#endif
- default:return_trace (false);
- }
- }
-};
-
-template<typename Iterator>
-static void
-SingleSubst_serialize (hb_serialize_context_t *c,
- Iterator it)
-{ c->start_embed<SingleSubst> ()->serialize (c, it); }
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_SINGLESUBST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat1.hh
deleted file mode 100644
index 850be86c043..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ /dev/null
@@ -1,204 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH
-#define OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct SingleSubstFormat1_3
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- typename Types::HBUINT
- deltaGlyphID; /* Add to original GlyphID to get
- * substitute GlyphID, modulo 0x10000 */
-
- public:
- DEFINE_SIZE_STATIC (2 + 2 * Types::size);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- coverage.sanitize (c, this) &&
- /* The coverage table may use a range to represent a set
- * of glyphs, which means a small number of bytes can
- * generate a large glyph set. Manually modify the
- * sanitizer max ops to take this into account.
- *
- * Note: This check *must* be right after coverage sanitize. */
- c->check_ops ((this + coverage).get_population () >> 1));
- }
-
- hb_codepoint_t get_mask () const
- { return (1 << (8 * Types::size)) - 1; }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- bool may_have_non_1to1 () const
- { return false; }
-
- void closure (hb_closure_context_t *c) const
- {
- hb_codepoint_t d = deltaGlyphID;
- hb_codepoint_t mask = get_mask ();
-
- /* Help fuzzer avoid this function as much. */
- unsigned pop = (this+coverage).get_population ();
- if (pop >= mask)
- return;
-
- hb_set_t intersection;
- (this+coverage).intersect_set (c->parent_active_glyphs (), intersection);
-
- /* In degenerate fuzzer-found fonts, but not real fonts,
- * this table can keep adding new glyphs in each round of closure.
- * Refuse to close-over, if it maps glyph range to overlapping range. */
- hb_codepoint_t min_before = intersection.get_min ();
- hb_codepoint_t max_before = intersection.get_max ();
- hb_codepoint_t min_after = (min_before + d) & mask;
- hb_codepoint_t max_after = (max_before + d) & mask;
- if (intersection.get_population () == max_before - min_before + 1 &&
- ((min_before <= min_after && min_after <= max_before) ||
- (min_before <= max_after && max_after <= max_before)))
- return;
-
- + hb_iter (intersection)
- | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; })
- | hb_sink (c->output)
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- hb_codepoint_t d = deltaGlyphID;
- hb_codepoint_t mask = get_mask ();
-
- + hb_iter (this+coverage)
- | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; })
- | hb_sink (c->output)
- ;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
- unsigned
- get_glyph_alternates (hb_codepoint_t glyph_id,
- unsigned start_offset,
- unsigned *alternate_count /* IN/OUT. May be NULL. */,
- hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
- {
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (likely (index == NOT_COVERED))
- {
- if (alternate_count)
- *alternate_count = 0;
- return 0;
- }
-
- if (alternate_count && *alternate_count)
- {
- hb_codepoint_t d = deltaGlyphID;
- hb_codepoint_t mask = get_mask ();
-
- glyph_id = (glyph_id + d) & mask;
-
- *alternate_glyphs = glyph_id;
- *alternate_count = 1;
- }
-
- return 1;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- hb_codepoint_t d = deltaGlyphID;
- hb_codepoint_t mask = get_mask ();
-
- glyph_id = (glyph_id + d) & mask;
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "replacing glyph at %u (single substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph (glyph_id);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (single substitution)",
- c->buffer->idx - 1u);
- }
-
- return_trace (true);
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator glyphs,
- unsigned delta)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
- c->check_assign (deltaGlyphID, delta, HB_SERIALIZE_ERROR_INT_OVERFLOW);
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- hb_codepoint_t d = deltaGlyphID;
- hb_codepoint_t mask = get_mask ();
-
- hb_set_t intersection;
- (this+coverage).intersect_set (glyphset, intersection);
-
- auto it =
- + hb_iter (intersection)
- | hb_map_retains_sorting ([d, mask] (hb_codepoint_t g) {
- return hb_codepoint_pair_t (g,
- (g + d) & mask); })
- | hb_filter (glyphset, hb_second)
- | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
- { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
- ;
-
- bool ret = bool (it);
- SingleSubst_serialize (c->serializer, it);
- return_trace (ret);
- }
-};
-
-}
-}
-}
-
-
-#endif /* OT_LAYOUT_GSUB_SINGLESUBSTFORMAT1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat2.hh
deleted file mode 100644
index 9c651abe71d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
-#define OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
-
-#include "Common.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-template <typename Types>
-struct SingleSubstFormat2_4
-{
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- Array16Of<typename Types::HBGlyphID>
- substitute; /* Array of substitute
- * GlyphIDs--ordered by Coverage Index */
-
- public:
- DEFINE_SIZE_ARRAY (4 + Types::size, substitute);
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- { return (this+coverage).intersects (glyphs); }
-
- bool may_have_non_1to1 () const
- { return false; }
-
- void closure (hb_closure_context_t *c) const
- {
- auto &cov = this+coverage;
- auto &glyph_set = c->parent_active_glyphs ();
-
- if (substitute.len > glyph_set.get_population () * 4)
- {
- for (auto g : glyph_set)
- {
- unsigned i = cov.get_coverage (g);
- if (i == NOT_COVERED || i >= substitute.len)
- continue;
- c->output->add (substitute.arrayZ[i]);
- }
-
- return;
- }
-
- + hb_zip (cov, substitute)
- | hb_filter (glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_sink (c->output)
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- + hb_zip (this+coverage, substitute)
- | hb_map (hb_second)
- | hb_sink (c->output)
- ;
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool would_apply (hb_would_apply_context_t *c) const
- { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
-
- unsigned
- get_glyph_alternates (hb_codepoint_t glyph_id,
- unsigned start_offset,
- unsigned *alternate_count /* IN/OUT. May be NULL. */,
- hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
- {
- unsigned int index = (this+coverage).get_coverage (glyph_id);
- if (likely (index == NOT_COVERED))
- {
- if (alternate_count)
- *alternate_count = 0;
- return 0;
- }
-
- if (alternate_count && *alternate_count)
- {
- glyph_id = substitute[index];
-
- *alternate_glyphs = glyph_id;
- *alternate_count = 1;
- }
-
- return 1;
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- if (unlikely (index >= substitute.len)) return_trace (false);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "replacing glyph at %u (single substitution)",
- c->buffer->idx);
- }
-
- c->replace_glyph (substitute[index]);
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- c->buffer->message (c->font,
- "replaced glyph at %u (single substitution)",
- c->buffer->idx - 1u);
- }
-
- return_trace (true);
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator,
- hb_codepoint_pair_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- auto substitutes =
- + it
- | hb_map (hb_second)
- ;
- auto glyphs =
- + it
- | hb_map_retains_sorting (hb_first)
- ;
- if (unlikely (!c->extend_min (this))) return_trace (false);
- if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
- if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_zip (this+coverage, substitute)
- | hb_filter (glyphset, hb_first)
- | hb_filter (glyphset, hb_second)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t
- { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
- ;
-
- bool ret = bool (it);
- SingleSubst_serialize (c->serializer, it);
- return_trace (ret);
- }
-};
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookup.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookup.hh
deleted file mode 100644
index d49dcc0e0fd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookup.hh
+++ /dev/null
@@ -1,220 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
-#define OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
-
-#include "Common.hh"
-#include "SubstLookupSubTable.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct SubstLookup : Lookup
-{
- using SubTable = SubstLookupSubTable;
-
- bool sanitize (hb_sanitize_context_t *c) const
- { return Lookup::sanitize<SubTable> (c); }
-
- const SubTable& get_subtable (unsigned int i) const
- { return Lookup::get_subtable<SubTable> (i); }
-
- static inline bool lookup_type_is_reverse (unsigned int lookup_type)
- { return lookup_type == SubTable::ReverseChainSingle; }
-
- bool is_reverse () const
- {
- unsigned int type = get_type ();
- if (unlikely (type == SubTable::Extension))
- return get_subtable (0).u.extension.is_reverse ();
- return lookup_type_is_reverse (type);
- }
-
- bool may_have_non_1to1 () const
- {
- hb_have_non_1to1_context_t c;
- return dispatch (&c);
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- return_trace (dispatch (c));
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c);
- }
-
- hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
- {
- if (!c->should_visit_lookup (this_index))
- return hb_closure_context_t::default_return_value ();
-
- c->set_recurse_func (dispatch_closure_recurse_func);
-
- hb_closure_context_t::return_t ret = dispatch (c);
-
- c->flush ();
-
- return ret;
- }
-
- hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
- {
- if (c->is_lookup_visited (this_index))
- return hb_closure_lookups_context_t::default_return_value ();
-
- c->set_lookup_visited (this_index);
- if (!intersects (c->glyphs))
- {
- c->set_lookup_inactive (this_index);
- return hb_closure_lookups_context_t::default_return_value ();
- }
-
- hb_closure_lookups_context_t::return_t ret = dispatch (c);
- return ret;
- }
-
- hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
- return dispatch (c);
- }
-
- template <typename set_t>
- void collect_coverage (set_t *glyphs) const
- {
- hb_collect_coverage_context_t<set_t> c (glyphs);
- dispatch (&c);
- }
-
- bool would_apply (hb_would_apply_context_t *c,
- const hb_ot_layout_lookup_accelerator_t *accel) const
- {
- if (unlikely (!c->len)) return false;
- if (!accel->may_have (c->glyphs[0])) return false;
- return dispatch (c);
- }
-
- template<typename Glyphs, typename Substitutes,
- hb_requires (hb_is_sorted_source_of (Glyphs,
- const hb_codepoint_t) &&
- hb_is_source_of (Substitutes,
- const hb_codepoint_t))>
- bool serialize_single (hb_serialize_context_t *c,
- uint32_t lookup_props,
- Glyphs glyphs,
- Substitutes substitutes)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
- if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes)))
- {
- c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
- return_trace (true);
- }
- c->pop_discard ();
- return_trace (false);
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c,
- uint32_t lookup_props,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
- if (c->push<SubTable> ()->u.multiple.
- serialize (c, it))
- {
- c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
- return_trace (true);
- }
- c->pop_discard ();
- return_trace (false);
- }
-
- bool serialize_alternate (hb_serialize_context_t *c,
- uint32_t lookup_props,
- hb_sorted_array_t<const HBGlyphID16> glyphs,
- hb_array_t<const unsigned int> alternate_len_list,
- hb_array_t<const HBGlyphID16> alternate_glyphs_list)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
-
- if (c->push<SubTable> ()->u.alternate.
- serialize (c,
- glyphs,
- alternate_len_list,
- alternate_glyphs_list))
- {
- c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
- return_trace (true);
- }
- c->pop_discard ();
- return_trace (false);
- }
-
- bool serialize_ligature (hb_serialize_context_t *c,
- uint32_t lookup_props,
- hb_sorted_array_t<const HBGlyphID16> first_glyphs,
- hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
- hb_array_t<const HBGlyphID16> ligatures_list,
- hb_array_t<const unsigned int> component_count_list,
- hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
- if (c->push<SubTable> ()->u.ligature.
- serialize (c,
- first_glyphs,
- ligature_per_first_glyph_count_list,
- ligatures_list,
- component_count_list,
- component_list))
- {
- c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
- return_trace (true);
- }
- c->pop_discard ();
- return_trace (false);
- }
-
- template <typename context_t>
- static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
-
- static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index);
-
- static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
- {
- if (!c->should_visit_lookup (lookup_index))
- return hb_empty_t ();
-
- hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index);
-
- /* While in theory we should flush here, it will cause timeouts because a recursive
- * lookup can keep growing the glyph set. Skip, and outer loop will retry up to
- * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
- //c->flush ();
-
- return ret;
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
-
- bool subset (hb_subset_context_t *c) const
- { return Lookup::subset<SubTable> (c); }
-};
-
-
-}
-}
-}
-
-#endif /* OT_LAYOUT_GSUB_SUBSTLOOKUP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookupSubTable.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookupSubTable.hh
deleted file mode 100644
index a525fba0399..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SubstLookupSubTable.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH
-#define OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH
-
-#include "Common.hh"
-#include "SingleSubst.hh"
-#include "MultipleSubst.hh"
-#include "AlternateSubst.hh"
-#include "LigatureSubst.hh"
-#include "ContextSubst.hh"
-#include "ChainContextSubst.hh"
-#include "ExtensionSubst.hh"
-#include "ReverseChainSingleSubst.hh"
-
-namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-
-struct SubstLookupSubTable
-{
- friend struct ::OT::Lookup;
- friend struct SubstLookup;
-
- protected:
- union {
- SingleSubst single;
- MultipleSubst multiple;
- AlternateSubst alternate;
- LigatureSubst ligature;
- ContextSubst context;
- ChainContextSubst chainContext;
- ExtensionSubst extension;
- ReverseChainSingleSubst reverseChainContextSingle;
- } u;
- public:
- DEFINE_SIZE_MIN (0);
-
- enum Type {
- Single = 1,
- Multiple = 2,
- Alternate = 3,
- Ligature = 4,
- Context = 5,
- ChainContext = 6,
- Extension = 7,
- ReverseChainSingle = 8
- };
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
- {
- TRACE_DISPATCH (this, lookup_type);
- switch (lookup_type) {
- case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
- case Multiple: return_trace (u.multiple.dispatch (c, std::forward<Ts> (ds)...));
- case Alternate: return_trace (u.alternate.dispatch (c, std::forward<Ts> (ds)...));
- case Ligature: return_trace (u.ligature.dispatch (c, std::forward<Ts> (ds)...));
- case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
- case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
- case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
- case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, std::forward<Ts> (ds)...));
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
- {
- hb_intersects_context_t c (glyphs);
- return dispatch (&c, lookup_type);
- }
-};
-
-
-}
-}
-}
-
-#endif /* HB_OT_LAYOUT_GSUB_SUBSTLOOKUPSUBTABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh
deleted file mode 100644
index 6a43403e94b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod, Garret Rieger
- */
-
-#ifndef OT_LAYOUT_TYPES_HH
-#define OT_LAYOUT_TYPES_HH
-
-namespace OT {
-namespace Layout {
-
-struct SmallTypes {
- static constexpr unsigned size = 2;
- using large_int = uint32_t;
- using HBUINT = HBUINT16;
- using HBGlyphID = HBGlyphID16;
- using Offset = Offset16;
- template <typename Type, bool has_null=true>
- using OffsetTo = OT::Offset16To<Type, has_null>;
- template <typename Type>
- using ArrayOf = OT::Array16Of<Type>;
- template <typename Type>
- using SortedArrayOf = OT::SortedArray16Of<Type>;
-};
-
-struct MediumTypes {
- static constexpr unsigned size = 3;
- using large_int = uint64_t;
- using HBUINT = HBUINT24;
- using HBGlyphID = HBGlyphID24;
- using Offset = Offset24;
- template <typename Type, bool has_null=true>
- using OffsetTo = OT::Offset24To<Type, has_null>;
- template <typename Type>
- using ArrayOf = OT::Array24Of<Type>;
- template <typename Type>
- using SortedArrayOf = OT::SortedArray24Of<Type>;
-};
-
-}
-}
-
-#endif /* OT_LAYOUT_TYPES_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh
deleted file mode 100644
index 94e00d3aea3..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh
+++ /dev/null
@@ -1,399 +0,0 @@
-#ifndef OT_GLYF_COMPOSITEGLYPH_HH
-#define OT_GLYF_COMPOSITEGLYPH_HH
-
-
-#include "../../hb-open-type.hh"
-#include "composite-iter.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct CompositeGlyphRecord
-{
- protected:
- enum composite_glyph_flag_t
- {
- ARG_1_AND_2_ARE_WORDS = 0x0001,
- ARGS_ARE_XY_VALUES = 0x0002,
- ROUND_XY_TO_GRID = 0x0004,
- WE_HAVE_A_SCALE = 0x0008,
- MORE_COMPONENTS = 0x0020,
- WE_HAVE_AN_X_AND_Y_SCALE = 0x0040,
- WE_HAVE_A_TWO_BY_TWO = 0x0080,
- WE_HAVE_INSTRUCTIONS = 0x0100,
- USE_MY_METRICS = 0x0200,
- OVERLAP_COMPOUND = 0x0400,
- SCALED_COMPONENT_OFFSET = 0x0800,
- UNSCALED_COMPONENT_OFFSET = 0x1000,
-#ifndef HB_NO_BEYOND_64K
- GID_IS_24BIT = 0x2000
-#endif
- };
-
- public:
- unsigned int get_size () const
- {
- unsigned int size = min_size;
- /* glyphIndex is 24bit instead of 16bit */
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size;
-#endif
- /* arg1 and 2 are int16 */
- if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
- /* arg1 and 2 are int8 */
- else size += 2;
-
- /* One x 16 bit (scale) */
- if (flags & WE_HAVE_A_SCALE) size += 2;
- /* Two x 16 bit (xscale, yscale) */
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
- /* Four x 16 bit (xscale, scale01, scale10, yscale) */
- else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
-
- return size;
- }
-
- void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; }
- void set_overlaps_flag ()
- {
- flags = (uint16_t) flags | OVERLAP_COMPOUND;
- }
-
- bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; }
-
- bool has_more () const { return flags & MORE_COMPONENTS; }
- bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
- bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
- void get_anchor_points (unsigned int &point1, unsigned int &point2) const
- {
- const auto *p = &StructAfter<const HBUINT8> (flags);
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT)
- p += HBGlyphID24::static_size;
- else
-#endif
- p += HBGlyphID16::static_size;
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- point1 = ((const HBUINT16 *) p)[0];
- point2 = ((const HBUINT16 *) p)[1];
- }
- else
- {
- point1 = p[0];
- point2 = p[1];
- }
- }
-
- void transform_points (contour_point_vector_t &points,
- const float (&matrix)[4],
- const contour_point_t &trans) const
- {
- if (scaled_offsets ())
- {
- points.translate (trans);
- points.transform (matrix);
- }
- else
- {
- points.transform (matrix);
- points.translate (trans);
- }
- }
-
- bool get_points (contour_point_vector_t &points) const
- {
- float matrix[4];
- contour_point_t trans;
- get_transformation (matrix, trans);
- if (unlikely (!points.resize (points.length + 1))) return false;
- points[points.length - 1] = trans;
- return true;
- }
-
- unsigned compile_with_point (const contour_point_t &point,
- char *out) const
- {
- const HBINT8 *p = &StructAfter<const HBINT8> (flags);
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT)
- p += HBGlyphID24::static_size;
- else
-#endif
- p += HBGlyphID16::static_size;
-
- unsigned len = get_size ();
- unsigned len_before_val = (const char *)p - (const char *)this;
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- // no overflow, copy value
- hb_memcpy (out, this, len);
-
- HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
- o[0] = roundf (point.x);
- o[1] = roundf (point.y);
- }
- else
- {
- int new_x = roundf (point.x);
- int new_y = roundf (point.y);
- if (new_x <= 127 && new_x >= -128 &&
- new_y <= 127 && new_y >= -128)
- {
- hb_memcpy (out, this, len);
- HBINT8 *o = reinterpret_cast<HBINT8 *> (out + len_before_val);
- o[0] = new_x;
- o[1] = new_y;
- }
- else
- {
- // new point value has an int8 overflow
- hb_memcpy (out, this, len_before_val);
-
- //update flags
- CompositeGlyphRecord *o = reinterpret_cast<CompositeGlyphRecord *> (out);
- o->flags = flags | ARG_1_AND_2_ARE_WORDS;
- out += len_before_val;
-
- HBINT16 new_value;
- new_value = new_x;
- hb_memcpy (out, &new_value, HBINT16::static_size);
- out += HBINT16::static_size;
-
- new_value = new_y;
- hb_memcpy (out, &new_value, HBINT16::static_size);
- out += HBINT16::static_size;
-
- hb_memcpy (out, p+2, len - len_before_val - 2);
- len += 2;
- }
- }
- return len;
- }
-
- protected:
- bool scaled_offsets () const
- { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
-
- public:
- bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
- {
- matrix[0] = matrix[3] = 1.f;
- matrix[1] = matrix[2] = 0.f;
-
- const auto *p = &StructAfter<const HBINT8> (flags);
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT)
- p += HBGlyphID24::static_size;
- else
-#endif
- p += HBGlyphID16::static_size;
- int tx, ty;
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- tx = *(const HBINT16 *) p;
- p += HBINT16::static_size;
- ty = *(const HBINT16 *) p;
- p += HBINT16::static_size;
- }
- else
- {
- tx = *p++;
- ty = *p++;
- }
- if (is_anchored ()) tx = ty = 0;
-
- trans.init ((float) tx, (float) ty);
-
- {
- const F2DOT14 *points = (const F2DOT14 *) p;
- if (flags & WE_HAVE_A_SCALE)
- {
- matrix[0] = matrix[3] = points[0].to_float ();
- return true;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- matrix[0] = points[0].to_float ();
- matrix[3] = points[1].to_float ();
- return true;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- matrix[0] = points[0].to_float ();
- matrix[1] = points[1].to_float ();
- matrix[2] = points[2].to_float ();
- matrix[3] = points[3].to_float ();
- return true;
- }
- }
- return tx || ty;
- }
-
- hb_codepoint_t get_gid () const
- {
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT)
- return StructAfter<const HBGlyphID24> (flags);
- else
-#endif
- return StructAfter<const HBGlyphID16> (flags);
- }
- void set_gid (hb_codepoint_t gid)
- {
-#ifndef HB_NO_BEYOND_64K
- if (flags & GID_IS_24BIT)
- StructAfter<HBGlyphID24> (flags) = gid;
- else
-#endif
- /* TODO assert? */
- StructAfter<HBGlyphID16> (flags) = gid;
- }
-
-#ifndef HB_NO_BEYOND_64K
- void lower_gid_24_to_16 ()
- {
- hb_codepoint_t gid = get_gid ();
- if (!(flags & GID_IS_24BIT) || gid > 0xFFFFu)
- return;
-
- /* Lower the flag and move the rest of the struct down. */
-
- unsigned size = get_size ();
- char *end = (char *) this + size;
- char *p = &StructAfter<char> (flags);
- p += HBGlyphID24::static_size;
-
- flags = flags & ~GID_IS_24BIT;
- set_gid (gid);
-
- memmove (p - HBGlyphID24::static_size + HBGlyphID16::static_size, p, end - p);
- }
-#endif
-
- protected:
- HBUINT16 flags;
- HBUINT24 pad;
- public:
- DEFINE_SIZE_MIN (4);
-};
-
-using composite_iter_t = composite_iter_tmpl<CompositeGlyphRecord>;
-
-struct CompositeGlyph
-{
- const GlyphHeader &header;
- hb_bytes_t bytes;
- CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
- header (header_), bytes (bytes_) {}
-
- composite_iter_t iter () const
- { return composite_iter_t (bytes, &StructAfter<CompositeGlyphRecord, GlyphHeader> (header)); }
-
- unsigned int instructions_length (hb_bytes_t bytes) const
- {
- unsigned int start = bytes.length;
- unsigned int end = bytes.length;
- const CompositeGlyphRecord *last = nullptr;
- for (auto &item : iter ())
- last = &item;
- if (unlikely (!last)) return 0;
-
- if (last->has_instructions ())
- start = (char *) last - &bytes + last->get_size ();
- if (unlikely (start > end)) return 0;
- return end - start;
- }
-
- /* Trimming for composites not implemented.
- * If removing hints it falls out of that. */
- const hb_bytes_t trim_padding () const { return bytes; }
-
- void drop_hints ()
- {
- for (const auto &_ : iter ())
- const_cast<CompositeGlyphRecord &> (_).drop_instructions_flag ();
- }
-
- /* Chop instructions off the end */
- void drop_hints_bytes (hb_bytes_t &dest_start) const
- { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
-
- void set_overlaps_flag ()
- {
- CompositeGlyphRecord& glyph_chain = const_cast<CompositeGlyphRecord &> (
- StructAfter<CompositeGlyphRecord, GlyphHeader> (header));
- if (!bytes.check_range(&glyph_chain, CompositeGlyphRecord::min_size))
- return;
- glyph_chain.set_overlaps_flag ();
- }
-
- bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
- const contour_point_vector_t &points_with_deltas,
- hb_bytes_t &dest_bytes /* OUT */)
- {
- if (source_bytes.length <= GlyphHeader::static_size ||
- header.numberOfContours != -1)
- {
- dest_bytes = hb_bytes_t ();
- return true;
- }
-
- unsigned source_len = source_bytes.length - GlyphHeader::static_size;
-
- /* try to allocate more memories than source glyph bytes
- * in case that there might be an overflow for int8 value
- * and we would need to use int16 instead */
- char *o = (char *) hb_calloc (source_len * 2, sizeof (char));
- if (unlikely (!o)) return false;
-
- const CompositeGlyphRecord *c = reinterpret_cast<const CompositeGlyphRecord *> (source_bytes.arrayZ + GlyphHeader::static_size);
- auto it = composite_iter_t (hb_bytes_t ((const char *)c, source_len), c);
-
- char *p = o;
- unsigned i = 0, source_comp_len = 0;
- for (const auto &component : it)
- {
- /* last 4 points in points_with_deltas are phantom points and should not be included */
- if (i >= points_with_deltas.length - 4) {
- free (o);
- return false;
- }
-
- unsigned comp_len = component.get_size ();
- if (component.is_anchored ())
- {
- hb_memcpy (p, &component, comp_len);
- p += comp_len;
- }
- else
- {
- unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
- p += new_len;
- }
- i++;
- source_comp_len += comp_len;
- }
-
- //copy instructions if any
- if (source_len > source_comp_len)
- {
- unsigned instr_len = source_len - source_comp_len;
- hb_memcpy (p, (const char *)c + source_comp_len, instr_len);
- p += instr_len;
- }
-
- unsigned len = p - o;
- dest_bytes = hb_bytes_t (o, len);
- return true;
- }
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_COMPOSITEGLYPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
deleted file mode 100644
index 9e15a6e6d03..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
+++ /dev/null
@@ -1,566 +0,0 @@
-#ifndef OT_GLYF_GLYPH_HH
-#define OT_GLYF_GLYPH_HH
-
-
-#include "../../hb-open-type.hh"
-
-#include "GlyphHeader.hh"
-#include "SimpleGlyph.hh"
-#include "CompositeGlyph.hh"
-#include "VarCompositeGlyph.hh"
-#include "coord-setter.hh"
-
-
-namespace OT {
-
-struct glyf_accelerator_t;
-
-namespace glyf_impl {
-
-
-enum phantom_point_index_t
-{
- PHANTOM_LEFT = 0,
- PHANTOM_RIGHT = 1,
- PHANTOM_TOP = 2,
- PHANTOM_BOTTOM = 3,
- PHANTOM_COUNT = 4
-};
-
-struct Glyph
-{
- enum glyph_type_t {
- EMPTY,
- SIMPLE,
- COMPOSITE,
-#ifndef HB_NO_VAR_COMPOSITES
- VAR_COMPOSITE,
-#endif
- };
-
- public:
- composite_iter_t get_composite_iterator () const
- {
- if (type != COMPOSITE) return composite_iter_t ();
- return CompositeGlyph (*header, bytes).iter ();
- }
- var_composite_iter_t get_var_composite_iterator () const
- {
-#ifndef HB_NO_VAR_COMPOSITES
- if (type != VAR_COMPOSITE) return var_composite_iter_t ();
- return VarCompositeGlyph (*header, bytes).iter ();
-#else
- return var_composite_iter_t ();
-#endif
- }
-
- const hb_bytes_t trim_padding () const
- {
- switch (type) {
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding ();
-#endif
- case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
- case SIMPLE: return SimpleGlyph (*header, bytes).trim_padding ();
- case EMPTY: return bytes;
- default: return bytes;
- }
- }
-
- void drop_hints ()
- {
- switch (type) {
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE: return; // No hinting
-#endif
- case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
- case SIMPLE: SimpleGlyph (*header, bytes).drop_hints (); return;
- case EMPTY: return;
- }
- }
-
- void set_overlaps_flag ()
- {
- switch (type) {
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE: return; // No overlaps flag
-#endif
- case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
- case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
- case EMPTY: return;
- }
- }
-
- void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
- {
- switch (type) {
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE: return; // No hinting
-#endif
- case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
- case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
- case EMPTY: return;
- }
- }
-
- void update_mtx (const hb_subset_plan_t *plan,
- int xMin, int xMax,
- int yMin, int yMax,
- const contour_point_vector_t &all_points) const
- {
- hb_codepoint_t new_gid = 0;
- if (!plan->new_gid_for_old_gid (gid, &new_gid))
- return;
-
- if (type != EMPTY)
- {
- plan->bounds_width_map.set (new_gid, xMax - xMin);
- plan->bounds_height_map.set (new_gid, yMax - yMin);
- }
-
- unsigned len = all_points.length;
- float leftSideX = all_points[len - 4].x;
- float rightSideX = all_points[len - 3].x;
- float topSideY = all_points[len - 2].y;
- float bottomSideY = all_points[len - 1].y;
-
- signed hori_aw = roundf (rightSideX - leftSideX);
- if (hori_aw < 0) hori_aw = 0;
- int lsb = roundf (xMin - leftSideX);
- plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
- //flag value should be computed using non-empty glyphs
- if (type != EMPTY && lsb != xMin)
- plan->head_maxp_info.allXMinIsLsb = false;
-
- signed vert_aw = roundf (topSideY - bottomSideY);
- if (vert_aw < 0) vert_aw = 0;
- int tsb = roundf (topSideY - yMax);
- plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
- }
-
- bool compile_header_bytes (const hb_subset_plan_t *plan,
- const contour_point_vector_t &all_points,
- hb_bytes_t &dest_bytes /* OUT */) const
- {
- GlyphHeader *glyph_header = nullptr;
- if (!plan->pinned_at_default && type != EMPTY && all_points.length >= 4)
- {
- glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
- if (unlikely (!glyph_header)) return false;
- }
-
- float xMin = 0, xMax = 0;
- float yMin = 0, yMax = 0;
- if (all_points.length > 4)
- {
- xMin = xMax = all_points[0].x;
- yMin = yMax = all_points[0].y;
- }
-
- for (unsigned i = 1; i < all_points.length - 4; i++)
- {
- float x = all_points[i].x;
- float y = all_points[i].y;
- xMin = hb_min (xMin, x);
- xMax = hb_max (xMax, x);
- yMin = hb_min (yMin, y);
- yMax = hb_max (yMax, y);
- }
-
- update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
-
- int rounded_xMin = roundf (xMin);
- int rounded_xMax = roundf (xMax);
- int rounded_yMin = roundf (yMin);
- int rounded_yMax = roundf (yMax);
-
- if (type != EMPTY)
- {
- plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, rounded_xMin);
- plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, rounded_yMin);
- plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, rounded_xMax);
- plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, rounded_yMax);
- }
-
- /* when pinned at default, no need to compile glyph header
- * and for empty glyphs: all_points only include phantom points.
- * just update metrics and then return */
- if (!glyph_header)
- return true;
-
- glyph_header->numberOfContours = header->numberOfContours;
-
- glyph_header->xMin = rounded_xMin;
- glyph_header->yMin = rounded_yMin;
- glyph_header->xMax = rounded_xMax;
- glyph_header->yMax = rounded_yMax;
-
- dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
- return true;
- }
-
- bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
- hb_font_t *font,
- const glyf_accelerator_t &glyf,
- hb_bytes_t &dest_start, /* IN/OUT */
- hb_bytes_t &dest_end /* OUT */)
- {
- contour_point_vector_t all_points, points_with_deltas;
- unsigned composite_contours = 0;
- head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
- unsigned *composite_contours_p = &composite_contours;
-
- // don't compute head/maxp values when glyph has no contours(type is EMPTY)
- // also ignore .notdef glyph when --notdef-outline is not enabled
- if (type == EMPTY ||
- (gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)))
- {
- head_maxp_info_p = nullptr;
- composite_contours_p = nullptr;
- }
-
- if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false))
- return false;
-
- // .notdef, set type to empty so we only update metrics and don't compile bytes for
- // it
- if (gid == 0 &&
- !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
- {
- type = EMPTY;
- dest_start = hb_bytes_t ();
- dest_end = hb_bytes_t ();
- }
-
- //dont compile bytes when pinned at default, just recalculate bounds
- if (!plan->pinned_at_default)
- {
- switch (type)
- {
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE:
- // TODO
- dest_end = hb_bytes_t ();
- break;
-#endif
-
- case COMPOSITE:
- if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
- points_with_deltas,
- dest_end))
- return false;
- break;
- case SIMPLE:
- if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points,
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING,
- dest_end))
- return false;
- break;
- case EMPTY:
- /* set empty bytes for empty glyph
- * do not use source glyph's pointers */
- dest_start = hb_bytes_t ();
- dest_end = hb_bytes_t ();
- break;
- }
- }
-
- if (!compile_header_bytes (plan, all_points, dest_start))
- {
- dest_end.fini ();
- return false;
- }
- return true;
- }
-
-
- /* Note: Recursively calls itself.
- * all_points includes phantom points
- */
- template <typename accelerator_t>
- bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
- contour_point_vector_t &all_points /* OUT */,
- contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
- head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
- unsigned *composite_contours = nullptr, /* OUT */
- bool shift_points_hori = true,
- bool use_my_metrics = true,
- bool phantom_only = false,
- hb_array_t<int> coords = hb_array_t<int> (),
- unsigned int depth = 0,
- unsigned *edge_count = nullptr) const
- {
- if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
- unsigned stack_edge_count = 0;
- if (!edge_count) edge_count = &stack_edge_count;
- if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
- (*edge_count)++;
-
- if (head_maxp_info)
- {
- head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
- }
-
- if (!coords)
- coords = hb_array (font->coords, font->num_coords);
-
- contour_point_vector_t stack_points;
- bool inplace = type == SIMPLE && all_points.length == 0;
- /* Load into all_points if it's empty, as an optimization. */
- contour_point_vector_t &points = inplace ? all_points : stack_points;
-
- switch (type) {
- case SIMPLE:
- if (depth == 0 && head_maxp_info)
- head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
- if (depth > 0 && composite_contours)
- *composite_contours += (unsigned) header->numberOfContours;
- if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
- return false;
- break;
- case COMPOSITE:
- {
- for (auto &item : get_composite_iterator ())
- if (unlikely (!item.get_points (points))) return false;
- break;
- }
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE:
- {
- for (auto &item : get_var_composite_iterator ())
- if (unlikely (!item.get_points (points))) return false;
- }
-#endif
- case EMPTY:
- break;
- }
-
- /* Init phantom points */
- if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
- hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
- {
- int lsb = 0;
- int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
- (int) header->xMin - lsb : 0;
- HB_UNUSED int tsb = 0;
- int v_orig = (int) header->yMax +
-#ifndef HB_NO_VERTICAL
- ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
-#else
- 0
-#endif
- ;
- unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid);
- unsigned v_adv =
-#ifndef HB_NO_VERTICAL
- glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid)
-#else
- - font->face->get_upem ()
-#endif
- ;
- phantoms[PHANTOM_LEFT].x = h_delta;
- phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
- phantoms[PHANTOM_TOP].y = v_orig;
- phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
- }
-
-#ifndef HB_NO_VAR
- glyf_accelerator.gvar->apply_deltas_to_points (gid,
- coords,
- points.as_array ());
-#endif
-
- // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
- // with child glyphs' points
- if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
- {
- if (unlikely (!points_with_deltas->resize (points.length))) return false;
- points_with_deltas->copy_vector (points);
- }
-
- switch (type) {
- case SIMPLE:
- if (depth == 0 && head_maxp_info)
- head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4);
- if (!inplace)
- all_points.extend (points.as_array ());
- break;
- case COMPOSITE:
- {
- contour_point_vector_t comp_points;
- unsigned int comp_index = 0;
- for (auto &item : get_composite_iterator ())
- {
- comp_points.reset ();
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
- .get_points (font,
- glyf_accelerator,
- comp_points,
- points_with_deltas,
- head_maxp_info,
- composite_contours,
- shift_points_hori,
- use_my_metrics,
- phantom_only,
- coords,
- depth + 1,
- edge_count)))
- return false;
-
- /* Copy phantom points from component if USE_MY_METRICS flag set */
- if (use_my_metrics && item.is_use_my_metrics ())
- for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
- phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
-
- float matrix[4];
- contour_point_t default_trans;
- item.get_transformation (matrix, default_trans);
-
- /* Apply component transformation & translation (with deltas applied) */
- item.transform_points (comp_points, matrix, points[comp_index]);
-
- if (item.is_anchored ())
- {
- unsigned int p1, p2;
- item.get_anchor_points (p1, p2);
- if (likely (p1 < all_points.length && p2 < comp_points.length))
- {
- contour_point_t delta;
- delta.init (all_points[p1].x - comp_points[p2].x,
- all_points[p1].y - comp_points[p2].y);
-
- comp_points.translate (delta);
- }
- }
-
- all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
-
- if (all_points.length > HB_GLYF_MAX_POINTS)
- return false;
-
- comp_index++;
- }
-
- if (head_maxp_info && depth == 0)
- {
- if (composite_contours)
- head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours);
- head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length);
- head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index);
- }
- all_points.extend (phantoms);
- } break;
-#ifndef HB_NO_VAR_COMPOSITES
- case VAR_COMPOSITE:
- {
- contour_point_vector_t comp_points;
- hb_array_t<contour_point_t> points_left = points.as_array ();
- for (auto &item : get_var_composite_iterator ())
- {
- unsigned item_num_points = item.get_num_points ();
- hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
-
- comp_points.reset ();
-
- auto component_coords = coords;
- if (item.is_reset_unspecified_axes ())
- component_coords = hb_array<int> ();
-
- coord_setter_t coord_setter (component_coords);
- item.set_variations (coord_setter, record_points);
-
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
- .get_points (font,
- glyf_accelerator,
- comp_points,
- points_with_deltas,
- head_maxp_info,
- nullptr,
- shift_points_hori,
- use_my_metrics,
- phantom_only,
- coord_setter.get_coords (),
- depth + 1,
- edge_count)))
- return false;
-
- /* Apply component transformation */
- item.transform_points (record_points, comp_points);
-
- /* Copy phantom points from component if USE_MY_METRICS flag set */
- if (use_my_metrics && item.is_use_my_metrics ())
- for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
- phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
-
- all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
-
- if (all_points.length > HB_GLYF_MAX_POINTS)
- return false;
-
- points_left += item_num_points;
- }
- all_points.extend (phantoms);
- } break;
-#endif
- case EMPTY:
- all_points.extend (phantoms);
- break;
- }
-
- if (depth == 0 && shift_points_hori) /* Apply at top level */
- {
- /* Undocumented rasterizer behavior:
- * Shift points horizontally by the updated left side bearing
- */
- contour_point_t delta;
- delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
- if (delta.x) all_points.translate (delta);
- }
-
- return !all_points.in_error ();
- }
-
- bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
- hb_glyph_extents_t *extents) const
- {
- if (type == EMPTY) return true; /* Empty glyph; zero extents. */
- return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents);
- }
-
- hb_bytes_t get_bytes () const { return bytes; }
- glyph_type_t get_type () const { return type; }
- const GlyphHeader *get_header () const { return header; }
-
- Glyph () : bytes (),
- header (bytes.as<GlyphHeader> ()),
- gid (-1),
- type(EMPTY)
- {}
-
- Glyph (hb_bytes_t bytes_,
- hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_),
- header (bytes.as<GlyphHeader> ()),
- gid (gid_)
- {
- int num_contours = header->numberOfContours;
- if (unlikely (num_contours == 0)) type = EMPTY;
- else if (num_contours > 0) type = SIMPLE;
-#ifndef HB_NO_VAR_COMPOSITES
- else if (num_contours == -2) type = VAR_COMPOSITE;
-#endif
- else type = COMPOSITE; /* negative numbers */
- }
-
- protected:
- hb_bytes_t bytes;
- const GlyphHeader *header;
- hb_codepoint_t gid;
- glyph_type_t type;
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_GLYPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/GlyphHeader.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/GlyphHeader.hh
deleted file mode 100644
index a43b6691ab4..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/GlyphHeader.hh
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef OT_GLYF_GLYPHHEADER_HH
-#define OT_GLYF_GLYPHHEADER_HH
-
-
-#include "../../hb-open-type.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct GlyphHeader
-{
- bool has_data () const { return numberOfContours; }
-
- template <typename accelerator_t>
- bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
- hb_codepoint_t gid, hb_glyph_extents_t *extents) const
- {
- /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
- /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
- int lsb = hb_min (xMin, xMax);
- (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb);
- extents->x_bearing = lsb;
- extents->y_bearing = hb_max (yMin, yMax);
- extents->width = hb_max (xMin, xMax) - hb_min (xMin, xMax);
- extents->height = hb_min (yMin, yMax) - hb_max (yMin, yMax);
-
- font->scale_glyph_extents (extents);
-
- return true;
- }
-
- HBINT16 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. */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_GLYPHHEADER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh
deleted file mode 100644
index b6679b2dae8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh
+++ /dev/null
@@ -1,345 +0,0 @@
-#ifndef OT_GLYF_SIMPLEGLYPH_HH
-#define OT_GLYF_SIMPLEGLYPH_HH
-
-
-#include "../../hb-open-type.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct SimpleGlyph
-{
- enum simple_glyph_flag_t
- {
- FLAG_ON_CURVE = 0x01,
- FLAG_X_SHORT = 0x02,
- FLAG_Y_SHORT = 0x04,
- FLAG_REPEAT = 0x08,
- FLAG_X_SAME = 0x10,
- FLAG_Y_SAME = 0x20,
- FLAG_OVERLAP_SIMPLE = 0x40,
- FLAG_CUBIC = 0x80
- };
-
- const GlyphHeader &header;
- hb_bytes_t bytes;
- SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
- header (header_), bytes (bytes_) {}
-
- unsigned int instruction_len_offset () const
- { return GlyphHeader::static_size + 2 * header.numberOfContours; }
-
- unsigned int length (unsigned int instruction_len) const
- { return instruction_len_offset () + 2 + instruction_len; }
-
- bool has_instructions_length () const
- {
- return instruction_len_offset () + 2 <= bytes.length;
- }
-
- unsigned int instructions_length () const
- {
- unsigned int instruction_length_offset = instruction_len_offset ();
- if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;
-
- const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
- /* Out of bounds of the current glyph */
- if (unlikely (length (instructionLength) > bytes.length)) return 0;
- return instructionLength;
- }
-
- const hb_bytes_t trim_padding () const
- {
- /* based on FontTools _g_l_y_f.py::trim */
- const uint8_t *glyph = (uint8_t*) bytes.arrayZ;
- const uint8_t *glyph_end = glyph + bytes.length;
- /* simple glyph w/contours, possibly trimmable */
- glyph += instruction_len_offset ();
-
- if (unlikely (glyph + 2 >= glyph_end)) return hb_bytes_t ();
- unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
- unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
-
- glyph += 2 + num_instructions;
-
- unsigned int coord_bytes = 0;
- unsigned int coords_with_flags = 0;
- while (glyph < glyph_end)
- {
- uint8_t flag = *glyph;
- glyph++;
-
- unsigned int repeat = 1;
- if (flag & FLAG_REPEAT)
- {
- if (unlikely (glyph >= glyph_end)) return hb_bytes_t ();
- repeat = *glyph + 1;
- glyph++;
- }
-
- unsigned int xBytes, yBytes;
- xBytes = yBytes = 0;
- if (flag & FLAG_X_SHORT) xBytes = 1;
- else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
-
- if (flag & FLAG_Y_SHORT) yBytes = 1;
- else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
-
- coord_bytes += (xBytes + yBytes) * repeat;
- coords_with_flags += repeat;
- if (coords_with_flags >= num_coordinates) break;
- }
-
- if (unlikely (coords_with_flags != num_coordinates)) return hb_bytes_t ();
- return bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph));
- }
-
- /* zero instruction length */
- void drop_hints ()
- {
- if (!has_instructions_length ()) return;
- GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
- (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
- }
-
- void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
- {
- unsigned int instructions_len = instructions_length ();
- unsigned int glyph_length = length (instructions_len);
- dest_start = bytes.sub_array (0, glyph_length - instructions_len);
- dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
- }
-
- void set_overlaps_flag ()
- {
- if (unlikely (!header.numberOfContours)) return;
-
- unsigned flags_offset = length (instructions_length ());
- if (unlikely (flags_offset + 1 > bytes.length)) return;
-
- HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset);
- first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE;
- }
-
- static bool read_flags (const HBUINT8 *&p /* IN/OUT */,
- contour_point_vector_t &points_ /* IN/OUT */,
- const HBUINT8 *end)
- {
- unsigned count = points_.length;
- for (unsigned int i = 0; i < count;)
- {
- if (unlikely (p + 1 > end)) return false;
- uint8_t flag = *p++;
- points_.arrayZ[i++].flag = flag;
- if (flag & FLAG_REPEAT)
- {
- if (unlikely (p + 1 > end)) return false;
- unsigned int repeat_count = *p++;
- unsigned stop = hb_min (i + repeat_count, count);
- for (; i < stop; i++)
- points_.arrayZ[i].flag = flag;
- }
- }
- return true;
- }
-
- static bool read_points (const HBUINT8 *&p /* IN/OUT */,
- contour_point_vector_t &points_ /* IN/OUT */,
- const HBUINT8 *end,
- float contour_point_t::*m,
- const simple_glyph_flag_t short_flag,
- const simple_glyph_flag_t same_flag)
- {
- int v = 0;
-
- unsigned count = points_.length;
- for (unsigned i = 0; i < count; i++)
- {
- unsigned flag = points_[i].flag;
- if (flag & short_flag)
- {
- if (unlikely (p + 1 > end)) return false;
- if (flag & same_flag)
- v += *p++;
- else
- v -= *p++;
- }
- else
- {
- if (!(flag & same_flag))
- {
- if (unlikely (p + HBINT16::static_size > end)) return false;
- v += *(const HBINT16 *) p;
- p += HBINT16::static_size;
- }
- }
- points_.arrayZ[i].*m = v;
- }
- return true;
- }
-
- bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
- bool phantom_only = false) const
- {
- const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
- int num_contours = header.numberOfContours;
- assert (num_contours);
- /* One extra item at the end, for the instruction-count below. */
- if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
- unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
-
- points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
- if (!points_.resize (num_points)) return false;
- if (phantom_only) return true;
-
- for (int i = 0; i < num_contours; i++)
- points_[endPtsOfContours[i]].is_end_point = true;
-
- /* Skip instructions */
- const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
- endPtsOfContours[num_contours]);
-
- if (unlikely ((const char *) p < bytes.arrayZ)) return false; /* Unlikely overflow */
- const HBUINT8 *end = (const HBUINT8 *) (bytes.arrayZ + bytes.length);
- if (unlikely (p >= end)) return false;
-
- /* Read x & y coordinates */
- return read_flags (p, points_, end)
- && read_points (p, points_, end, &contour_point_t::x,
- FLAG_X_SHORT, FLAG_X_SAME)
- && read_points (p, points_, end, &contour_point_t::y,
- FLAG_Y_SHORT, FLAG_Y_SAME);
- }
-
- static void encode_coord (int value,
- uint8_t &flag,
- const simple_glyph_flag_t short_flag,
- const simple_glyph_flag_t same_flag,
- hb_vector_t<uint8_t> &coords /* OUT */)
- {
- if (value == 0)
- {
- flag |= same_flag;
- }
- else if (value >= -255 && value <= 255)
- {
- flag |= short_flag;
- if (value > 0) flag |= same_flag;
- else value = -value;
-
- coords.arrayZ[coords.length++] = (uint8_t) value;
- }
- else
- {
- int16_t val = value;
- coords.arrayZ[coords.length++] = val >> 8;
- coords.arrayZ[coords.length++] = val & 0xff;
- }
- }
-
- static void encode_flag (uint8_t &flag,
- uint8_t &repeat,
- uint8_t lastflag,
- hb_vector_t<uint8_t> &flags /* OUT */)
- {
- if (flag == lastflag && repeat != 255)
- {
- repeat++;
- if (repeat == 1)
- {
- /* We know there's room. */
- flags.arrayZ[flags.length++] = flag;
- }
- else
- {
- unsigned len = flags.length;
- flags.arrayZ[len-2] = flag | FLAG_REPEAT;
- flags.arrayZ[len-1] = repeat;
- }
- }
- else
- {
- repeat = 0;
- flags.push (flag);
- }
- }
-
- bool compile_bytes_with_deltas (const contour_point_vector_t &all_points,
- bool no_hinting,
- hb_bytes_t &dest_bytes /* OUT */)
- {
- if (header.numberOfContours == 0 || all_points.length <= 4)
- {
- dest_bytes = hb_bytes_t ();
- return true;
- }
- unsigned num_points = all_points.length - 4;
-
- hb_vector_t<uint8_t> flags, x_coords, y_coords;
- if (unlikely (!flags.alloc (num_points, true))) return false;
- if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
- if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
-
- uint8_t lastflag = 255, repeat = 0;
- int prev_x = 0, prev_y = 0;
-
- for (unsigned i = 0; i < num_points; i++)
- {
- uint8_t flag = all_points.arrayZ[i].flag;
- flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
-
- int cur_x = roundf (all_points.arrayZ[i].x);
- int cur_y = roundf (all_points.arrayZ[i].y);
- encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
- encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
- encode_flag (flag, repeat, lastflag, flags);
-
- prev_x = cur_x;
- prev_y = cur_y;
- lastflag = flag;
- }
-
- unsigned len_before_instrs = 2 * header.numberOfContours + 2;
- unsigned len_instrs = instructions_length ();
- unsigned total_len = len_before_instrs + flags.length + x_coords.length + y_coords.length;
-
- if (!no_hinting)
- total_len += len_instrs;
-
- char *p = (char *) hb_malloc (total_len);
- if (unlikely (!p)) return false;
-
- const char *src = bytes.arrayZ + GlyphHeader::static_size;
- char *cur = p;
- hb_memcpy (p, src, len_before_instrs);
-
- cur += len_before_instrs;
- src += len_before_instrs;
-
- if (!no_hinting)
- {
- hb_memcpy (cur, src, len_instrs);
- cur += len_instrs;
- }
-
- hb_memcpy (cur, flags.arrayZ, flags.length);
- cur += flags.length;
-
- hb_memcpy (cur, x_coords.arrayZ, x_coords.length);
- cur += x_coords.length;
-
- hb_memcpy (cur, y_coords.arrayZ, y_coords.length);
-
- dest_bytes = hb_bytes_t (p, total_len);
- return true;
- }
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_SIMPLEGLYPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SubsetGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/SubsetGlyph.hh
deleted file mode 100644
index 26dc374eab6..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SubsetGlyph.hh
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef OT_GLYF_SUBSETGLYPH_HH
-#define OT_GLYF_SUBSETGLYPH_HH
-
-
-#include "../../hb-open-type.hh"
-
-
-namespace OT {
-
-struct glyf_accelerator_t;
-
-namespace glyf_impl {
-
-
-struct SubsetGlyph
-{
- hb_codepoint_t old_gid;
- Glyph source_glyph;
- hb_bytes_t dest_start; /* region of source_glyph to copy first */
- hb_bytes_t dest_end; /* region of source_glyph to copy second */
- bool allocated;
-
- bool serialize (hb_serialize_context_t *c,
- bool use_short_loca,
- const hb_subset_plan_t *plan)
- {
- TRACE_SERIALIZE (this);
-
- hb_bytes_t dest_glyph = dest_start.copy (c);
- hb_bytes_t end_copy = dest_end.copy (c);
- if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
- return false;
- }
-
- dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
- unsigned int pad_length = use_short_loca ? padding () : 0;
- DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
-
- HBUINT8 pad;
- pad = 0;
- while (pad_length > 0)
- {
- c->embed (pad);
- pad_length--;
- }
-
- if (unlikely (!dest_glyph.length)) return_trace (true);
-
- /* update components gids. */
- for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
- {
- hb_codepoint_t new_gid;
- if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
- const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
- }
-#ifndef HB_NO_VAR_COMPOSITES
- for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ())
- {
- hb_codepoint_t new_gid;
- if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
- const_cast<VarCompositeGlyphRecord &> (_).set_gid (new_gid);
- }
-#endif
-
-#ifndef HB_NO_BEYOND_64K
- auto it = Glyph (dest_glyph).get_composite_iterator ();
- if (it)
- {
- /* lower GID24 to GID16 in components if possible.
- *
- * TODO: VarComposite. Not as critical, since VarComposite supports
- * gid24 from the first version. */
- char *p = it ? (char *) &*it : nullptr;
- char *q = p;
- const char *end = dest_glyph.arrayZ + dest_glyph.length;
- while (it)
- {
- auto &rec = const_cast<CompositeGlyphRecord &> (*it);
- ++it;
-
- q += rec.get_size ();
-
- rec.lower_gid_24_to_16 ();
-
- unsigned size = rec.get_size ();
-
- memmove (p, &rec, size);
-
- p += size;
- }
- memmove (p, q, end - q);
- p += end - q;
-
- /* We want to shorten the glyph, but we can't do that without
- * updating the length in the loca table, which is already
- * written out :-(. So we just fill the rest of the glyph with
- * harmless instructions, since that's what they will be
- * interpreted as.
- *
- * Should move the lowering to _populate_subset_glyphs() to
- * fix this issue. */
-
- hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
- p += end - p;
- dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);
-
- // TODO: Padding; & trim serialized bytes.
- // TODO: Update length in loca. Ugh.
- }
-#endif
-
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- Glyph (dest_glyph).drop_hints ();
-
- if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
- Glyph (dest_glyph).set_overlaps_flag ();
-
- return_trace (true);
- }
-
- bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
- hb_font_t *font,
- const glyf_accelerator_t &glyf)
- {
- allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
- return allocated;
- }
-
- void free_compiled_bytes ()
- {
- if (likely (allocated)) {
- allocated = false;
- dest_start.fini ();
- dest_end.fini ();
- }
- }
-
- void drop_hints_bytes ()
- { source_glyph.drop_hints_bytes (dest_start, dest_end); }
-
- unsigned int length () const { return dest_start.length + dest_end.length; }
- /* pad to 2 to ensure 2-byte loca will be ok */
- unsigned int padding () const { return length () % 2; }
- unsigned int padded_size () const { return length () + padding (); }
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_SUBSETGLYPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh
deleted file mode 100644
index 309ec473aa2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh
+++ /dev/null
@@ -1,371 +0,0 @@
-#ifndef OT_GLYF_VARCOMPOSITEGLYPH_HH
-#define OT_GLYF_VARCOMPOSITEGLYPH_HH
-
-
-#include "../../hb-open-type.hh"
-#include "coord-setter.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct VarCompositeGlyphRecord
-{
- protected:
- enum var_composite_glyph_flag_t
- {
- USE_MY_METRICS = 0x0001,
- AXIS_INDICES_ARE_SHORT = 0x0002,
- UNIFORM_SCALE = 0x0004,
- HAVE_TRANSLATE_X = 0x0008,
- HAVE_TRANSLATE_Y = 0x0010,
- HAVE_ROTATION = 0x0020,
- HAVE_SCALE_X = 0x0040,
- HAVE_SCALE_Y = 0x0080,
- HAVE_SKEW_X = 0x0100,
- HAVE_SKEW_Y = 0x0200,
- HAVE_TCENTER_X = 0x0400,
- HAVE_TCENTER_Y = 0x0800,
- GID_IS_24BIT = 0x1000,
- AXES_HAVE_VARIATION = 0x2000,
- RESET_UNSPECIFIED_AXES = 0x4000,
- };
-
- public:
-
- unsigned int get_size () const
- {
- unsigned int size = min_size;
-
- unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
- size += numAxes * axis_width;
-
- // gid
- size += 2;
- if (flags & GID_IS_24BIT) size += 1;
-
- if (flags & HAVE_TRANSLATE_X) size += 2;
- if (flags & HAVE_TRANSLATE_Y) size += 2;
- if (flags & HAVE_ROTATION) size += 2;
- if (flags & HAVE_SCALE_X) size += 2;
- if (flags & HAVE_SCALE_Y) size += 2;
- if (flags & HAVE_SKEW_X) size += 2;
- if (flags & HAVE_SKEW_Y) size += 2;
- if (flags & HAVE_TCENTER_X) size += 2;
- if (flags & HAVE_TCENTER_Y) size += 2;
-
- return size;
- }
-
- bool has_more () const { return true; }
-
- bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
- bool is_reset_unspecified_axes () const { return flags & RESET_UNSPECIFIED_AXES; }
-
- hb_codepoint_t get_gid () const
- {
- if (flags & GID_IS_24BIT)
- return StructAfter<const HBGlyphID24> (numAxes);
- else
- return StructAfter<const HBGlyphID16> (numAxes);
- }
-
- void set_gid (hb_codepoint_t gid)
- {
- if (flags & GID_IS_24BIT)
- StructAfter<HBGlyphID24> (numAxes) = gid;
- else
- StructAfter<HBGlyphID16> (numAxes) = gid;
- }
-
- unsigned get_numAxes () const
- {
- return numAxes;
- }
-
- unsigned get_num_points () const
- {
- unsigned num = 0;
- if (flags & AXES_HAVE_VARIATION) num += numAxes;
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++;
- if (flags & HAVE_ROTATION) num++;
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++;
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++;
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++;
- return num;
- }
-
- void transform_points (hb_array_t<contour_point_t> record_points,
- contour_point_vector_t &points) const
- {
- float matrix[4];
- contour_point_t trans;
-
- get_transformation_from_points (record_points, matrix, trans);
-
- points.transform (matrix);
- points.translate (trans);
- }
-
- static inline void transform (float (&matrix)[4], contour_point_t &trans,
- float (other)[6])
- {
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268
- float xx1 = other[0];
- float xy1 = other[1];
- float yx1 = other[2];
- float yy1 = other[3];
- float dx1 = other[4];
- float dy1 = other[5];
- float xx2 = matrix[0];
- float xy2 = matrix[1];
- float yx2 = matrix[2];
- float yy2 = matrix[3];
- float dx2 = trans.x;
- float dy2 = trans.y;
-
- matrix[0] = xx1*xx2 + xy1*yx2;
- matrix[1] = xx1*xy2 + xy1*yy2;
- matrix[2] = yx1*xx2 + yy1*yx2;
- matrix[3] = yx1*xy2 + yy1*yy2;
- trans.x = xx2*dx1 + yx2*dy1 + dx2;
- trans.y = xy2*dx1 + yy2*dy1 + dy2;
- }
-
- static void translate (float (&matrix)[4], contour_point_t &trans,
- float translateX, float translateY)
- {
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
- float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
- transform (matrix, trans, other);
- }
-
- static void scale (float (&matrix)[4], contour_point_t &trans,
- float scaleX, float scaleY)
- {
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
- float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
- transform (matrix, trans, other);
- }
-
- static void rotate (float (&matrix)[4], contour_point_t &trans,
- float rotation)
- {
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
- rotation = rotation * HB_PI;
- float c = cosf (rotation);
- float s = sinf (rotation);
- float other[6] = {c, s, -s, c, 0.f, 0.f};
- transform (matrix, trans, other);
- }
-
- static void skew (float (&matrix)[4], contour_point_t &trans,
- float skewX, float skewY)
- {
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
- skewX = skewX * HB_PI;
- skewY = skewY * HB_PI;
- float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
- transform (matrix, trans, other);
- }
-
- bool get_points (contour_point_vector_t &points) const
- {
- float translateX = 0.f;
- float translateY = 0.f;
- float rotation = 0.f;
- float scaleX = 1.f * (1 << 10);
- float scaleY = 1.f * (1 << 10);
- float skewX = 0.f;
- float skewY = 0.f;
- float tCenterX = 0.f;
- float tCenterY = 0.f;
-
- unsigned num_points = get_num_points ();
-
- if (unlikely (!points.resize (points.length + num_points))) return false;
-
- unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
- unsigned axes_size = numAxes * axis_width;
-
- const F2DOT14 *q = (const F2DOT14 *) (axes_size +
- (flags & GID_IS_24BIT ? 3 : 2) +
- &StructAfter<const HBUINT8> (numAxes));
-
- hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - num_points);
-
- unsigned count = numAxes;
- if (flags & AXES_HAVE_VARIATION)
- {
- for (unsigned i = 0; i < count; i++)
- rec_points[i].x = q++->to_int ();
- rec_points += count;
- }
- else
- q += count;
-
- const HBUINT16 *p = (const HBUINT16 *) q;
-
- if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++;
- if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++;
- if (flags & HAVE_ROTATION) rotation = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_SCALE_X) scaleX = ((const F6DOT10 *) p++)->to_int ();
- if (flags & HAVE_SCALE_Y) scaleY = ((const F6DOT10 *) p++)->to_int ();
- if (flags & HAVE_SKEW_X) skewX = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_SKEW_Y) skewY = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++;
- if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++;
-
- if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
- scaleY = scaleX;
-
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
- {
- rec_points[0].x = translateX;
- rec_points[0].y = translateY;
- rec_points++;
- }
- if (flags & HAVE_ROTATION)
- {
- rec_points[0].x = rotation;
- rec_points++;
- }
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
- {
- rec_points[0].x = scaleX;
- rec_points[0].y = scaleY;
- rec_points++;
- }
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
- {
- rec_points[0].x = skewX;
- rec_points[0].y = skewY;
- rec_points++;
- }
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
- {
- rec_points[0].x = tCenterX;
- rec_points[0].y = tCenterY;
- rec_points++;
- }
- assert (!rec_points);
-
- return true;
- }
-
- void get_transformation_from_points (hb_array_t<contour_point_t> rec_points,
- float (&matrix)[4], contour_point_t &trans) const
- {
- if (flags & AXES_HAVE_VARIATION)
- rec_points += numAxes;
-
- matrix[0] = matrix[3] = 1.f;
- matrix[1] = matrix[2] = 0.f;
- trans.init (0.f, 0.f);
-
- float translateX = 0.f;
- float translateY = 0.f;
- float rotation = 0.f;
- float scaleX = 1.f;
- float scaleY = 1.f;
- float skewX = 0.f;
- float skewY = 0.f;
- float tCenterX = 0.f;
- float tCenterY = 0.f;
-
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
- {
- translateX = rec_points[0].x;
- translateY = rec_points[0].y;
- rec_points++;
- }
- if (flags & HAVE_ROTATION)
- {
- rotation = rec_points[0].x / (1 << 12);
- rec_points++;
- }
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
- {
- scaleX = rec_points[0].x / (1 << 10);
- scaleY = rec_points[0].y / (1 << 10);
- rec_points++;
- }
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
- {
- skewX = rec_points[0].x / (1 << 12);
- skewY = rec_points[0].y / (1 << 12);
- rec_points++;
- }
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
- {
- tCenterX = rec_points[0].x;
- tCenterY = rec_points[0].y;
- rec_points++;
- }
- assert (!rec_points);
-
- translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
- rotate (matrix, trans, rotation);
- scale (matrix, trans, scaleX, scaleY);
- skew (matrix, trans, -skewX, skewY);
- translate (matrix, trans, -tCenterX, -tCenterY);
- }
-
- void set_variations (coord_setter_t &setter,
- hb_array_t<contour_point_t> rec_points) const
- {
- bool have_variations = flags & AXES_HAVE_VARIATION;
- unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
-
- const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
- const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
-
- const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
-
- unsigned count = numAxes;
- for (unsigned i = 0; i < count; i++)
- {
- unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
-
- signed v = have_variations ? rec_points[i].x : a++->to_int ();
-
- v = hb_clamp (v, -(1<<14), (1<<14));
- setter[axis_index] = v;
- }
- }
-
- protected:
- HBUINT16 flags;
- HBUINT8 numAxes;
- public:
- DEFINE_SIZE_MIN (3);
-};
-
-using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
-
-struct VarCompositeGlyph
-{
- const GlyphHeader &header;
- hb_bytes_t bytes;
- VarCompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
- header (header_), bytes (bytes_) {}
-
- var_composite_iter_t iter () const
- { return var_composite_iter_t (bytes, &StructAfter<VarCompositeGlyphRecord, GlyphHeader> (header)); }
-
- const hb_bytes_t trim_padding () const
- {
- unsigned length = GlyphHeader::static_size;
- for (auto &comp : iter ())
- length += comp.get_size ();
- return bytes.sub_array (0, length);
- }
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_VARCOMPOSITEGLYPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/composite-iter.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/composite-iter.hh
deleted file mode 100644
index d05701f3d1e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/composite-iter.hh
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef OT_GLYF_COMPOSITE_ITER_HH
-#define OT_GLYF_COMPOSITE_ITER_HH
-
-
-#include "../../hb.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-template <typename CompositeGlyphRecord>
-struct composite_iter_tmpl : hb_iter_with_fallback_t<composite_iter_tmpl<CompositeGlyphRecord>,
- const CompositeGlyphRecord &>
-{
- typedef const CompositeGlyphRecord *__item_t__;
- composite_iter_tmpl (hb_bytes_t glyph_, __item_t__ current_) :
- glyph (glyph_), current (nullptr), current_size (0)
- {
- set_current (current_);
- }
-
- composite_iter_tmpl () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {}
-
- const CompositeGlyphRecord & __item__ () const { return *current; }
- bool __more__ () const { return current; }
- void __next__ ()
- {
- if (!current->has_more ()) { current = nullptr; return; }
-
- set_current (&StructAtOffset<CompositeGlyphRecord> (current, current_size));
- }
- composite_iter_tmpl __end__ () const { return composite_iter_tmpl (); }
- bool operator != (const composite_iter_tmpl& o) const
- { return current != o.current; }
-
-
- void set_current (__item_t__ current_)
- {
- if (!glyph.check_range (current_, CompositeGlyphRecord::min_size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
- unsigned size = current_->get_size ();
- if (!glyph.check_range (current_, size))
- {
- current = nullptr;
- current_size = 0;
- return;
- }
-
- current = current_;
- current_size = size;
- }
-
- private:
- hb_bytes_t glyph;
- __item_t__ current;
- unsigned current_size;
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-#endif /* OT_GLYF_COMPOSITE_ITER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/coord-setter.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/coord-setter.hh
deleted file mode 100644
index df64ed5af7d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/coord-setter.hh
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef OT_GLYF_COORD_SETTER_HH
-#define OT_GLYF_COORD_SETTER_HH
-
-
-#include "../../hb.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct coord_setter_t
-{
- coord_setter_t (hb_array_t<int> coords) :
- coords (coords) {}
-
- int& operator [] (unsigned idx)
- {
- if (coords.length < idx + 1)
- coords.resize (idx + 1);
- return coords[idx];
- }
-
- hb_array_t<int> get_coords ()
- { return coords.as_array (); }
-
- hb_vector_t<int> coords;
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-#endif /* OT_GLYF_COORD_SETTER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh
deleted file mode 100644
index 30106b2b98b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf-helpers.hh
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef OT_GLYF_GLYF_HELPERS_HH
-#define OT_GLYF_GLYF_HELPERS_HH
-
-
-#include "../../hb-open-type.hh"
-#include "../../hb-subset-plan.hh"
-
-#include "loca.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-template<typename IteratorIn, typename IteratorOut,
- hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
- hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
-static void
-_write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest)
-{
- unsigned right_shift = short_offsets ? 1 : 0;
- unsigned int offset = 0;
- dest << 0;
- + it
- | hb_map ([=, &offset] (unsigned int padded_size)
- {
- offset += padded_size;
- DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset);
- return offset >> right_shift;
- })
- | hb_sink (dest)
- ;
-}
-
-static bool
-_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
-{
- hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
- hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
- hb_blob_destroy (head_blob);
-
- if (unlikely (!head_prime_blob))
- return false;
-
- head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
- head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
- if (plan->normalized_coords)
- {
- head_prime->xMin = plan->head_maxp_info.xMin;
- head_prime->xMax = plan->head_maxp_info.xMax;
- head_prime->yMin = plan->head_maxp_info.yMin;
- head_prime->yMax = plan->head_maxp_info.yMax;
-
- unsigned orig_flag = head_prime->flags;
- if (plan->head_maxp_info.allXMinIsLsb)
- orig_flag |= 1 << 1;
- else
- orig_flag &= ~(1 << 1);
- head_prime->flags = orig_flag;
- }
- bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
-
- hb_blob_destroy (head_prime_blob);
- return success;
-}
-
-template<typename Iterator,
- hb_requires (hb_is_source_of (Iterator, unsigned int))>
-static bool
-_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
-{
- unsigned num_offsets = padded_offsets.len () + 1;
- unsigned entry_size = use_short_loca ? 2 : 4;
- char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
-
- if (unlikely (!loca_prime_data)) return false;
-
- DEBUG_MSG (SUBSET, nullptr, "loca entry_size %u num_offsets %u size %u",
- entry_size, num_offsets, entry_size * num_offsets);
-
- if (use_short_loca)
- _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
- else
- _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
-
- hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
- entry_size * num_offsets,
- HB_MEMORY_MODE_WRITABLE,
- loca_prime_data,
- hb_free);
-
- bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
- && _add_head_and_set_loca_version (plan, use_short_loca);
-
- hb_blob_destroy (loca_blob);
- return result;
-}
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_GLYF_HELPERS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh
deleted file mode 100644
index dd08dda6ee1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh
+++ /dev/null
@@ -1,504 +0,0 @@
-#ifndef OT_GLYF_GLYF_HH
-#define OT_GLYF_GLYF_HH
-
-
-#include "../../hb-open-type.hh"
-#include "../../hb-ot-head-table.hh"
-#include "../../hb-ot-hmtx-table.hh"
-#include "../../hb-ot-var-gvar-table.hh"
-#include "../../hb-draw.hh"
-#include "../../hb-paint.hh"
-
-#include "glyf-helpers.hh"
-#include "Glyph.hh"
-#include "SubsetGlyph.hh"
-#include "loca.hh"
-#include "path-builder.hh"
-
-
-namespace OT {
-
-
-/*
- * glyf -- TrueType Glyph Data
- * https://docs.microsoft.com/en-us/typography/opentype/spec/glyf
- */
-#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
-
-struct glyf
-{
- friend struct glyf_accelerator_t;
-
- static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
-
- static bool has_valid_glyf_format(const hb_face_t* face)
- {
- const OT::head &head = *face->table.head;
- return head.indexToLocFormat <= 1 && head.glyphDataFormat <= 1;
- }
-
- bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
- {
- TRACE_SANITIZE (this);
- /* Runtime checks as eager sanitizing each glyph is costy */
- return_trace (true);
- }
-
- /* requires source of SubsetGlyph complains the identifier isn't declared */
- template <typename Iterator>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- bool use_short_loca,
- const hb_subset_plan_t *plan)
- {
- TRACE_SERIALIZE (this);
-
- unsigned init_len = c->length ();
- for (auto &_ : it)
- if (unlikely (!_.serialize (c, use_short_loca, plan)))
- return false;
-
- /* As a special case when all glyph in the font are empty, add a zero byte
- * to the table, so that OTS doesn’t reject it, and to make the table work
- * on Windows as well.
- * See https://github.com/khaledhosny/ots/issues/52 */
- if (init_len == c->length ())
- {
- HBUINT8 empty_byte;
- empty_byte = 0;
- c->copy (empty_byte);
- }
- return_trace (true);
- }
-
- /* Byte region(s) per glyph to output
- unpadded, hints removed if so requested
- If we fail to process a glyph we produce an empty (0-length) glyph */
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- if (!has_valid_glyf_format (c->plan->source)) {
- // glyf format is unknown don't attempt to subset it.
- DEBUG_MSG (SUBSET, nullptr,
- "unkown glyf format, dropping from subset.");
- return_trace (false);
- }
-
- glyf *glyf_prime = c->serializer->start_embed <glyf> ();
- if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
-
- hb_font_t *font = nullptr;
- if (c->plan->normalized_coords)
- {
- font = _create_font_for_instancing (c->plan);
- if (unlikely (!font)) return false;
- }
-
- hb_vector_t<unsigned> padded_offsets;
- unsigned num_glyphs = c->plan->num_output_glyphs ();
- if (unlikely (!padded_offsets.resize (num_glyphs)))
- {
- hb_font_destroy (font);
- return false;
- }
-
- hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
- if (!_populate_subset_glyphs (c->plan, font, glyphs))
- {
- hb_font_destroy (font);
- return false;
- }
-
- if (font)
- hb_font_destroy (font);
-
- unsigned max_offset = 0;
- for (unsigned i = 0; i < num_glyphs; i++)
- {
- padded_offsets[i] = glyphs[i].padded_size ();
- max_offset += padded_offsets[i];
- }
-
- bool use_short_loca = false;
- if (likely (!c->plan->force_long_loca))
- use_short_loca = max_offset < 0x1FFFF;
-
- if (!use_short_loca) {
- for (unsigned i = 0; i < num_glyphs; i++)
- padded_offsets[i] = glyphs[i].length ();
- }
-
- bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
- if (c->plan->normalized_coords && !c->plan->pinned_at_default)
- _free_compiled_subset_glyphs (glyphs);
-
- if (!result) return false;
-
- if (unlikely (c->serializer->in_error ())) return_trace (false);
-
- return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
- padded_offsets.iter (),
- use_short_loca)));
- }
-
- bool
- _populate_subset_glyphs (const hb_subset_plan_t *plan,
- hb_font_t *font,
- hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
-
- hb_font_t *
- _create_font_for_instancing (const hb_subset_plan_t *plan) const;
-
- void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs) const
- {
- for (unsigned i = 0; i < glyphs.length; i++)
- glyphs[i].free_compiled_bytes ();
- }
-
- protected:
- UnsizedArrayOf<HBUINT8>
- dataZ; /* Glyphs data. */
- public:
- DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
- * check the size externally, allow Null() object of it by
- * defining it _MIN instead. */
-};
-
-struct glyf_accelerator_t
-{
- glyf_accelerator_t (hb_face_t *face)
- {
- short_offset = false;
- num_glyphs = 0;
- loca_table = nullptr;
- glyf_table = nullptr;
-#ifndef HB_NO_VAR
- gvar = nullptr;
-#endif
- hmtx = nullptr;
-#ifndef HB_NO_VERTICAL
- vmtx = nullptr;
-#endif
- const OT::head &head = *face->table.head;
- if (!glyf::has_valid_glyf_format (face))
- /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
- return;
- short_offset = 0 == head.indexToLocFormat;
-
- loca_table = face->table.loca.get_blob (); // Needs no destruct!
- glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
-#ifndef HB_NO_VAR
- gvar = face->table.gvar;
-#endif
- hmtx = face->table.hmtx;
-#ifndef HB_NO_VERTICAL
- vmtx = face->table.vmtx;
-#endif
-
- num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
- num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
- }
- ~glyf_accelerator_t ()
- {
- glyf_table.destroy ();
- }
-
- bool has_data () const { return num_glyphs; }
-
- protected:
- template<typename T>
- bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer) const
- {
- if (gid >= num_glyphs) return false;
-
- /* Making this allocfree is not that easy
- https://github.com/harfbuzz/harfbuzz/issues/2095
- mostly because of gvar handling in VF fonts,
- perhaps a separate path for non-VF fonts can be considered */
- contour_point_vector_t all_points;
-
- bool phantom_only = !consumer.is_consuming_contour_points ();
- if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only)))
- return false;
-
- if (consumer.is_consuming_contour_points ())
- {
- unsigned count = all_points.length;
- assert (count >= glyf_impl::PHANTOM_COUNT);
- count -= glyf_impl::PHANTOM_COUNT;
- for (unsigned point_index = 0; point_index < count; point_index++)
- consumer.consume_point (all_points[point_index]);
- consumer.points_end ();
- }
-
- /* Where to write phantoms, nullptr if not requested */
- contour_point_t *phantoms = consumer.get_phantoms_sink ();
- if (phantoms)
- for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i)
- phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i];
-
- return true;
- }
-
- public:
-
-#ifndef HB_NO_VAR
- struct points_aggregator_t
- {
- hb_font_t *font;
- hb_glyph_extents_t *extents;
- contour_point_t *phantoms;
- bool scaled;
-
- struct contour_bounds_t
- {
- contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
-
- void add (const contour_point_t &p)
- {
- min_x = hb_min (min_x, p.x);
- min_y = hb_min (min_y, p.y);
- max_x = hb_max (max_x, p.x);
- max_y = hb_max (max_y, p.y);
- }
-
- bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
-
- void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scaled)
- {
- if (unlikely (empty ()))
- {
- extents->width = 0;
- extents->x_bearing = 0;
- extents->height = 0;
- extents->y_bearing = 0;
- return;
- }
- {
- extents->x_bearing = roundf (min_x);
- extents->width = roundf (max_x - extents->x_bearing);
- extents->y_bearing = roundf (max_y);
- extents->height = roundf (min_y - extents->y_bearing);
-
- if (scaled)
- font->scale_glyph_extents (extents);
- }
- }
-
- protected:
- float min_x, min_y, max_x, max_y;
- } bounds;
-
- points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_, bool scaled_)
- {
- font = font_;
- extents = extents_;
- phantoms = phantoms_;
- scaled = scaled_;
- if (extents) bounds = contour_bounds_t ();
- }
-
- void consume_point (const contour_point_t &point) { bounds.add (point); }
- void points_end () { bounds.get_extents (font, extents, scaled); }
-
- bool is_consuming_contour_points () { return extents; }
- contour_point_t *get_phantoms_sink () { return phantoms; }
- };
-
- unsigned
- get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
- {
- if (unlikely (gid >= num_glyphs)) return 0;
-
- bool success = false;
-
- contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
- if (font->num_coords)
- success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false));
-
- if (unlikely (!success))
- return
-#ifndef HB_NO_VERTICAL
- is_vertical ? vmtx->get_advance_without_var_unscaled (gid) :
-#endif
- hmtx->get_advance_without_var_unscaled (gid);
-
- float result = is_vertical
- ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y
- : phantoms[glyf_impl::PHANTOM_RIGHT].x - phantoms[glyf_impl::PHANTOM_LEFT].x;
- return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2);
- }
-
- bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const
- {
- if (unlikely (gid >= num_glyphs)) return false;
-
- hb_glyph_extents_t extents;
-
- contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
- if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false))))
- return false;
-
- *lsb = is_vertical
- ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing
- : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x);
- return true;
- }
-#endif
-
- bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const
- {
- if (unlikely (gid >= num_glyphs)) return false;
- if (is_vertical) return false; // TODO Humm, what to do here?
-
- *lsb = glyph_for_gid (gid).get_header ()->xMin;
- return true;
- }
-
- public:
- bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
- {
- if (unlikely (gid >= num_glyphs)) return false;
-
-#ifndef HB_NO_VAR
- if (font->num_coords)
- return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true));
-#endif
- return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents);
- }
-
- bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
- {
- funcs->push_clip_glyph (data, gid, font);
- funcs->color (data, true, foreground);
- funcs->pop_clip (data);
-
- return true;
- }
-
- const glyf_impl::Glyph
- glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
- {
- if (unlikely (gid >= num_glyphs)) return glyf_impl::Glyph ();
-
- unsigned int start_offset, end_offset;
-
- if (short_offset)
- {
- const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
- start_offset = 2 * offsets[gid];
- end_offset = 2 * offsets[gid + 1];
- }
- else
- {
- const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
- start_offset = offsets[gid];
- end_offset = offsets[gid + 1];
- }
-
- if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
- return glyf_impl::Glyph ();
-
- glyf_impl::Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
- end_offset - start_offset), gid);
- return needs_padding_removal ? glyf_impl::Glyph (glyph.trim_padding (), gid) : glyph;
- }
-
- bool
- get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const
- { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); }
-
-#ifndef HB_NO_VAR
- const gvar_accelerator_t *gvar;
-#endif
- const hmtx_accelerator_t *hmtx;
-#ifndef HB_NO_VERTICAL
- const vmtx_accelerator_t *vmtx;
-#endif
-
- private:
- bool short_offset;
- unsigned int num_glyphs;
- hb_blob_ptr_t<loca> loca_table;
- hb_blob_ptr_t<glyf> glyf_table;
-};
-
-
-inline bool
-glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
- hb_font_t *font,
- hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
-{
- OT::glyf_accelerator_t glyf (plan->source);
- unsigned num_glyphs = plan->num_output_glyphs ();
- if (!glyphs.resize (num_glyphs)) return false;
-
- for (auto p : plan->glyph_map->iter ())
- {
- unsigned new_gid = p.second;
- glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
- subset_glyph.old_gid = p.first;
-
- if (unlikely (new_gid == 0 &&
- !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
- !plan->normalized_coords)
- subset_glyph.source_glyph = glyf_impl::Glyph ();
- else
- {
- /* If plan has an accelerator, the preprocessing step already trimmed glyphs.
- * Don't trim them again! */
- subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, !plan->accelerator);
- }
-
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- subset_glyph.drop_hints_bytes ();
- else
- subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
-
- if (font)
- {
- if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf)))
- {
- // when pinned at default, only bounds are updated, thus no need to free
- if (!plan->pinned_at_default)
- _free_compiled_subset_glyphs (glyphs);
- return false;
- }
- }
- }
- return true;
-}
-
-inline hb_font_t *
-glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const
-{
- hb_font_t *font = hb_font_create (plan->source);
- if (unlikely (font == hb_font_get_empty ())) return nullptr;
-
- hb_vector_t<hb_variation_t> vars;
- if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true)))
- {
- hb_font_destroy (font);
- return nullptr;
- }
-
- for (auto _ : plan->user_axes_location)
- {
- hb_variation_t var;
- var.tag = _.first;
- var.value = _.second;
- vars.push (var);
- }
-
-#ifndef HB_NO_VAR
- hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ());
-#endif
- return font;
-}
-
-
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_GLYF_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/loca.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/loca.hh
deleted file mode 100644
index 4481cba8ed2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/loca.hh
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef OT_GLYF_LOCA_HH
-#define OT_GLYF_LOCA_HH
-
-
-#include "../../hb-open-type.hh"
-
-
-namespace OT {
-
-
-/*
- * loca -- Index to Location
- * https://docs.microsoft.com/en-us/typography/opentype/spec/loca
- */
-#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
-
-struct loca
-{
- friend struct glyf;
- friend struct glyf_accelerator_t;
-
- static constexpr hb_tag_t tableTag = HB_OT_TAG_loca;
-
- bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
- {
- TRACE_SANITIZE (this);
- return_trace (true);
- }
-
- protected:
- UnsizedArrayOf<HBUINT8>
- dataZ; /* Location data. */
- public:
- DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
- * check the size externally, allow Null() object of it by
- * defining it _MIN instead. */
-};
-
-
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_LOCA_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh
deleted file mode 100644
index 8916241f76e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh
+++ /dev/null
@@ -1,193 +0,0 @@
-#ifndef OT_GLYF_PATH_BUILDER_HH
-#define OT_GLYF_PATH_BUILDER_HH
-
-
-#include "../../hb.hh"
-
-
-namespace OT {
-namespace glyf_impl {
-
-
-struct path_builder_t
-{
- hb_font_t *font;
- hb_draw_session_t *draw_session;
-
- struct optional_point_t
- {
- optional_point_t () {}
- optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {}
- operator bool () const { return has_data; }
-
- bool has_data = false;
- float x = 0.;
- float y = 0.;
-
- optional_point_t lerp (optional_point_t p, float t)
- { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
- } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
-
- path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
- {
- font = font_;
- draw_session = &draw_session_;
- first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
- }
-
- /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
- See also:
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
- * https://stackoverflow.com/a/20772557
- *
- * Cubic support added. */
- void consume_point (const contour_point_t &point)
- {
- bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
-#ifdef HB_NO_CUBIC_GLYF
- bool is_cubic = false;
-#else
- bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
-#endif
- optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
- if (!first_oncurve)
- {
- if (is_on_curve)
- {
- first_oncurve = p;
- draw_session->move_to (p.x, p.y);
- }
- else
- {
- if (is_cubic && !first_offcurve2)
- {
- first_offcurve2 = first_offcurve;
- first_offcurve = p;
- }
- else if (first_offcurve)
- {
- optional_point_t mid = first_offcurve.lerp (p, .5f);
- first_oncurve = mid;
- last_offcurve = p;
- draw_session->move_to (mid.x, mid.y);
- }
- else
- first_offcurve = p;
- }
- }
- else
- {
- if (last_offcurve)
- {
- if (is_on_curve)
- {
- if (last_offcurve2)
- {
- draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
- last_offcurve.x, last_offcurve.y,
- p.x, p.y);
- last_offcurve2 = optional_point_t ();
- }
- else
- draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
- p.x, p.y);
- last_offcurve = optional_point_t ();
- }
- else
- {
- if (is_cubic && !last_offcurve2)
- {
- last_offcurve2 = last_offcurve;
- last_offcurve = p;
- }
- else
- {
- optional_point_t mid = last_offcurve.lerp (p, .5f);
-
- if (is_cubic)
- {
- draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
- last_offcurve.x, last_offcurve.y,
- mid.x, mid.y);
- last_offcurve2 = optional_point_t ();
- }
- else
- draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
- mid.x, mid.y);
- last_offcurve = p;
- }
- }
- }
- else
- {
- if (is_on_curve)
- draw_session->line_to (p.x, p.y);
- else
- last_offcurve = p;
- }
- }
-
- if (point.is_end_point)
- {
- if (first_offcurve && last_offcurve)
- {
- optional_point_t mid = last_offcurve.lerp (first_offcurve2 ?
- first_offcurve2 :
- first_offcurve, .5f);
- if (last_offcurve2)
- draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
- last_offcurve.x, last_offcurve.y,
- mid.x, mid.y);
- else
- draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
- mid.x, mid.y);
- last_offcurve = optional_point_t ();
- }
- /* now check the rest */
-
- if (first_offcurve && first_oncurve)
- {
- if (first_offcurve2)
- draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
- first_offcurve.x, first_offcurve.y,
- first_oncurve.x, first_oncurve.y);
- else
- draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
- first_oncurve.x, first_oncurve.y);
- }
- else if (last_offcurve && first_oncurve)
- {
- if (last_offcurve2)
- draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
- last_offcurve.x, last_offcurve.y,
- first_oncurve.x, first_oncurve.y);
- else
- draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
- first_oncurve.x, first_oncurve.y);
- }
- else if (first_oncurve)
- draw_session->line_to (first_oncurve.x, first_oncurve.y);
- else if (first_offcurve)
- {
- float x = first_offcurve.x, y = first_offcurve.y;
- draw_session->move_to (x, y);
- draw_session->quadratic_to (x, y, x, y);
- }
-
- /* Getting ready for the next contour */
- first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
- draw_session->close_path ();
- }
- }
- void points_end () {}
-
- bool is_consuming_contour_points () { return true; }
- contour_point_t *get_phantoms_sink () { return nullptr; }
-};
-
-
-} /* namespace glyf_impl */
-} /* namespace OT */
-
-
-#endif /* OT_GLYF_PATH_BUILDER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh b/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh
deleted file mode 100644
index c1839f3b683..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/OT/name/name.hh
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef OT_NAME_NAME_HH
-#define OT_NAME_NAME_HH
-
-#include "../../hb-open-type.hh"
-#include "../../hb-ot-name-language.hh"
-#include "../../hb-aat-layout.hh"
-#include "../../hb-utf.hh"
-
-
-namespace OT {
-
-template <typename in_utf_t, typename out_utf_t>
-inline unsigned int
-hb_ot_name_convert_utf (hb_bytes_t bytes,
- unsigned int *text_size /* IN/OUT */,
- typename out_utf_t::codepoint_t *text /* OUT */)
-{
- unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
- const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
- const typename in_utf_t::codepoint_t *src_end = src + src_len;
-
- typename out_utf_t::codepoint_t *dst = text;
-
- hb_codepoint_t unicode;
- const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
-
- if (text_size && *text_size)
- {
- (*text_size)--; /* Save room for NUL-termination. */
- const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
-
- while (src < src_end && dst < dst_end)
- {
- const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
- typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
- if (dst_next == dst)
- break; /* Out-of-room. */
-
- dst = dst_next;
- src = src_next;
- }
-
- *text_size = dst - text;
- *dst = 0; /* NUL-terminate. */
- }
-
- /* Accumulate length of rest. */
- unsigned int dst_len = dst - text;
- while (src < src_end)
- {
- src = in_utf_t::next (src, src_end, &unicode, replacement);
- dst_len += out_utf_t::encode_len (unicode);
- }
- return dst_len;
-}
-
-#define entry_score var.u16[0]
-#define entry_index var.u16[1]
-
-
-/*
- * name -- Naming
- * https://docs.microsoft.com/en-us/typography/opentype/spec/name
- */
-#define HB_OT_TAG_name HB_TAG('n','a','m','e')
-
-#define UNSUPPORTED 42
-
-struct NameRecord
-{
- hb_language_t language (hb_face_t *face) const
- {
-#ifndef HB_NO_OT_NAME_LANGUAGE
- unsigned int p = platformID;
- unsigned int l = languageID;
-
- if (p == 3)
- return _hb_ot_name_language_for_ms_code (l);
-
- if (p == 1)
- return _hb_ot_name_language_for_mac_code (l);
-
-#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
- if (p == 0)
- return face->table.ltag->get_language (l);
-#endif
-
-#endif
- return HB_LANGUAGE_INVALID;
- }
-
- uint16_t score () const
- {
- /* Same order as in cmap::find_best_subtable(). */
- unsigned int p = platformID;
- unsigned int e = encodingID;
-
- /* 32-bit. */
- if (p == 3 && e == 10) return 0;
- if (p == 0 && e == 6) return 1;
- if (p == 0 && e == 4) return 2;
-
- /* 16-bit. */
- if (p == 3 && e == 1) return 3;
- if (p == 0 && e == 3) return 4;
- if (p == 0 && e == 2) return 5;
- if (p == 0 && e == 1) return 6;
- if (p == 0 && e == 0) return 7;
-
- /* Symbol. */
- if (p == 3 && e == 0) return 8;
-
- /* We treat all Mac Latin names as ASCII only. */
- if (p == 1 && e == 0) return 10; /* 10 is magic number :| */
-
- return UNSUPPORTED;
- }
-
- NameRecord* copy (hb_serialize_context_t *c, const void *base
-#ifdef HB_EXPERIMENTAL_API
- , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
-#endif
- ) const
- {
- TRACE_SERIALIZE (this);
- HB_UNUSED auto snap = c->snapshot ();
- auto *out = c->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-#ifdef HB_EXPERIMENTAL_API
- hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
- hb_bytes_t* name_bytes;
-
- if (name_table_overrides->has (record_ids, &name_bytes)) {
- hb_bytes_t encoded_bytes = *name_bytes;
- char *name_str_utf16_be = nullptr;
-
- if (platformID != 1)
- {
- unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
-
- text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
- unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
- name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
- if (!name_str_utf16_be)
- {
- c->revert (snap);
- return_trace (nullptr);
- }
- hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
- (hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
-
- unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
- if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
- c->revert (snap);
- hb_free (name_str_utf16_be);
- return_trace (nullptr);
- }
-
- encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
- }
- else
- {
- // mac platform, copy the UTF-8 string(all ascii characters) as is
- if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
- c->revert (snap);
- return_trace (nullptr);
- }
- }
-
- out->offset = 0;
- c->push ();
- encoded_bytes.copy (c);
- c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
- hb_free (name_str_utf16_be);
- }
- else
-#endif
- {
- out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
- }
- return_trace (out);
- }
-
- bool isUnicode () const
- {
- unsigned int p = platformID;
- unsigned int e = encodingID;
-
- return (p == 0 ||
- (p == 3 && (e == 0 || e == 1 || e == 10)));
- }
-
- static int cmp (const void *pa, const void *pb)
- {
- const NameRecord *a = (const NameRecord *)pa;
- const NameRecord *b = (const NameRecord *)pb;
-
- if (a->platformID != b->platformID)
- return a->platformID - b->platformID;
-
- if (a->encodingID != b->encodingID)
- return a->encodingID - b->encodingID;
-
- if (a->languageID != b->languageID)
- return a->languageID - b->languageID;
-
- if (a->nameID != b->nameID)
- return a->nameID - b->nameID;
-
- if (a->length != b->length)
- return a->length - b->length;
-
- return 0;
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
- }
-
- HBUINT16 platformID; /* Platform ID. */
- HBUINT16 encodingID; /* Platform-specific encoding ID. */
- HBUINT16 languageID; /* Language ID. */
- HBUINT16 nameID; /* Name ID. */
- HBUINT16 length; /* String length (in bytes). */
- NNOffset16To<UnsizedArrayOf<HBUINT8>>
- offset; /* String offset from start of storage area (in bytes). */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-static int
-_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
-{
- const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
- const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
-
- /* Compare by name_id, then language. */
-
- if (a->name_id != b->name_id)
- return a->name_id - b->name_id;
-
- if (a->language == b->language) return 0;
- if (!a->language) return -1;
- if (!b->language) return +1;
-
- const char *astr = hb_language_to_string (a->language);
- const char *bstr = hb_language_to_string (b->language);
-
- signed c = strcmp (astr, bstr);
-
- // 'a' is the user request, and 'b' is string in the font.
- // If eg. user asks for "en-us" and font has "en", approve.
- if (!exact && c &&
- hb_language_matches (b->language, a->language))
- return 0;
-
- return c;
-}
-
-static int
-_hb_ot_name_entry_cmp (const void *pa, const void *pb)
-{
- /* Compare by name_id, then language, then score, then index. */
-
- int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
- if (v)
- return v;
-
- const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
- const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
-
- if (a->entry_score != b->entry_score)
- return a->entry_score - b->entry_score;
-
- if (a->entry_index != b->entry_index)
- return a->entry_index - b->entry_index;
-
- return 0;
-}
-
-struct name
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_name;
-
- unsigned int get_size () const
- { return min_size + count * nameRecordZ.item_size; }
-
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- const void *src_string_pool
-#ifdef HB_EXPERIMENTAL_API
- , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
- , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
-#endif
- )
- {
- TRACE_SERIALIZE (this);
-
- if (unlikely (!c->extend_min ((*this)))) return_trace (false);
-
- unsigned total_count = it.len ()
-#ifdef HB_EXPERIMENTAL_API
- + insert_name_records.length
-#endif
- ;
- this->format = 0;
- if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return false;
-
- NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
- if (unlikely (!name_records)) return_trace (false);
-
- hb_array_t<NameRecord> records (name_records, total_count);
-
- for (const NameRecord& record : it)
- {
- hb_memcpy (name_records, &record, NameRecord::static_size);
- name_records++;
- }
-
-#ifdef HB_EXPERIMENTAL_API
- for (unsigned i = 0; i < insert_name_records.length; i++)
- {
- const hb_ot_name_record_ids_t& ids = insert_name_records[i];
- NameRecord record;
- record.platformID = ids.platform_id;
- record.encodingID = ids.encoding_id;
- record.languageID = ids.language_id;
- record.nameID = ids.name_id;
- record.length = 0; // handled in NameRecord copy()
- record.offset = 0;
- memcpy (name_records, &record, NameRecord::static_size);
- name_records++;
- }
-#endif
-
- records.qsort ();
-
- c->copy_all (records,
- src_string_pool
-#ifdef HB_EXPERIMENTAL_API
- , name_table_overrides
-#endif
- );
- hb_free (records.arrayZ);
-
-
- if (unlikely (c->ran_out_of_room ())) return_trace (false);
-
- this->stringOffset = c->length ();
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- name *name_prime = c->serializer->start_embed<name> ();
- if (unlikely (!name_prime)) return_trace (false);
-
-#ifdef HB_EXPERIMENTAL_API
- const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
- &c->plan->name_table_overrides;
-#endif
-
- auto it =
- + nameRecordZ.as_array (count)
- | hb_filter (c->plan->name_ids, &NameRecord::nameID)
- | hb_filter (c->plan->name_languages, &NameRecord::languageID)
- | hb_filter ([&] (const NameRecord& namerecord) {
- return
- (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
- || namerecord.isUnicode ();
- })
-#ifdef HB_EXPERIMENTAL_API
- | hb_filter ([&] (const NameRecord& namerecord) {
- if (name_table_overrides->is_empty ())
- return true;
- hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
- namerecord.encodingID,
- namerecord.languageID,
- namerecord.nameID);
-
- hb_bytes_t *p;
- if (name_table_overrides->has (rec_ids, &p) &&
- (*p).length == 0)
- return false;
- return true;
- })
-#endif
- ;
-
-#ifdef HB_EXPERIMENTAL_API
- hb_hashmap_t<hb_ot_name_record_ids_t, unsigned> retained_name_record_ids;
- for (const NameRecord& rec : it)
- {
- hb_ot_name_record_ids_t rec_ids (rec.platformID,
- rec.encodingID,
- rec.languageID,
- rec.nameID);
- retained_name_record_ids.set (rec_ids, 1);
- }
-
- hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
- if (!name_table_overrides->is_empty ())
- {
- if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true)))
- return_trace (false);
- for (const auto& record_ids : name_table_overrides->keys ())
- {
- if (name_table_overrides->get (record_ids).length == 0)
- continue;
- if (retained_name_record_ids.has (record_ids))
- continue;
- insert_name_records.push (record_ids);
- }
- }
-#endif
-
- return (name_prime->serialize (c->serializer, it,
- std::addressof (this + stringOffset)
-#ifdef HB_EXPERIMENTAL_API
- , insert_name_records
- , name_table_overrides
-#endif
- ));
- }
-
- bool sanitize_records (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- const void *string_pool = (this+stringOffset).arrayZ;
- return_trace (nameRecordZ.sanitize (c, count, string_pool));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (format == 0 || format == 1) &&
- c->check_array (nameRecordZ.arrayZ, count) &&
- c->check_range (this, stringOffset) &&
- sanitize_records (c));
- }
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- this->table = hb_sanitize_context_t ().reference_table<name> (face);
- assert (this->table.get_length () >= this->table->stringOffset);
- this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
- this->pool_len = this->table.get_length () - this->table->stringOffset;
- const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
- this->table->count);
-
- this->names.alloc (all_names.length, true);
-
- for (unsigned int i = 0; i < all_names.length; i++)
- {
- hb_ot_name_entry_t *entry = this->names.push ();
-
- entry->name_id = all_names[i].nameID;
- entry->language = all_names[i].language (face);
- entry->entry_score = all_names[i].score ();
- entry->entry_index = i;
- }
-
- this->names.qsort (_hb_ot_name_entry_cmp);
- /* Walk and pick best only for each name_id,language pair,
- * while dropping unsupported encodings. */
- unsigned int j = 0;
- for (unsigned int i = 0; i < this->names.length; i++)
- {
- if (this->names[i].entry_score == UNSUPPORTED ||
- this->names[i].language == HB_LANGUAGE_INVALID)
- continue;
- if (i &&
- this->names[i - 1].name_id == this->names[i].name_id &&
- this->names[i - 1].language == this->names[i].language)
- continue;
- this->names[j++] = this->names[i];
- }
- this->names.resize (j);
- }
- ~accelerator_t ()
- {
- this->table.destroy ();
- }
-
- int get_index (hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *width=nullptr) const
- {
- const hb_ot_name_entry_t key = {name_id, {0}, language};
- const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
- this->names.length,
- sizeof (hb_ot_name_entry_t),
- _hb_ot_name_entry_cmp_key,
- true);
-
- if (!entry)
- {
- entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
- this->names.length,
- sizeof (hb_ot_name_entry_t),
- _hb_ot_name_entry_cmp_key,
- false);
- }
-
- if (!entry)
- return -1;
-
- if (width)
- *width = entry->entry_score < 10 ? 2 : 1;
-
- return entry->entry_index;
- }
-
- hb_bytes_t get_name (unsigned int idx) const
- {
- const hb_array_t<const NameRecord> all_names (table->nameRecordZ.arrayZ, table->count);
- const NameRecord &record = all_names[idx];
- const hb_bytes_t string_pool (pool, pool_len);
- return string_pool.sub_array (record.offset, record.length);
- }
-
- private:
- const char *pool;
- unsigned int pool_len;
- public:
- hb_blob_ptr_t<name> table;
- hb_vector_t<hb_ot_name_entry_t> names;
- };
-
- public:
- /* We only implement format 0 for now. */
- HBUINT16 format; /* Format selector (=0/1). */
- HBUINT16 count; /* Number of name records. */
- NNOffset16To<UnsizedArrayOf<HBUINT8>>
- stringOffset; /* Offset to start of string storage (from start of table). */
- UnsizedArrayOf<NameRecord>
- nameRecordZ; /* The name records where count is the number of records. */
- public:
- DEFINE_SIZE_ARRAY (6, nameRecordZ);
-};
-
-#undef entry_index
-#undef entry_score
-
-struct name_accelerator_t : name::accelerator_t {
- name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* OT_NAME_NAME_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh
deleted file mode 100644
index c2e24a70678..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/classdef-graph.hh
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "graph.hh"
-#include "../hb-ot-layout-common.hh"
-
-#ifndef GRAPH_CLASSDEF_GRAPH_HH
-#define GRAPH_CLASSDEF_GRAPH_HH
-
-namespace graph {
-
-struct ClassDefFormat1 : public OT::ClassDefFormat1_3<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- constexpr unsigned min_size = OT::ClassDefFormat1_3<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
- return vertex_len >= min_size + classValue.get_size () - classValue.len.get_size ();
- }
-};
-
-struct ClassDefFormat2 : public OT::ClassDefFormat2_4<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- constexpr unsigned min_size = OT::ClassDefFormat2_4<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
- return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size ();
- }
-};
-
-struct ClassDef : public OT::ClassDef
-{
- template<typename It>
- static bool add_class_def (gsubgpos_graph_context_t& c,
- unsigned parent_id,
- unsigned link_position,
- It glyph_and_class,
- unsigned max_size)
- {
- unsigned class_def_prime_id = c.graph.new_node (nullptr, nullptr);
- auto& class_def_prime_vertex = c.graph.vertices_[class_def_prime_id];
- if (!make_class_def (c, glyph_and_class, class_def_prime_id, max_size))
- return false;
-
- auto* class_def_link = c.graph.vertices_[parent_id].obj.real_links.push ();
- class_def_link->width = SmallTypes::size;
- class_def_link->objidx = class_def_prime_id;
- class_def_link->position = link_position;
- class_def_prime_vertex.parents.push (parent_id);
-
- return true;
- }
-
- template<typename It>
- static bool make_class_def (gsubgpos_graph_context_t& c,
- It glyph_and_class,
- unsigned dest_obj,
- unsigned max_size)
- {
- char* buffer = (char*) hb_calloc (1, max_size);
- hb_serialize_context_t serializer (buffer, max_size);
- OT::ClassDef_serialize (&serializer, glyph_and_class);
- serializer.end_serialize ();
- if (serializer.in_error ())
- {
- hb_free (buffer);
- return false;
- }
-
- hb_bytes_t class_def_copy = serializer.copy_bytes ();
- c.add_buffer ((char *) class_def_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
-
- auto& obj = c.graph.vertices_[dest_obj].obj;
- obj.head = (char *) class_def_copy.arrayZ;
- obj.tail = obj.head + class_def_copy.length;
-
- hb_free (buffer);
- return true;
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < OT::ClassDef::min_size) return false;
- switch (u.format)
- {
- case 1: return ((ClassDefFormat1*)this)->sanitize (vertex);
- case 2: return ((ClassDefFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BEYOND_64K
- // Not currently supported
- case 3:
- case 4:
-#endif
- default: return false;
- }
- }
-};
-
-
-struct class_def_size_estimator_t
-{
- template<typename It>
- class_def_size_estimator_t (It glyph_and_class)
- : gids_consecutive (true), num_ranges_per_class (), glyphs_per_class ()
- {
- unsigned last_gid = (unsigned) -1;
- for (auto p : + glyph_and_class)
- {
- unsigned gid = p.first;
- unsigned klass = p.second;
-
- if (last_gid != (unsigned) -1 && gid != last_gid + 1)
- gids_consecutive = false;
- last_gid = gid;
-
- hb_set_t* glyphs;
- if (glyphs_per_class.has (klass, &glyphs) && glyphs) {
- glyphs->add (gid);
- continue;
- }
-
- hb_set_t new_glyphs;
- new_glyphs.add (gid);
- glyphs_per_class.set (klass, std::move (new_glyphs));
- }
-
- if (in_error ()) return;
-
- for (unsigned klass : glyphs_per_class.keys ())
- {
- if (!klass) continue; // class 0 doesn't get encoded.
-
- const hb_set_t& glyphs = glyphs_per_class.get (klass);
- hb_codepoint_t start = HB_SET_VALUE_INVALID;
- hb_codepoint_t end = HB_SET_VALUE_INVALID;
-
- unsigned count = 0;
- while (glyphs.next_range (&start, &end))
- count++;
-
- num_ranges_per_class.set (klass, count);
- }
- }
-
- // Incremental increase in the Coverage and ClassDef table size
- // (worst case) if all glyphs associated with 'klass' were added.
- unsigned incremental_coverage_size (unsigned klass) const
- {
- // Coverage takes 2 bytes per glyph worst case,
- return 2 * glyphs_per_class.get (klass).get_population ();
- }
-
- // Incremental increase in the Coverage and ClassDef table size
- // (worst case) if all glyphs associated with 'klass' were added.
- unsigned incremental_class_def_size (unsigned klass) const
- {
- // ClassDef takes 6 bytes per range
- unsigned class_def_2_size = 6 * num_ranges_per_class.get (klass);
- if (gids_consecutive)
- {
- // ClassDef1 takes 2 bytes per glyph, but only can be used
- // when gids are consecutive.
- return hb_min (2 * glyphs_per_class.get (klass).get_population (), class_def_2_size);
- }
-
- return class_def_2_size;
- }
-
- bool in_error ()
- {
- if (num_ranges_per_class.in_error ()) return true;
- if (glyphs_per_class.in_error ()) return true;
-
- for (const hb_set_t& s : glyphs_per_class.values ())
- {
- if (s.in_error ()) return true;
- }
- return false;
- }
-
- private:
- bool gids_consecutive;
- hb_hashmap_t<unsigned, unsigned> num_ranges_per_class;
- hb_hashmap_t<unsigned, hb_set_t> glyphs_per_class;
-};
-
-
-}
-
-#endif // GRAPH_CLASSDEF_GRAPH_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh
deleted file mode 100644
index 49d09363156..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/coverage-graph.hh
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "graph.hh"
-#include "../OT/Layout/Common/Coverage.hh"
-
-#ifndef GRAPH_COVERAGE_GRAPH_HH
-#define GRAPH_COVERAGE_GRAPH_HH
-
-namespace graph {
-
-struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
- return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size ();
- }
-};
-
-struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
- return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size ();
- }
-};
-
-struct Coverage : public OT::Layout::Common::Coverage
-{
- static Coverage* clone_coverage (gsubgpos_graph_context_t& c,
- unsigned coverage_id,
- unsigned new_parent_id,
- unsigned link_position,
- unsigned start, unsigned end)
-
- {
- unsigned coverage_size = c.graph.vertices_[coverage_id].table_size ();
- auto& coverage_v = c.graph.vertices_[coverage_id];
- Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
- if (!coverage_table || !coverage_table->sanitize (coverage_v))
- return nullptr;
-
- auto new_coverage =
- + hb_zip (coverage_table->iter (), hb_range ())
- | hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
- return p.second >= start && p.second < end;
- })
- | hb_map_retains_sorting (hb_first)
- ;
-
- return add_coverage (c, new_parent_id, link_position, new_coverage, coverage_size);
- }
-
- template<typename It>
- static Coverage* add_coverage (gsubgpos_graph_context_t& c,
- unsigned parent_id,
- unsigned link_position,
- It glyphs,
- unsigned max_size)
- {
- unsigned coverage_prime_id = c.graph.new_node (nullptr, nullptr);
- auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id];
- if (!make_coverage (c, glyphs, coverage_prime_id, max_size))
- return nullptr;
-
- auto* coverage_link = c.graph.vertices_[parent_id].obj.real_links.push ();
- coverage_link->width = SmallTypes::size;
- coverage_link->objidx = coverage_prime_id;
- coverage_link->position = link_position;
- coverage_prime_vertex.parents.push (parent_id);
-
- return (Coverage*) coverage_prime_vertex.obj.head;
- }
-
- template<typename It>
- static bool make_coverage (gsubgpos_graph_context_t& c,
- It glyphs,
- unsigned dest_obj,
- unsigned max_size)
- {
- char* buffer = (char*) hb_calloc (1, max_size);
- hb_serialize_context_t serializer (buffer, max_size);
- OT::Layout::Common::Coverage_serialize (&serializer, glyphs);
- serializer.end_serialize ();
- if (serializer.in_error ())
- {
- hb_free (buffer);
- return false;
- }
-
- hb_bytes_t coverage_copy = serializer.copy_bytes ();
- c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
-
- auto& obj = c.graph.vertices_[dest_obj].obj;
- obj.head = (char *) coverage_copy.arrayZ;
- obj.tail = obj.head + coverage_copy.length;
-
- hb_free (buffer);
- return true;
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < OT::Layout::Common::Coverage::min_size) return false;
- switch (u.format)
- {
- case 1: return ((CoverageFormat1*)this)->sanitize (vertex);
- case 2: return ((CoverageFormat2*)this)->sanitize (vertex);
-#ifndef HB_NO_BEYOND_64K
- // Not currently supported
- case 3:
- case 4:
-#endif
- default: return false;
- }
- }
-};
-
-
-}
-
-#endif // GRAPH_COVERAGE_GRAPH_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
deleted file mode 100644
index 38ca5db0961..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "../hb-set.hh"
-#include "../hb-priority-queue.hh"
-#include "../hb-serialize.hh"
-
-#ifndef GRAPH_GRAPH_HH
-#define GRAPH_GRAPH_HH
-
-namespace graph {
-
-/**
- * Represents a serialized table in the form of a graph.
- * Provides methods for modifying and reordering the graph.
- */
-struct graph_t
-{
- struct vertex_t
- {
- hb_serialize_context_t::object_t obj;
- int64_t distance = 0 ;
- int64_t space = 0 ;
- hb_vector_t<unsigned> parents;
- unsigned start = 0;
- unsigned end = 0;
- unsigned priority = 0;
-
-
- bool link_positions_valid (unsigned num_objects, bool removed_nil)
- {
- hb_set_t assigned_bytes;
- for (const auto& l : obj.real_links)
- {
- if (l.objidx >= num_objects
- || (removed_nil && !l.objidx))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Invalid graph. Invalid object index.");
- return false;
- }
-
- unsigned start = l.position;
- unsigned end = start + l.width - 1;
-
- if (unlikely (l.width < 2 || l.width > 4))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Invalid graph. Invalid link width.");
- return false;
- }
-
- if (unlikely (end >= table_size ()))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Invalid graph. Link position is out of bounds.");
- return false;
- }
-
- if (unlikely (assigned_bytes.intersects (start, end)))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Invalid graph. Found offsets whose positions overlap.");
- return false;
- }
-
- assigned_bytes.add_range (start, end);
- }
-
- return !assigned_bytes.in_error ();
- }
-
- void normalize ()
- {
- obj.real_links.qsort ();
- for (auto& l : obj.real_links)
- {
- for (unsigned i = 0; i < l.width; i++)
- {
- obj.head[l.position + i] = 0;
- }
- }
- }
-
- bool equals (const vertex_t& other,
- const graph_t& graph,
- const graph_t& other_graph,
- unsigned depth) const
- {
- if (!(as_bytes () == other.as_bytes ()))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "vertex [%lu] bytes != [%lu] bytes, depth = %u",
- (unsigned long) table_size (),
- (unsigned long) other.table_size (),
- depth);
-
- auto a = as_bytes ();
- auto b = other.as_bytes ();
- while (a || b)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " 0x%x %s 0x%x", (unsigned) *a, (*a == *b) ? "==" : "!=", (unsigned) *b);
- a++;
- b++;
- }
- return false;
- }
-
- return links_equal (obj.real_links, other.obj.real_links, graph, other_graph, depth);
- }
-
- hb_bytes_t as_bytes () const
- {
- return hb_bytes_t (obj.head, table_size ());
- }
-
- friend void swap (vertex_t& a, vertex_t& b)
- {
- hb_swap (a.obj, b.obj);
- hb_swap (a.distance, b.distance);
- hb_swap (a.space, b.space);
- hb_swap (a.parents, b.parents);
- hb_swap (a.start, b.start);
- hb_swap (a.end, b.end);
- hb_swap (a.priority, b.priority);
- }
-
- hb_hashmap_t<unsigned, unsigned>
- position_to_index_map () const
- {
- hb_hashmap_t<unsigned, unsigned> result;
-
- for (const auto& l : obj.real_links) {
- result.set (l.position, l.objidx);
- }
-
- return result;
- }
-
- bool is_shared () const
- {
- return parents.length > 1;
- }
-
- unsigned incoming_edges () const
- {
- return parents.length;
- }
-
- void remove_parent (unsigned parent_index)
- {
- for (unsigned i = 0; i < parents.length; i++)
- {
- if (parents[i] != parent_index) continue;
- parents.remove_unordered (i);
- break;
- }
- }
-
- void remove_real_link (unsigned child_index, const void* offset)
- {
- for (unsigned i = 0; i < obj.real_links.length; i++)
- {
- auto& link = obj.real_links.arrayZ[i];
- if (link.objidx != child_index)
- continue;
-
- if ((obj.head + link.position) != offset)
- continue;
-
- obj.real_links.remove_unordered (i);
- return;
- }
- }
-
- void remap_parents (const hb_vector_t<unsigned>& id_map)
- {
- for (unsigned i = 0; i < parents.length; i++)
- parents[i] = id_map[parents[i]];
- }
-
- void remap_parent (unsigned old_index, unsigned new_index)
- {
- for (unsigned i = 0; i < parents.length; i++)
- {
- if (parents[i] == old_index)
- parents[i] = new_index;
- }
- }
-
- bool is_leaf () const
- {
- return !obj.real_links.length && !obj.virtual_links.length;
- }
-
- bool raise_priority ()
- {
- if (has_max_priority ()) return false;
- priority++;
- return true;
- }
-
- bool has_max_priority () const {
- return priority >= 3;
- }
-
- size_t table_size () const {
- return obj.tail - obj.head;
- }
-
- int64_t modified_distance (unsigned order) const
- {
- // TODO(garretrieger): once priority is high enough, should try
- // setting distance = 0 which will force to sort immediately after
- // it's parent where possible.
-
- int64_t modified_distance =
- hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF);
- if (has_max_priority ()) {
- modified_distance = 0;
- }
- return (modified_distance << 18) | (0x003FFFF & order);
- }
-
- int64_t distance_modifier () const
- {
- if (!priority) return 0;
- int64_t table_size = obj.tail - obj.head;
-
- if (priority == 1)
- return -table_size / 2;
-
- return -table_size;
- }
-
- private:
- bool links_equal (const hb_vector_t<hb_serialize_context_t::object_t::link_t>& this_links,
- const hb_vector_t<hb_serialize_context_t::object_t::link_t>& other_links,
- const graph_t& graph,
- const graph_t& other_graph,
- unsigned depth) const
- {
- auto a = this_links.iter ();
- auto b = other_links.iter ();
-
- while (a && b)
- {
- const auto& link_a = *a;
- const auto& link_b = *b;
-
- if (link_a.width != link_b.width ||
- link_a.is_signed != link_b.is_signed ||
- link_a.whence != link_b.whence ||
- link_a.position != link_b.position ||
- link_a.bias != link_b.bias)
- return false;
-
- if (!graph.vertices_[link_a.objidx].equals (
- other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1))
- return false;
-
- a++;
- b++;
- }
-
- if (bool (a) != bool (b))
- return false;
-
- return true;
- }
- };
-
- template <typename T>
- struct vertex_and_table_t
- {
- vertex_and_table_t () : index (0), vertex (nullptr), table (nullptr)
- {}
-
- unsigned index;
- vertex_t* vertex;
- T* table;
-
- operator bool () {
- return table && vertex;
- }
- };
-
- /*
- * A topological sorting of an object graph. Ordered
- * in reverse serialization order (first object in the
- * serialization is at the end of the list). This matches
- * the 'packed' object stack used internally in the
- * serializer
- */
- template<typename T>
- graph_t (const T& objects)
- : parents_invalid (true),
- distance_invalid (true),
- positions_invalid (true),
- successful (true),
- buffers ()
- {
- num_roots_for_space_.push (1);
- bool removed_nil = false;
- vertices_.alloc (objects.length);
- vertices_scratch_.alloc (objects.length);
- for (unsigned i = 0; i < objects.length; i++)
- {
- // If this graph came from a serialization buffer object 0 is the
- // nil object. We don't need it for our purposes here so drop it.
- if (i == 0 && !objects[i])
- {
- removed_nil = true;
- continue;
- }
-
- vertex_t* v = vertices_.push ();
- if (check_success (!vertices_.in_error ()))
- v->obj = *objects[i];
-
- check_success (v->link_positions_valid (objects.length, removed_nil));
-
- if (!removed_nil) continue;
- // Fix indices to account for removed nil object.
- for (auto& l : v->obj.all_links_writer ()) {
- l.objidx--;
- }
- }
- }
-
- ~graph_t ()
- {
- vertices_.fini ();
- for (char* b : buffers)
- hb_free (b);
- }
-
- bool operator== (const graph_t& other) const
- {
- return root ().equals (other.root (), *this, other, 0);
- }
-
- // Sorts links of all objects in a consistent manner and zeroes all offsets.
- void normalize ()
- {
- for (auto& v : vertices_.writer ())
- v.normalize ();
- }
-
- bool in_error () const
- {
- return !successful ||
- vertices_.in_error () ||
- num_roots_for_space_.in_error ();
- }
-
- const vertex_t& root () const
- {
- return vertices_[root_idx ()];
- }
-
- unsigned root_idx () const
- {
- // Object graphs are in reverse order, the first object is at the end
- // of the vector. Since the graph is topologically sorted it's safe to
- // assume the first object has no incoming edges.
- return vertices_.length - 1;
- }
-
- const hb_serialize_context_t::object_t& object (unsigned i) const
- {
- return vertices_[i].obj;
- }
-
- void add_buffer (char* buffer)
- {
- buffers.push (buffer);
- }
-
- /*
- * Adds a 16 bit link from parent_id to child_id
- */
- template<typename T>
- void add_link (T* offset,
- unsigned parent_id,
- unsigned child_id)
- {
- auto& v = vertices_[parent_id];
- auto* link = v.obj.real_links.push ();
- link->width = 2;
- link->objidx = child_id;
- link->position = (char*) offset - (char*) v.obj.head;
- vertices_[child_id].parents.push (parent_id);
- }
-
- /*
- * Generates a new topological sorting of graph ordered by the shortest
- * distance to each node if positions are marked as invalid.
- */
- void sort_shortest_distance_if_needed ()
- {
- if (!positions_invalid) return;
- sort_shortest_distance ();
- }
-
-
- /*
- * Generates a new topological sorting of graph ordered by the shortest
- * distance to each node.
- */
- void sort_shortest_distance ()
- {
- positions_invalid = true;
-
- if (vertices_.length <= 1) {
- // Graph of 1 or less doesn't need sorting.
- return;
- }
-
- update_distances ();
-
- hb_priority_queue_t queue;
- hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
- if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
- hb_vector_t<unsigned> id_map;
- if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
-
- hb_vector_t<unsigned> removed_edges;
- if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return;
- update_parents ();
-
- queue.insert (root ().modified_distance (0), root_idx ());
- int new_id = root_idx ();
- unsigned order = 1;
- while (!queue.in_error () && !queue.is_empty ())
- {
- unsigned next_id = queue.pop_minimum().second;
-
- hb_swap (sorted_graph[new_id], vertices_[next_id]);
- const vertex_t& next = sorted_graph[new_id];
-
- if (unlikely (!check_success(new_id >= 0))) {
- // We are out of ids. Which means we've visited a node more than once.
- // This graph contains a cycle which is not allowed.
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle.");
- return;
- }
-
- id_map[next_id] = new_id--;
-
- for (const auto& link : next.obj.all_links ()) {
- removed_edges[link.objidx]++;
- if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
- // Add the order that the links were encountered to the priority.
- // This ensures that ties between priorities objects are broken in a consistent
- // way. More specifically this is set up so that if a set of objects have the same
- // distance they'll be added to the topological order in the order that they are
- // referenced from the parent object.
- queue.insert (vertices_[link.objidx].modified_distance (order++),
- link.objidx);
- }
- }
-
- check_success (!queue.in_error ());
- check_success (!sorted_graph.in_error ());
-
- remap_all_obj_indices (id_map, &sorted_graph);
- hb_swap (vertices_, sorted_graph);
-
- if (!check_success (new_id == -1))
- print_orphaned_nodes ();
- }
-
- /*
- * Finds the set of nodes (placed into roots) that should be assigned unique spaces.
- * More specifically this looks for the top most 24 bit or 32 bit links in the graph.
- * Some special casing is done that is specific to the layout of GSUB/GPOS tables.
- */
- void find_space_roots (hb_set_t& visited, hb_set_t& roots)
- {
- int root_index = (int) root_idx ();
- for (int i = root_index; i >= 0; i--)
- {
- if (visited.has (i)) continue;
-
- // Only real links can form 32 bit spaces
- for (auto& l : vertices_[i].obj.real_links)
- {
- if (l.is_signed || l.width < 3)
- continue;
-
- if (i == root_index && l.width == 3)
- // Ignore 24bit links from the root node, this skips past the single 24bit
- // pointer to the lookup list.
- continue;
-
- if (l.width == 3)
- {
- // A 24bit offset forms a root, unless there is 32bit offsets somewhere
- // in it's subgraph, then those become the roots instead. This is to make sure
- // that extension subtables beneath a 24bit lookup become the spaces instead
- // of the offset to the lookup.
- hb_set_t sub_roots;
- find_32bit_roots (l.objidx, sub_roots);
- if (sub_roots) {
- for (unsigned sub_root_idx : sub_roots) {
- roots.add (sub_root_idx);
- find_subgraph (sub_root_idx, visited);
- }
- continue;
- }
- }
-
- roots.add (l.objidx);
- find_subgraph (l.objidx, visited);
- }
- }
- }
-
- template <typename T, typename ...Ts>
- vertex_and_table_t<T> as_table (unsigned parent, const void* offset, Ts... ds)
- {
- return as_table_from_index<T> (index_for_offset (parent, offset), std::forward<Ts>(ds)...);
- }
-
- template <typename T, typename ...Ts>
- vertex_and_table_t<T> as_mutable_table (unsigned parent, const void* offset, Ts... ds)
- {
- return as_table_from_index<T> (mutable_index_for_offset (parent, offset), std::forward<Ts>(ds)...);
- }
-
- template <typename T, typename ...Ts>
- vertex_and_table_t<T> as_table_from_index (unsigned index, Ts... ds)
- {
- if (index >= vertices_.length)
- return vertex_and_table_t<T> ();
-
- vertex_and_table_t<T> r;
- r.vertex = &vertices_[index];
- r.table = (T*) r.vertex->obj.head;
- r.index = index;
- if (!r.table)
- return vertex_and_table_t<T> ();
-
- if (!r.table->sanitize (*(r.vertex), std::forward<Ts>(ds)...))
- return vertex_and_table_t<T> ();
-
- return r;
- }
-
- // Finds the object id of the object pointed to by the offset at 'offset'
- // within object[node_idx].
- unsigned index_for_offset (unsigned node_idx, const void* offset) const
- {
- const auto& node = object (node_idx);
- if (offset < node.head || offset >= node.tail) return -1;
-
- unsigned length = node.real_links.length;
- for (unsigned i = 0; i < length; i++)
- {
- // Use direct access for increased performance, this is a hot method.
- const auto& link = node.real_links.arrayZ[i];
- if (offset != node.head + link.position)
- continue;
- return link.objidx;
- }
-
- return -1;
- }
-
- // Finds the object id of the object pointed to by the offset at 'offset'
- // within object[node_idx]. Ensures that the returned object is safe to mutate.
- // That is, if the original child object is shared by parents other than node_idx
- // it will be duplicated and the duplicate will be returned instead.
- unsigned mutable_index_for_offset (unsigned node_idx, const void* offset)
- {
- unsigned child_idx = index_for_offset (node_idx, offset);
- auto& child = vertices_[child_idx];
- for (unsigned p : child.parents)
- {
- if (p != node_idx) {
- return duplicate (node_idx, child_idx);
- }
- }
-
- return child_idx;
- }
-
-
- /*
- * Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s).
- * Currently, this is implemented specifically tailored to the structure of a GPOS/GSUB
- * (including with 24bit offsets) table.
- */
- bool assign_spaces ()
- {
- update_parents ();
-
- hb_set_t visited;
- hb_set_t roots;
- find_space_roots (visited, roots);
-
- // Mark everything not in the subgraphs of the roots as visited. This prevents
- // subgraphs from being connected via nodes not in those subgraphs.
- visited.invert ();
-
- if (!roots) return false;
-
- while (roots)
- {
- uint32_t next = HB_SET_VALUE_INVALID;
- if (unlikely (!check_success (!roots.in_error ()))) break;
- if (!roots.next (&next)) break;
-
- hb_set_t connected_roots;
- find_connected_nodes (next, roots, visited, connected_roots);
- if (unlikely (!check_success (!connected_roots.in_error ()))) break;
-
- isolate_subgraph (connected_roots);
- if (unlikely (!check_success (!connected_roots.in_error ()))) break;
-
- unsigned next_space = this->next_space ();
- num_roots_for_space_.push (0);
- for (unsigned root : connected_roots)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space);
- vertices_[root].space = next_space;
- num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1;
- distance_invalid = true;
- positions_invalid = true;
- }
-
- // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space
- // into the 32 bit space as needed, instead of using isolation.
- }
-
-
-
- return true;
- }
-
- /*
- * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph
- * that originate from outside of the subgraph will be removed by duplicating the linked to
- * object.
- *
- * Indices stored in roots will be updated if any of the roots are duplicated to new indices.
- */
- bool isolate_subgraph (hb_set_t& roots)
- {
- update_parents ();
- hb_map_t subgraph;
-
- // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these
- // set the subgraph incoming edge count to match all of root_idx's incoming edges
- hb_set_t parents;
- for (unsigned root_idx : roots)
- {
- subgraph.set (root_idx, wide_parents (root_idx, parents));
- find_subgraph (root_idx, subgraph);
- }
-
- unsigned original_root_idx = root_idx ();
- hb_map_t index_map;
- bool made_changes = false;
- for (auto entry : subgraph.iter ())
- {
- const auto& node = vertices_[entry.first];
- unsigned subgraph_incoming_edges = entry.second;
-
- if (subgraph_incoming_edges < node.incoming_edges ())
- {
- // Only de-dup objects with incoming links from outside the subgraph.
- made_changes = true;
- duplicate_subgraph (entry.first, index_map);
- }
- }
-
- if (in_error ())
- return false;
-
- if (!made_changes)
- return false;
-
- if (original_root_idx != root_idx ()
- && parents.has (original_root_idx))
- {
- // If the root idx has changed since parents was determined, update root idx in parents
- parents.add (root_idx ());
- parents.del (original_root_idx);
- }
-
- auto new_subgraph =
- + subgraph.keys ()
- | hb_map([&] (uint32_t node_idx) {
- const uint32_t *v;
- if (index_map.has (node_idx, &v)) return *v;
- return node_idx;
- })
- ;
-
- remap_obj_indices (index_map, new_subgraph);
- remap_obj_indices (index_map, parents.iter (), true);
-
- // Update roots set with new indices as needed.
- uint32_t next = HB_SET_VALUE_INVALID;
- while (roots.next (&next))
- {
- const uint32_t *v;
- if (index_map.has (next, &v))
- {
- roots.del (next);
- roots.add (*v);
- }
- }
-
- return true;
- }
-
- void find_subgraph (unsigned node_idx, hb_map_t& subgraph)
- {
- for (const auto& link : vertices_[node_idx].obj.all_links ())
- {
- const uint32_t *v;
- if (subgraph.has (link.objidx, &v))
- {
- subgraph.set (link.objidx, *v + 1);
- continue;
- }
- subgraph.set (link.objidx, 1);
- find_subgraph (link.objidx, subgraph);
- }
- }
-
- void find_subgraph (unsigned node_idx, hb_set_t& subgraph)
- {
- if (subgraph.has (node_idx)) return;
- subgraph.add (node_idx);
- for (const auto& link : vertices_[node_idx].obj.all_links ())
- find_subgraph (link.objidx, subgraph);
- }
-
- size_t find_subgraph_size (unsigned node_idx, hb_set_t& subgraph, unsigned max_depth = -1)
- {
- if (subgraph.has (node_idx)) return 0;
- subgraph.add (node_idx);
-
- const auto& o = vertices_[node_idx].obj;
- size_t size = o.tail - o.head;
- if (max_depth == 0)
- return size;
-
- for (const auto& link : o.all_links ())
- size += find_subgraph_size (link.objidx, subgraph, max_depth - 1);
- return size;
- }
-
- /*
- * Finds the topmost children of 32bit offsets in the subgraph starting
- * at node_idx. Found indices are placed into 'found'.
- */
- void find_32bit_roots (unsigned node_idx, hb_set_t& found)
- {
- for (const auto& link : vertices_[node_idx].obj.all_links ())
- {
- if (!link.is_signed && link.width == 4) {
- found.add (link.objidx);
- continue;
- }
- find_32bit_roots (link.objidx, found);
- }
- }
-
- /*
- * Moves the child of old_parent_idx pointed to by old_offset to a new
- * vertex at the new_offset.
- */
- template<typename O>
- void move_child (unsigned old_parent_idx,
- const O* old_offset,
- unsigned new_parent_idx,
- const O* new_offset)
- {
- distance_invalid = true;
- positions_invalid = true;
-
- auto& old_v = vertices_[old_parent_idx];
- auto& new_v = vertices_[new_parent_idx];
-
- unsigned child_id = index_for_offset (old_parent_idx,
- old_offset);
-
- auto* new_link = new_v.obj.real_links.push ();
- new_link->width = O::static_size;
- new_link->objidx = child_id;
- new_link->position = (const char*) new_offset - (const char*) new_v.obj.head;
-
- auto& child = vertices_[child_id];
- child.parents.push (new_parent_idx);
-
- old_v.remove_real_link (child_id, old_offset);
- child.remove_parent (old_parent_idx);
- }
-
- /*
- * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
- * links. index_map is updated with mappings from old id to new id. If a duplication has already
- * been performed for a given index, then it will be skipped.
- */
- void duplicate_subgraph (unsigned node_idx, hb_map_t& index_map)
- {
- if (index_map.has (node_idx))
- return;
-
- unsigned clone_idx = duplicate (node_idx);
- if (!check_success (clone_idx != (unsigned) -1))
- return;
-
- index_map.set (node_idx, clone_idx);
- for (const auto& l : object (node_idx).all_links ()) {
- duplicate_subgraph (l.objidx, index_map);
- }
- }
-
- /*
- * Creates a copy of node_idx and returns it's new index.
- */
- unsigned duplicate (unsigned node_idx)
- {
- positions_invalid = true;
- distance_invalid = true;
-
- auto* clone = vertices_.push ();
- auto& child = vertices_[node_idx];
- if (vertices_.in_error ()) {
- return -1;
- }
-
- clone->obj.head = child.obj.head;
- clone->obj.tail = child.obj.tail;
- clone->distance = child.distance;
- clone->space = child.space;
- clone->parents.reset ();
-
- unsigned clone_idx = vertices_.length - 2;
- for (const auto& l : child.obj.real_links)
- {
- clone->obj.real_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
- }
- for (const auto& l : child.obj.virtual_links)
- {
- clone->obj.virtual_links.push (l);
- vertices_[l.objidx].parents.push (clone_idx);
- }
-
- check_success (!clone->obj.real_links.in_error ());
- check_success (!clone->obj.virtual_links.in_error ());
-
- // The last object is the root of the graph, so swap back the root to the end.
- // The root's obj idx does change, however since it's root nothing else refers to it.
- // all other obj idx's will be unaffected.
- hb_swap (vertices_[vertices_.length - 2], *clone);
-
- // Since the root moved, update the parents arrays of all children on the root.
- for (const auto& l : root ().obj.all_links ())
- vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
-
- return clone_idx;
- }
-
- /*
- * Creates a copy of child and re-assigns the link from
- * parent to the clone. The copy is a shallow copy, objects
- * linked from child are not duplicated.
- */
- unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx)
- {
- unsigned new_idx = duplicate (parent_idx, child_idx);
- if (new_idx == (unsigned) -1) return child_idx;
- return new_idx;
- }
-
-
- /*
- * Creates a copy of child and re-assigns the link from
- * parent to the clone. The copy is a shallow copy, objects
- * linked from child are not duplicated.
- */
- unsigned duplicate (unsigned parent_idx, unsigned child_idx)
- {
- update_parents ();
-
- unsigned links_to_child = 0;
- for (const auto& l : vertices_[parent_idx].obj.all_links ())
- {
- if (l.objidx == child_idx) links_to_child++;
- }
-
- if (vertices_[child_idx].incoming_edges () <= links_to_child)
- {
- // Can't duplicate this node, doing so would orphan the original one as all remaining links
- // to child are from parent.
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u",
- parent_idx, child_idx);
- return -1;
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %u => %u",
- parent_idx, child_idx);
-
- unsigned clone_idx = duplicate (child_idx);
- if (clone_idx == (unsigned) -1) return false;
- // duplicate shifts the root node idx, so if parent_idx was root update it.
- if (parent_idx == clone_idx) parent_idx++;
-
- auto& parent = vertices_[parent_idx];
- for (auto& l : parent.obj.all_links_writer ())
- {
- if (l.objidx != child_idx)
- continue;
-
- reassign_link (l, parent_idx, clone_idx);
- }
-
- return clone_idx;
- }
-
-
- /*
- * Adds a new node to the graph, not connected to anything.
- */
- unsigned new_node (char* head, char* tail)
- {
- positions_invalid = true;
- distance_invalid = true;
-
- auto* clone = vertices_.push ();
- if (vertices_.in_error ()) {
- return -1;
- }
-
- clone->obj.head = head;
- clone->obj.tail = tail;
- clone->distance = 0;
- clone->space = 0;
-
- unsigned clone_idx = vertices_.length - 2;
-
- // The last object is the root of the graph, so swap back the root to the end.
- // The root's obj idx does change, however since it's root nothing else refers to it.
- // all other obj idx's will be unaffected.
- hb_swap (vertices_[vertices_.length - 2], *clone);
-
- // Since the root moved, update the parents arrays of all children on the root.
- for (const auto& l : root ().obj.all_links ())
- vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
-
- return clone_idx;
- }
-
- /*
- * Raises the sorting priority of all children.
- */
- bool raise_childrens_priority (unsigned parent_idx)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %u",
- parent_idx);
- // This operation doesn't change ordering until a sort is run, so no need
- // to invalidate positions. It does not change graph structure so no need
- // to update distances or edge counts.
- auto& parent = vertices_[parent_idx].obj;
- bool made_change = false;
- for (auto& l : parent.all_links_writer ())
- made_change |= vertices_[l.objidx].raise_priority ();
- return made_change;
- }
-
- bool is_fully_connected ()
- {
- update_parents();
-
- if (root().parents)
- // Root cannot have parents.
- return false;
-
- for (unsigned i = 0; i < root_idx (); i++)
- {
- if (!vertices_[i].parents)
- return false;
- }
- return true;
- }
-
-#if 0
- /*
- * Saves the current graph to a packed binary format which the repacker fuzzer takes
- * as a seed.
- */
- void save_fuzzer_seed (hb_tag_t tag) const
- {
- FILE* f = fopen ("./repacker_fuzzer_seed", "w");
- fwrite ((void*) &tag, sizeof (tag), 1, f);
-
- uint16_t num_objects = vertices_.length;
- fwrite ((void*) &num_objects, sizeof (num_objects), 1, f);
-
- for (const auto& v : vertices_)
- {
- uint16_t blob_size = v.table_size ();
- fwrite ((void*) &blob_size, sizeof (blob_size), 1, f);
- fwrite ((const void*) v.obj.head, blob_size, 1, f);
- }
-
- uint16_t link_count = 0;
- for (const auto& v : vertices_)
- link_count += v.obj.real_links.length;
-
- fwrite ((void*) &link_count, sizeof (link_count), 1, f);
-
- typedef struct
- {
- uint16_t parent;
- uint16_t child;
- uint16_t position;
- uint8_t width;
- } link_t;
-
- for (unsigned i = 0; i < vertices_.length; i++)
- {
- for (const auto& l : vertices_[i].obj.real_links)
- {
- link_t link {
- (uint16_t) i, (uint16_t) l.objidx,
- (uint16_t) l.position, (uint8_t) l.width
- };
- fwrite ((void*) &link, sizeof (link), 1, f);
- }
- }
-
- fclose (f);
- }
-#endif
-
- void print_orphaned_nodes ()
- {
- if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected.");
- parents_invalid = true;
- update_parents();
-
- if (root().parents) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
- }
-
- for (unsigned i = 0; i < root_idx (); i++)
- {
- const auto& v = vertices_[i];
- if (!v.parents)
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
- }
- }
-
- unsigned num_roots_for_space (unsigned space) const
- {
- return num_roots_for_space_[space];
- }
-
- unsigned next_space () const
- {
- return num_roots_for_space_.length;
- }
-
- void move_to_new_space (const hb_set_t& indices)
- {
- num_roots_for_space_.push (0);
- unsigned new_space = num_roots_for_space_.length - 1;
-
- for (unsigned index : indices) {
- auto& node = vertices_[index];
- num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
- num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1;
- node.space = new_space;
- distance_invalid = true;
- positions_invalid = true;
- }
- }
-
- unsigned space_for (unsigned index, unsigned* root = nullptr) const
- {
- const auto& node = vertices_[index];
- if (node.space)
- {
- if (root != nullptr)
- *root = index;
- return node.space;
- }
-
- if (!node.parents)
- {
- if (root)
- *root = index;
- return 0;
- }
-
- return space_for (node.parents[0], root);
- }
-
- void err_other_error () { this->successful = false; }
-
- size_t total_size_in_bytes () const {
- size_t total_size = 0;
- for (unsigned i = 0; i < vertices_.length; i++) {
- size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
- total_size += size;
- }
- return total_size;
- }
-
-
- private:
-
- /*
- * Returns the numbers of incoming edges that are 24 or 32 bits wide.
- */
- unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
- {
- unsigned count = 0;
- hb_set_t visited;
- for (unsigned p : vertices_[node_idx].parents)
- {
- if (visited.has (p)) continue;
- visited.add (p);
-
- // Only real links can be wide
- for (const auto& l : vertices_[p].obj.real_links)
- {
- if (l.objidx == node_idx
- && (l.width == 3 || l.width == 4)
- && !l.is_signed)
- {
- count++;
- parents.add (p);
- }
- }
- }
- return count;
- }
-
- bool check_success (bool success)
- { return this->successful && (success || ((void) err_other_error (), false)); }
-
- public:
- /*
- * Creates a map from objid to # of incoming edges.
- */
- void update_parents ()
- {
- if (!parents_invalid) return;
-
- for (unsigned i = 0; i < vertices_.length; i++)
- vertices_[i].parents.reset ();
-
- for (unsigned p = 0; p < vertices_.length; p++)
- {
- for (auto& l : vertices_[p].obj.all_links ())
- {
- vertices_[l.objidx].parents.push (p);
- }
- }
-
- for (unsigned i = 0; i < vertices_.length; i++)
- // parents arrays must be accurate or downstream operations like cycle detection
- // and sorting won't work correctly.
- check_success (!vertices_[i].parents.in_error ());
-
- parents_invalid = false;
- }
-
- /*
- * compute the serialized start and end positions for each vertex.
- */
- void update_positions ()
- {
- if (!positions_invalid) return;
-
- unsigned current_pos = 0;
- for (int i = root_idx (); i >= 0; i--)
- {
- auto& v = vertices_[i];
- v.start = current_pos;
- current_pos += v.obj.tail - v.obj.head;
- v.end = current_pos;
- }
-
- positions_invalid = false;
- }
-
- /*
- * Finds the distance to each object in the graph
- * from the initial node.
- */
- void update_distances ()
- {
- if (!distance_invalid) return;
-
- // Uses Dijkstra's algorithm to find all of the shortest distances.
- // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
- //
- // Implementation Note:
- // Since our priority queue doesn't support fast priority decreases
- // we instead just add new entries into the queue when a priority changes.
- // Redundant ones are filtered out later on by the visited set.
- // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
- // for practical performance this is faster then using a more advanced queue
- // (such as a fibonacci queue) with a fast decrease priority.
- for (unsigned i = 0; i < vertices_.length; i++)
- {
- if (i == vertices_.length - 1)
- vertices_[i].distance = 0;
- else
- vertices_[i].distance = hb_int_max (int64_t);
- }
-
- hb_priority_queue_t queue;
- queue.insert (0, vertices_.length - 1);
-
- hb_vector_t<bool> visited;
- visited.resize (vertices_.length);
-
- while (!queue.in_error () && !queue.is_empty ())
- {
- unsigned next_idx = queue.pop_minimum ().second;
- if (visited[next_idx]) continue;
- const auto& next = vertices_[next_idx];
- int64_t next_distance = vertices_[next_idx].distance;
- visited[next_idx] = true;
-
- for (const auto& link : next.obj.all_links ())
- {
- if (visited[link.objidx]) continue;
-
- const auto& child = vertices_[link.objidx].obj;
- unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
- int64_t child_weight = (child.tail - child.head) +
- ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
- int64_t child_distance = next_distance + child_weight;
-
- if (child_distance < vertices_[link.objidx].distance)
- {
- vertices_[link.objidx].distance = child_distance;
- queue.insert (child_distance, link.objidx);
- }
- }
- }
-
- check_success (!queue.in_error ());
- if (!check_success (queue.is_empty ()))
- {
- print_orphaned_nodes ();
- return;
- }
-
- distance_invalid = false;
- }
-
- private:
- /*
- * Updates a link in the graph to point to a different object. Corrects the
- * parents vector on the previous and new child nodes.
- */
- void reassign_link (hb_serialize_context_t::object_t::link_t& link,
- unsigned parent_idx,
- unsigned new_idx)
- {
- unsigned old_idx = link.objidx;
- link.objidx = new_idx;
- vertices_[old_idx].remove_parent (parent_idx);
- vertices_[new_idx].parents.push (parent_idx);
- }
-
- /*
- * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts.
- */
- template<typename Iterator, hb_requires (hb_is_iterator (Iterator))>
- void remap_obj_indices (const hb_map_t& id_map,
- Iterator subgraph,
- bool only_wide = false)
- {
- if (!id_map) return;
- for (unsigned i : subgraph)
- {
- for (auto& link : vertices_[i].obj.all_links_writer ())
- {
- const uint32_t *v;
- if (!id_map.has (link.objidx, &v)) continue;
- if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
-
- reassign_link (link, i, *v);
- }
- }
- }
-
- /*
- * Updates all objidx's in all links using the provided mapping.
- */
- void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
- hb_vector_t<vertex_t>* sorted_graph) const
- {
- for (unsigned i = 0; i < sorted_graph->length; i++)
- {
- (*sorted_graph)[i].remap_parents (id_map);
- for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
- {
- link.objidx = id_map[link.objidx];
- }
- }
- }
-
- /*
- * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped.
- * For this search the graph is treated as being undirected.
- *
- * Connected targets will be added to connected and removed from targets. All visited nodes
- * will be added to visited.
- */
- void find_connected_nodes (unsigned start_idx,
- hb_set_t& targets,
- hb_set_t& visited,
- hb_set_t& connected)
- {
- if (unlikely (!check_success (!visited.in_error ()))) return;
- if (visited.has (start_idx)) return;
- visited.add (start_idx);
-
- if (targets.has (start_idx))
- {
- targets.del (start_idx);
- connected.add (start_idx);
- }
-
- const auto& v = vertices_[start_idx];
-
- // Graph is treated as undirected so search children and parents of start_idx
- for (const auto& l : v.obj.all_links ())
- find_connected_nodes (l.objidx, targets, visited, connected);
-
- for (unsigned p : v.parents)
- find_connected_nodes (p, targets, visited, connected);
- }
-
- public:
- // TODO(garretrieger): make private, will need to move most of offset overflow code into graph.
- hb_vector_t<vertex_t> vertices_;
- hb_vector_t<vertex_t> vertices_scratch_;
- private:
- bool parents_invalid;
- bool distance_invalid;
- bool positions_invalid;
- bool successful;
- hb_vector_t<unsigned> num_roots_for_space_;
- hb_vector_t<char*> buffers;
-};
-
-}
-
-#endif // GRAPH_GRAPH_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.cc b/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.cc
deleted file mode 100644
index b2044426d46..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "gsubgpos-graph.hh"
-
-namespace graph {
-
-gsubgpos_graph_context_t::gsubgpos_graph_context_t (hb_tag_t table_tag_,
- graph_t& graph_)
- : table_tag (table_tag_),
- graph (graph_),
- lookup_list_index (0),
- lookups ()
-{
- if (table_tag_ != HB_OT_TAG_GPOS
- && table_tag_ != HB_OT_TAG_GSUB)
- return;
-
- GSTAR* gstar = graph::GSTAR::graph_to_gstar (graph_);
- if (gstar) {
- gstar->find_lookups (graph, lookups);
- lookup_list_index = gstar->get_lookup_list_index (graph_);
- }
-}
-
-unsigned gsubgpos_graph_context_t::create_node (unsigned size)
-{
- char* buffer = (char*) hb_calloc (1, size);
- if (!buffer)
- return -1;
-
- add_buffer (buffer);
-
- return graph.new_node (buffer, buffer + size);
-}
-
-unsigned gsubgpos_graph_context_t::num_non_ext_subtables () {
- unsigned count = 0;
- for (auto l : lookups.values ())
- {
- if (l->is_extension (table_tag)) continue;
- count += l->number_of_subtables ();
- }
- return count;
-}
-
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.hh b/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.hh
deleted file mode 100644
index 9fe9662e645..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-context.hh
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "graph.hh"
-#include "../hb-ot-layout-gsubgpos.hh"
-
-#ifndef GRAPH_GSUBGPOS_CONTEXT_HH
-#define GRAPH_GSUBGPOS_CONTEXT_HH
-
-namespace graph {
-
-struct Lookup;
-
-struct gsubgpos_graph_context_t
-{
- hb_tag_t table_tag;
- graph_t& graph;
- unsigned lookup_list_index;
- hb_hashmap_t<unsigned, graph::Lookup*> lookups;
-
-
- HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_,
- graph_t& graph_);
-
- HB_INTERNAL unsigned create_node (unsigned size);
-
- void add_buffer (char* buffer)
- {
- graph.add_buffer (buffer);
- }
-
- private:
- HB_INTERNAL unsigned num_non_ext_subtables ();
-};
-
-}
-
-#endif // GRAPH_GSUBGPOS_CONTEXT
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh
deleted file mode 100644
index c170638409f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/gsubgpos-graph.hh
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "graph.hh"
-#include "../hb-ot-layout-gsubgpos.hh"
-#include "../OT/Layout/GSUB/ExtensionSubst.hh"
-#include "gsubgpos-context.hh"
-#include "pairpos-graph.hh"
-#include "markbasepos-graph.hh"
-
-#ifndef GRAPH_GSUBGPOS_GRAPH_HH
-#define GRAPH_GSUBGPOS_GRAPH_HH
-
-namespace graph {
-
-struct Lookup;
-
-template<typename T>
-struct ExtensionFormat1 : public OT::ExtensionFormat1<T>
-{
- void reset(unsigned type)
- {
- this->format = 1;
- this->extensionLookupType = type;
- this->extensionOffset = 0;
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- return vertex_len >= OT::ExtensionFormat1<T>::static_size;
- }
-
- unsigned get_lookup_type () const
- {
- return this->extensionLookupType;
- }
-
- unsigned get_subtable_index (graph_t& graph, unsigned this_index) const
- {
- return graph.index_for_offset (this_index, &this->extensionOffset);
- }
-};
-
-struct Lookup : public OT::Lookup
-{
- unsigned number_of_subtables () const
- {
- return subTable.len;
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < OT::Lookup::min_size) return false;
- return vertex_len >= this->get_size ();
- }
-
- bool is_extension (hb_tag_t table_tag) const
- {
- return lookupType == extension_type (table_tag);
- }
-
- bool make_extension (gsubgpos_graph_context_t& c,
- unsigned this_index)
- {
- unsigned type = lookupType;
- unsigned ext_type = extension_type (c.table_tag);
- if (!ext_type || is_extension (c.table_tag))
- {
- // NOOP
- return true;
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Promoting lookup type %u (obj %u) to extension.",
- type,
- this_index);
-
- for (unsigned i = 0; i < subTable.len; i++)
- {
- unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]);
- if (!make_subtable_extension (c,
- this_index,
- subtable_index))
- return false;
- }
-
- lookupType = ext_type;
- return true;
- }
-
- bool split_subtables_if_needed (gsubgpos_graph_context_t& c,
- unsigned this_index)
- {
- unsigned type = lookupType;
- bool is_ext = is_extension (c.table_tag);
-
- if (c.table_tag != HB_OT_TAG_GPOS)
- return true;
-
- if (!is_ext &&
- type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair &&
- type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase)
- return true;
-
- hb_vector_t<hb_pair_t<unsigned, hb_vector_t<unsigned>>> all_new_subtables;
- for (unsigned i = 0; i < subTable.len; i++)
- {
- unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]);
- unsigned parent_index = this_index;
- if (is_ext) {
- unsigned ext_subtable_index = subtable_index;
- parent_index = ext_subtable_index;
- ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
- (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*)
- c.graph.object (ext_subtable_index).head;
- if (!extension || !extension->sanitize (c.graph.vertices_[ext_subtable_index]))
- continue;
-
- subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index);
- type = extension->get_lookup_type ();
- if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair
- && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase)
- continue;
- }
-
- hb_vector_t<unsigned> new_sub_tables;
- switch (type)
- {
- case 2:
- new_sub_tables = split_subtable<PairPos> (c, parent_index, subtable_index); break;
- case 4:
- new_sub_tables = split_subtable<MarkBasePos> (c, parent_index, subtable_index); break;
- default:
- break;
- }
- if (new_sub_tables.in_error ()) return false;
- if (!new_sub_tables) continue;
- hb_pair_t<unsigned, hb_vector_t<unsigned>>* entry = all_new_subtables.push ();
- entry->first = i;
- entry->second = std::move (new_sub_tables);
- }
-
- if (all_new_subtables) {
- add_sub_tables (c, this_index, type, all_new_subtables);
- }
-
- return true;
- }
-
- template<typename T>
- hb_vector_t<unsigned> split_subtable (gsubgpos_graph_context_t& c,
- unsigned parent_idx,
- unsigned objidx)
- {
- T* sub_table = (T*) c.graph.object (objidx).head;
- if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx]))
- return hb_vector_t<unsigned> ();
-
- return sub_table->split_subtables (c, parent_idx, objidx);
- }
-
- void add_sub_tables (gsubgpos_graph_context_t& c,
- unsigned this_index,
- unsigned type,
- hb_vector_t<hb_pair_t<unsigned, hb_vector_t<unsigned>>>& subtable_ids)
- {
- bool is_ext = is_extension (c.table_tag);
- auto& v = c.graph.vertices_[this_index];
- fix_existing_subtable_links (c, this_index, subtable_ids);
-
- unsigned new_subtable_count = 0;
- for (const auto& p : subtable_ids)
- new_subtable_count += p.second.length;
-
- size_t new_size = v.table_size ()
- + new_subtable_count * OT::Offset16::static_size;
- char* buffer = (char*) hb_calloc (1, new_size);
- c.add_buffer (buffer);
- hb_memcpy (buffer, v.obj.head, v.table_size());
-
- v.obj.head = buffer;
- v.obj.tail = buffer + new_size;
-
- Lookup* new_lookup = (Lookup*) buffer;
-
- unsigned shift = 0;
- new_lookup->subTable.len = subTable.len + new_subtable_count;
- for (const auto& p : subtable_ids)
- {
- unsigned offset_index = p.first + shift + 1;
- shift += p.second.length;
-
- for (unsigned subtable_id : p.second)
- {
- if (is_ext)
- {
- unsigned ext_id = create_extension_subtable (c, subtable_id, type);
- c.graph.vertices_[subtable_id].parents.push (ext_id);
- subtable_id = ext_id;
- }
-
- auto* link = v.obj.real_links.push ();
- link->width = 2;
- link->objidx = subtable_id;
- link->position = (char*) &new_lookup->subTable[offset_index++] -
- (char*) new_lookup;
- c.graph.vertices_[subtable_id].parents.push (this_index);
- }
- }
-
- // Repacker sort order depends on link order, which we've messed up so resort it.
- v.obj.real_links.qsort ();
-
- // The head location of the lookup has changed, invalidating the lookups map entry
- // in the context. Update the map.
- c.lookups.set (this_index, new_lookup);
- }
-
- void fix_existing_subtable_links (gsubgpos_graph_context_t& c,
- unsigned this_index,
- hb_vector_t<hb_pair_t<unsigned, hb_vector_t<unsigned>>>& subtable_ids)
- {
- auto& v = c.graph.vertices_[this_index];
- Lookup* lookup = (Lookup*) v.obj.head;
-
- unsigned shift = 0;
- for (const auto& p : subtable_ids)
- {
- unsigned insert_index = p.first + shift;
- unsigned pos_offset = p.second.length * OT::Offset16::static_size;
- unsigned insert_offset = (char*) &lookup->subTable[insert_index] - (char*) lookup;
- shift += p.second.length;
-
- for (auto& l : v.obj.all_links_writer ())
- {
- if (l.position > insert_offset) l.position += pos_offset;
- }
- }
- }
-
- unsigned create_extension_subtable (gsubgpos_graph_context_t& c,
- unsigned subtable_index,
- unsigned type)
- {
- unsigned extension_size = OT::ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>::static_size;
-
- unsigned ext_index = c.create_node (extension_size);
- if (ext_index == (unsigned) -1)
- return -1;
-
- auto& ext_vertex = c.graph.vertices_[ext_index];
- ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
- (ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*) ext_vertex.obj.head;
- extension->reset (type);
-
- // Make extension point at the subtable.
- auto* l = ext_vertex.obj.real_links.push ();
-
- l->width = 4;
- l->objidx = subtable_index;
- l->position = 4;
-
- return ext_index;
- }
-
- bool make_subtable_extension (gsubgpos_graph_context_t& c,
- unsigned lookup_index,
- unsigned subtable_index)
- {
- unsigned type = lookupType;
-
- unsigned ext_index = create_extension_subtable(c, subtable_index, type);
- if (ext_index == (unsigned) -1)
- return false;
-
- auto& lookup_vertex = c.graph.vertices_[lookup_index];
- for (auto& l : lookup_vertex.obj.real_links.writer ())
- {
- if (l.objidx == subtable_index)
- // Change lookup to point at the extension.
- l.objidx = ext_index;
- }
-
- // Make extension point at the subtable.
- auto& ext_vertex = c.graph.vertices_[ext_index];
- auto& subtable_vertex = c.graph.vertices_[subtable_index];
- ext_vertex.parents.push (lookup_index);
- subtable_vertex.remap_parent (lookup_index, ext_index);
-
- return true;
- }
-
- private:
- unsigned extension_type (hb_tag_t table_tag) const
- {
- switch (table_tag)
- {
- case HB_OT_TAG_GPOS: return 9;
- case HB_OT_TAG_GSUB: return 7;
- default: return 0;
- }
- }
-};
-
-template <typename T>
-struct LookupList : public OT::LookupList<T>
-{
- bool sanitize (const graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < OT::LookupList<T>::min_size) return false;
- return vertex_len >= OT::LookupList<T>::item_size * this->len;
- }
-};
-
-struct GSTAR : public OT::GSUBGPOS
-{
- static GSTAR* graph_to_gstar (graph_t& graph)
- {
- const auto& r = graph.root ();
-
- GSTAR* gstar = (GSTAR*) r.obj.head;
- if (!gstar || !gstar->sanitize (r))
- return nullptr;
-
- return gstar;
- }
-
- const void* get_lookup_list_field_offset () const
- {
- switch (u.version.major) {
- case 1: return u.version1.get_lookup_list_offset ();
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.get_lookup_list_offset ();
-#endif
- default: return 0;
- }
- }
-
- bool sanitize (const graph_t::vertex_t& vertex)
- {
- int64_t len = vertex.obj.tail - vertex.obj.head;
- if (len < OT::GSUBGPOS::min_size) return false;
- return len >= get_size ();
- }
-
- void find_lookups (graph_t& graph,
- hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */)
- {
- switch (u.version.major) {
- case 1: find_lookups<SmallTypes> (graph, lookups); break;
-#ifndef HB_NO_BEYOND_64K
- case 2: find_lookups<MediumTypes> (graph, lookups); break;
-#endif
- }
- }
-
- unsigned get_lookup_list_index (graph_t& graph)
- {
- return graph.index_for_offset (graph.root_idx (),
- get_lookup_list_field_offset());
- }
-
- template<typename Types>
- void find_lookups (graph_t& graph,
- hb_hashmap_t<unsigned, Lookup*>& lookups /* OUT */)
- {
- unsigned lookup_list_idx = get_lookup_list_index (graph);
- const LookupList<Types>* lookupList =
- (const LookupList<Types>*) graph.object (lookup_list_idx).head;
- if (!lookupList || !lookupList->sanitize (graph.vertices_[lookup_list_idx]))
- return;
-
- for (unsigned i = 0; i < lookupList->len; i++)
- {
- unsigned lookup_idx = graph.index_for_offset (lookup_list_idx, &(lookupList->arrayZ[i]));
- Lookup* lookup = (Lookup*) graph.object (lookup_idx).head;
- if (!lookup || !lookup->sanitize (graph.vertices_[lookup_idx])) continue;
- lookups.set (lookup_idx, lookup);
- }
- }
-};
-
-
-
-
-}
-
-#endif /* GRAPH_GSUBGPOS_GRAPH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh
deleted file mode 100644
index 84ef5f71b93..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#ifndef GRAPH_MARKBASEPOS_GRAPH_HH
-#define GRAPH_MARKBASEPOS_GRAPH_HH
-
-#include "split-helpers.hh"
-#include "coverage-graph.hh"
-#include "../OT/Layout/GPOS/MarkBasePos.hh"
-#include "../OT/Layout/GPOS/PosLookupSubTable.hh"
-
-namespace graph {
-
-struct AnchorMatrix : public OT::Layout::GPOS_impl::AnchorMatrix
-{
- bool sanitize (graph_t::vertex_t& vertex, unsigned class_count) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < AnchorMatrix::min_size) return false;
-
- return vertex_len >= AnchorMatrix::min_size +
- OT::Offset16::static_size * class_count * this->rows;
- }
-
- bool shrink (gsubgpos_graph_context_t& c,
- unsigned this_index,
- unsigned old_class_count,
- unsigned new_class_count)
- {
- if (new_class_count >= old_class_count) return false;
- auto& o = c.graph.vertices_[this_index].obj;
- unsigned base_count = rows;
- o.tail = o.head +
- AnchorMatrix::min_size +
- OT::Offset16::static_size * base_count * new_class_count;
-
- // Reposition links into the new indexing scheme.
- for (auto& link : o.real_links.writer ())
- {
- unsigned index = (link.position - 2) / 2;
- unsigned base = index / old_class_count;
- unsigned klass = index % old_class_count;
- if (klass >= new_class_count)
- // should have already been removed
- return false;
-
- unsigned new_index = base * new_class_count + klass;
-
- link.position = (char*) &(this->matrixZ[new_index]) - (char*) this;
- }
-
- return true;
- }
-
- unsigned clone (gsubgpos_graph_context_t& c,
- unsigned this_index,
- unsigned start,
- unsigned end,
- unsigned class_count)
- {
- unsigned base_count = rows;
- unsigned new_class_count = end - start;
- unsigned size = AnchorMatrix::min_size +
- OT::Offset16::static_size * new_class_count * rows;
- unsigned prime_id = c.create_node (size);
- if (prime_id == (unsigned) -1) return -1;
- AnchorMatrix* prime = (AnchorMatrix*) c.graph.object (prime_id).head;
- prime->rows = base_count;
-
- auto& o = c.graph.vertices_[this_index].obj;
- int num_links = o.real_links.length;
- for (int i = 0; i < num_links; i++)
- {
- const auto& link = o.real_links[i];
- unsigned old_index = (link.position - 2) / OT::Offset16::static_size;
- unsigned klass = old_index % class_count;
- if (klass < start || klass >= end) continue;
-
- unsigned base = old_index / class_count;
- unsigned new_klass = klass - start;
- unsigned new_index = base * new_class_count + new_klass;
-
-
- unsigned child_idx = link.objidx;
- c.graph.add_link (&(prime->matrixZ[new_index]),
- prime_id,
- child_idx);
-
- auto& child = c.graph.vertices_[child_idx];
- child.remove_parent (this_index);
-
- o.real_links.remove_unordered (i);
- num_links--;
- i--;
- }
-
- return prime_id;
- }
-};
-
-struct MarkArray : public OT::Layout::GPOS_impl::MarkArray
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- unsigned min_size = MarkArray::min_size;
- if (vertex_len < min_size) return false;
-
- return vertex_len >= get_size ();
- }
-
- bool shrink (gsubgpos_graph_context_t& c,
- const hb_hashmap_t<unsigned, unsigned>& mark_array_links,
- unsigned this_index,
- unsigned new_class_count)
- {
- auto& o = c.graph.vertices_[this_index].obj;
- for (const auto& link : o.real_links)
- c.graph.vertices_[link.objidx].remove_parent (this_index);
- o.real_links.reset ();
-
- unsigned new_index = 0;
- for (const auto& record : this->iter ())
- {
- unsigned klass = record.klass;
- if (klass >= new_class_count) continue;
-
- (*this)[new_index].klass = klass;
- unsigned position = (char*) &record.markAnchor - (char*) this;
- unsigned* objidx;
- if (!mark_array_links.has (position, &objidx))
- {
- new_index++;
- continue;
- }
-
- c.graph.add_link (&(*this)[new_index].markAnchor, this_index, *objidx);
- new_index++;
- }
-
- this->len = new_index;
- o.tail = o.head + MarkArray::min_size +
- OT::Layout::GPOS_impl::MarkRecord::static_size * new_index;
- return true;
- }
-
- unsigned clone (gsubgpos_graph_context_t& c,
- unsigned this_index,
- const hb_hashmap_t<unsigned, unsigned>& pos_to_index,
- hb_set_t& marks,
- unsigned start_class)
- {
- unsigned size = MarkArray::min_size +
- OT::Layout::GPOS_impl::MarkRecord::static_size *
- marks.get_population ();
- unsigned prime_id = c.create_node (size);
- if (prime_id == (unsigned) -1) return -1;
- MarkArray* prime = (MarkArray*) c.graph.object (prime_id).head;
- prime->len = marks.get_population ();
-
-
- unsigned i = 0;
- for (hb_codepoint_t mark : marks)
- {
- (*prime)[i].klass = (*this)[mark].klass - start_class;
- unsigned offset_pos = (char*) &((*this)[mark].markAnchor) - (char*) this;
- unsigned* anchor_index;
- if (pos_to_index.has (offset_pos, &anchor_index))
- c.graph.move_child (this_index,
- &((*this)[mark].markAnchor),
- prime_id,
- &((*prime)[i].markAnchor));
-
- i++;
- }
-
- return prime_id;
- }
-};
-
-struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- return vertex_len >= MarkBasePosFormat1::static_size;
- }
-
- hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
- unsigned parent_index,
- unsigned this_index)
- {
- hb_set_t visited;
-
- const unsigned base_coverage_id = c.graph.index_for_offset (this_index, &baseCoverage);
- const unsigned base_size =
- OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size +
- MarkArray::min_size +
- AnchorMatrix::min_size +
- c.graph.vertices_[base_coverage_id].table_size ();
-
- hb_vector_t<class_info_t> class_to_info = get_class_info (c, this_index);
-
- unsigned class_count = classCount;
- auto base_array = c.graph.as_table<AnchorMatrix> (this_index,
- &baseArray,
- class_count);
- if (!base_array) return hb_vector_t<unsigned> ();
- unsigned base_count = base_array.table->rows;
-
- unsigned partial_coverage_size = 4;
- unsigned accumulated = base_size;
- hb_vector_t<unsigned> split_points;
-
- for (unsigned klass = 0; klass < class_count; klass++)
- {
- class_info_t& info = class_to_info[klass];
- partial_coverage_size += OT::HBUINT16::static_size * info.marks.get_population ();
- unsigned accumulated_delta =
- OT::Layout::GPOS_impl::MarkRecord::static_size * info.marks.get_population () +
- OT::Offset16::static_size * base_count;
-
- for (unsigned objidx : info.child_indices)
- accumulated_delta += c.graph.find_subgraph_size (objidx, visited);
-
- accumulated += accumulated_delta;
- unsigned total = accumulated + partial_coverage_size;
-
- if (total >= (1 << 16))
- {
- split_points.push (klass);
- accumulated = base_size + accumulated_delta;
- partial_coverage_size = 4 + OT::HBUINT16::static_size * info.marks.get_population ();
- visited.clear (); // node sharing isn't allowed between splits.
- }
- }
-
-
- const unsigned mark_array_id = c.graph.index_for_offset (this_index, &markArray);
- split_context_t split_context {
- c,
- this,
- c.graph.duplicate_if_shared (parent_index, this_index),
- std::move (class_to_info),
- c.graph.vertices_[mark_array_id].position_to_index_map (),
- };
-
- return actuate_subtable_split<split_context_t> (split_context, split_points);
- }
-
- private:
-
- struct class_info_t {
- hb_set_t marks;
- hb_vector_t<unsigned> child_indices;
- };
-
- struct split_context_t {
- gsubgpos_graph_context_t& c;
- MarkBasePosFormat1* thiz;
- unsigned this_index;
- hb_vector_t<class_info_t> class_to_info;
- hb_hashmap_t<unsigned, unsigned> mark_array_links;
-
- hb_set_t marks_for (unsigned start, unsigned end)
- {
- hb_set_t marks;
- for (unsigned klass = start; klass < end; klass++)
- {
- + class_to_info[klass].marks.iter ()
- | hb_sink (marks)
- ;
- }
- return marks;
- }
-
- unsigned original_count ()
- {
- return thiz->classCount;
- }
-
- unsigned clone_range (unsigned start, unsigned end)
- {
- return thiz->clone_range (*this, this->this_index, start, end);
- }
-
- bool shrink (unsigned count)
- {
- return thiz->shrink (*this, this->this_index, count);
- }
- };
-
- hb_vector_t<class_info_t> get_class_info (gsubgpos_graph_context_t& c,
- unsigned this_index)
- {
- hb_vector_t<class_info_t> class_to_info;
-
- unsigned class_count= classCount;
- class_to_info.resize (class_count);
-
- auto mark_array = c.graph.as_table<MarkArray> (this_index, &markArray);
- if (!mark_array) return hb_vector_t<class_info_t> ();
- unsigned mark_count = mark_array.table->len;
- for (unsigned mark = 0; mark < mark_count; mark++)
- {
- unsigned klass = (*mark_array.table)[mark].get_class ();
- class_to_info[klass].marks.add (mark);
- }
-
- for (const auto& link : mark_array.vertex->obj.real_links)
- {
- unsigned mark = (link.position - 2) /
- OT::Layout::GPOS_impl::MarkRecord::static_size;
- unsigned klass = (*mark_array.table)[mark].get_class ();
- class_to_info[klass].child_indices.push (link.objidx);
- }
-
- unsigned base_array_id =
- c.graph.index_for_offset (this_index, &baseArray);
- auto& base_array_v = c.graph.vertices_[base_array_id];
-
- for (const auto& link : base_array_v.obj.real_links)
- {
- unsigned index = (link.position - 2) / OT::Offset16::static_size;
- unsigned klass = index % class_count;
- class_to_info[klass].child_indices.push (link.objidx);
- }
-
- return class_to_info;
- }
-
- bool shrink (split_context_t& sc,
- unsigned this_index,
- unsigned count)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Shrinking MarkBasePosFormat1 (%u) to [0, %u).",
- this_index,
- count);
-
- unsigned old_count = classCount;
- if (count >= old_count)
- return true;
-
- classCount = count;
-
- auto mark_coverage = sc.c.graph.as_mutable_table<Coverage> (this_index,
- &markCoverage);
- if (!mark_coverage) return false;
- hb_set_t marks = sc.marks_for (0, count);
- auto new_coverage =
- + hb_enumerate (mark_coverage.table->iter ())
- | hb_filter (marks, hb_first)
- | hb_map_retains_sorting (hb_second)
- ;
- if (!Coverage::make_coverage (sc.c, + new_coverage,
- mark_coverage.index,
- 4 + 2 * marks.get_population ()))
- return false;
-
-
- auto base_array = sc.c.graph.as_mutable_table<AnchorMatrix> (this_index,
- &baseArray,
- old_count);
- if (!base_array || !base_array.table->shrink (sc.c,
- base_array.index,
- old_count,
- count))
- return false;
-
- auto mark_array = sc.c.graph.as_mutable_table<MarkArray> (this_index,
- &markArray);
- if (!mark_array || !mark_array.table->shrink (sc.c,
- sc.mark_array_links,
- mark_array.index,
- count))
- return false;
-
- return true;
- }
-
- // Create a new MarkBasePos that has all of the data for classes from [start, end).
- unsigned clone_range (split_context_t& sc,
- unsigned this_index,
- unsigned start, unsigned end) const
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Cloning MarkBasePosFormat1 (%u) range [%u, %u).", this_index, start, end);
-
- graph_t& graph = sc.c.graph;
- unsigned prime_size = OT::Layout::GPOS_impl::MarkBasePosFormat1_2<SmallTypes>::static_size;
-
- unsigned prime_id = sc.c.create_node (prime_size);
- if (prime_id == (unsigned) -1) return -1;
-
- MarkBasePosFormat1* prime = (MarkBasePosFormat1*) graph.object (prime_id).head;
- prime->format = this->format;
- unsigned new_class_count = end - start;
- prime->classCount = new_class_count;
-
- unsigned base_coverage_id =
- graph.index_for_offset (sc.this_index, &baseCoverage);
- graph.add_link (&(prime->baseCoverage), prime_id, base_coverage_id);
- graph.duplicate (prime_id, base_coverage_id);
-
- auto mark_coverage = sc.c.graph.as_table<Coverage> (this_index,
- &markCoverage);
- if (!mark_coverage) return false;
- hb_set_t marks = sc.marks_for (start, end);
- auto new_coverage =
- + hb_enumerate (mark_coverage.table->iter ())
- | hb_filter (marks, hb_first)
- | hb_map_retains_sorting (hb_second)
- ;
- if (!Coverage::add_coverage (sc.c,
- prime_id,
- 2,
- + new_coverage,
- marks.get_population () * 2 + 4))
- return -1;
-
- auto mark_array =
- graph.as_table <MarkArray> (sc.this_index, &markArray);
- if (!mark_array) return -1;
- unsigned new_mark_array =
- mark_array.table->clone (sc.c,
- mark_array.index,
- sc.mark_array_links,
- marks,
- start);
- graph.add_link (&(prime->markArray), prime_id, new_mark_array);
-
- unsigned class_count = classCount;
- auto base_array =
- graph.as_table<AnchorMatrix> (sc.this_index, &baseArray, class_count);
- if (!base_array) return -1;
- unsigned new_base_array =
- base_array.table->clone (sc.c,
- base_array.index,
- start, end, this->classCount);
- graph.add_link (&(prime->baseArray), prime_id, new_base_array);
-
- return prime_id;
- }
-};
-
-
-struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos
-{
- hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
- unsigned parent_index,
- unsigned this_index)
- {
- switch (u.format) {
- case 1:
- return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BEYOND_64K
- case 2: HB_FALLTHROUGH;
- // Don't split 24bit PairPos's.
-#endif
- default:
- return hb_vector_t<unsigned> ();
- }
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < u.format.get_size ()) return false;
-
- switch (u.format) {
- case 1:
- return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex);
-#ifndef HB_NO_BEYOND_64K
- case 2: HB_FALLTHROUGH;
-#endif
- default:
- // We don't handle format 3 and 4 here.
- return false;
- }
- }
-};
-
-
-}
-
-#endif // GRAPH_MARKBASEPOS_GRAPH_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh
deleted file mode 100644
index 1c13eb24f94..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/pairpos-graph.hh
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#ifndef GRAPH_PAIRPOS_GRAPH_HH
-#define GRAPH_PAIRPOS_GRAPH_HH
-
-#include "split-helpers.hh"
-#include "coverage-graph.hh"
-#include "classdef-graph.hh"
-#include "../OT/Layout/GPOS/PairPos.hh"
-#include "../OT/Layout/GPOS/PosLookupSubTable.hh"
-
-namespace graph {
-
-struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
-
- return vertex_len >=
- min_size + pairSet.get_size () - pairSet.len.get_size();
- }
-
- hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
- unsigned parent_index,
- unsigned this_index)
- {
- hb_set_t visited;
-
- const unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage);
- const unsigned coverage_size = c.graph.vertices_[coverage_id].table_size ();
- const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size;
-
- unsigned partial_coverage_size = 4;
- unsigned accumulated = base_size;
- hb_vector_t<unsigned> split_points;
- for (unsigned i = 0; i < pairSet.len; i++)
- {
- unsigned pair_set_index = pair_set_graph_index (c, this_index, i);
- unsigned accumulated_delta =
- c.graph.find_subgraph_size (pair_set_index, visited) +
- SmallTypes::size; // for PairSet offset.
- partial_coverage_size += OT::HBUINT16::static_size;
-
- accumulated += accumulated_delta;
- unsigned total = accumulated + hb_min (partial_coverage_size, coverage_size);
-
- if (total >= (1 << 16))
- {
- split_points.push (i);
- accumulated = base_size + accumulated_delta;
- partial_coverage_size = 6;
- visited.clear (); // node sharing isn't allowed between splits.
- }
- }
-
- split_context_t split_context {
- c,
- this,
- c.graph.duplicate_if_shared (parent_index, this_index),
- };
-
- return actuate_subtable_split<split_context_t> (split_context, split_points);
- }
-
- private:
-
- struct split_context_t {
- gsubgpos_graph_context_t& c;
- PairPosFormat1* thiz;
- unsigned this_index;
-
- unsigned original_count ()
- {
- return thiz->pairSet.len;
- }
-
- unsigned clone_range (unsigned start, unsigned end)
- {
- return thiz->clone_range (this->c, this->this_index, start, end);
- }
-
- bool shrink (unsigned count)
- {
- return thiz->shrink (this->c, this->this_index, count);
- }
- };
-
- bool shrink (gsubgpos_graph_context_t& c,
- unsigned this_index,
- unsigned count)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Shrinking PairPosFormat1 (%u) to [0, %u).",
- this_index,
- count);
- unsigned old_count = pairSet.len;
- if (count >= old_count)
- return true;
-
- pairSet.len = count;
- c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size;
-
- auto coverage = c.graph.as_mutable_table<Coverage> (this_index, &this->coverage);
- if (!coverage) return false;
-
- unsigned coverage_size = coverage.vertex->table_size ();
- auto new_coverage =
- + hb_zip (coverage.table->iter (), hb_range ())
- | hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
- return p.second < count;
- })
- | hb_map_retains_sorting (hb_first)
- ;
-
- return Coverage::make_coverage (c, new_coverage, coverage.index, coverage_size);
- }
-
- // Create a new PairPos including PairSet's from start (inclusive) to end (exclusive).
- // Returns object id of the new object.
- unsigned clone_range (gsubgpos_graph_context_t& c,
- unsigned this_index,
- unsigned start, unsigned end) const
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Cloning PairPosFormat1 (%u) range [%u, %u).", this_index, start, end);
-
- unsigned num_pair_sets = end - start;
- unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size
- + num_pair_sets * SmallTypes::size;
-
- unsigned pair_pos_prime_id = c.create_node (prime_size);
- if (pair_pos_prime_id == (unsigned) -1) return -1;
-
- PairPosFormat1* pair_pos_prime = (PairPosFormat1*) c.graph.object (pair_pos_prime_id).head;
- pair_pos_prime->format = this->format;
- pair_pos_prime->valueFormat[0] = this->valueFormat[0];
- pair_pos_prime->valueFormat[1] = this->valueFormat[1];
- pair_pos_prime->pairSet.len = num_pair_sets;
-
- for (unsigned i = start; i < end; i++)
- {
- c.graph.move_child<> (this_index,
- &pairSet[i],
- pair_pos_prime_id,
- &pair_pos_prime->pairSet[i - start]);
- }
-
- unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage);
- if (!Coverage::clone_coverage (c,
- coverage_id,
- pair_pos_prime_id,
- 2,
- start, end))
- return -1;
-
- return pair_pos_prime_id;
- }
-
-
-
- unsigned pair_set_graph_index (gsubgpos_graph_context_t& c, unsigned this_index, unsigned i) const
- {
- return c.graph.index_for_offset (this_index, &pairSet[i]);
- }
-};
-
-struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>
-{
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- size_t vertex_len = vertex.table_size ();
- unsigned min_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size;
- if (vertex_len < min_size) return false;
-
- const unsigned class1_count = class1Count;
- return vertex_len >=
- min_size + class1_count * get_class1_record_size ();
- }
-
- hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
- unsigned parent_index,
- unsigned this_index)
- {
- const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size;
- const unsigned class_def_2_size = size_of (c, this_index, &classDef2);
- const Coverage* coverage = get_coverage (c, this_index);
- const ClassDef* class_def_1 = get_class_def_1 (c, this_index);
- auto gid_and_class =
- + coverage->iter ()
- | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1->get_class (gid));
- })
- ;
- class_def_size_estimator_t estimator (gid_and_class);
-
- const unsigned class1_count = class1Count;
- const unsigned class2_count = class2Count;
- const unsigned class1_record_size = get_class1_record_size ();
-
- const unsigned value_1_len = valueFormat1.get_len ();
- const unsigned value_2_len = valueFormat2.get_len ();
- const unsigned total_value_len = value_1_len + value_2_len;
-
- unsigned accumulated = base_size;
- unsigned coverage_size = 4;
- unsigned class_def_1_size = 4;
- unsigned max_coverage_size = coverage_size;
- unsigned max_class_def_1_size = class_def_1_size;
-
- hb_vector_t<unsigned> split_points;
-
- hb_hashmap_t<unsigned, unsigned> device_tables = get_all_device_tables (c, this_index);
- hb_vector_t<unsigned> format1_device_table_indices = valueFormat1.get_device_table_indices ();
- hb_vector_t<unsigned> format2_device_table_indices = valueFormat2.get_device_table_indices ();
- bool has_device_tables = bool(format1_device_table_indices) || bool(format2_device_table_indices);
-
- hb_set_t visited;
- for (unsigned i = 0; i < class1_count; i++)
- {
- unsigned accumulated_delta = class1_record_size;
- coverage_size += estimator.incremental_coverage_size (i);
- class_def_1_size += estimator.incremental_class_def_size (i);
- max_coverage_size = hb_max (max_coverage_size, coverage_size);
- max_class_def_1_size = hb_max (max_class_def_1_size, class_def_1_size);
-
- if (has_device_tables) {
- for (unsigned j = 0; j < class2_count; j++)
- {
- unsigned value1_index = total_value_len * (class2_count * i + j);
- unsigned value2_index = value1_index + value_1_len;
- accumulated_delta += size_of_value_record_children (c,
- device_tables,
- format1_device_table_indices,
- value1_index,
- visited);
- accumulated_delta += size_of_value_record_children (c,
- device_tables,
- format2_device_table_indices,
- value2_index,
- visited);
- }
- }
-
- accumulated += accumulated_delta;
- unsigned total = accumulated
- + coverage_size + class_def_1_size + class_def_2_size
- // The largest object will pack last and can exceed the size limit.
- - hb_max (hb_max (coverage_size, class_def_1_size), class_def_2_size);
- if (total >= (1 << 16))
- {
- split_points.push (i);
- // split does not include i, so add the size for i when we reset the size counters.
- accumulated = base_size + accumulated_delta;
- coverage_size = 4 + estimator.incremental_coverage_size (i);
- class_def_1_size = 4 + estimator.incremental_class_def_size (i);
- visited.clear (); // node sharing isn't allowed between splits.
- }
- }
-
- split_context_t split_context {
- c,
- this,
- c.graph.duplicate_if_shared (parent_index, this_index),
- class1_record_size,
- total_value_len,
- value_1_len,
- value_2_len,
- max_coverage_size,
- max_class_def_1_size,
- device_tables,
- format1_device_table_indices,
- format2_device_table_indices
- };
-
- return actuate_subtable_split<split_context_t> (split_context, split_points);
- }
- private:
-
- struct split_context_t
- {
- gsubgpos_graph_context_t& c;
- PairPosFormat2* thiz;
- unsigned this_index;
- unsigned class1_record_size;
- unsigned value_record_len;
- unsigned value1_record_len;
- unsigned value2_record_len;
- unsigned max_coverage_size;
- unsigned max_class_def_size;
-
- const hb_hashmap_t<unsigned, unsigned>& device_tables;
- const hb_vector_t<unsigned>& format1_device_table_indices;
- const hb_vector_t<unsigned>& format2_device_table_indices;
-
- unsigned original_count ()
- {
- return thiz->class1Count;
- }
-
- unsigned clone_range (unsigned start, unsigned end)
- {
- return thiz->clone_range (*this, start, end);
- }
-
- bool shrink (unsigned count)
- {
- return thiz->shrink (*this, count);
- }
- };
-
- size_t get_class1_record_size () const
- {
- const size_t class2_count = class2Count;
- return
- class2_count * (valueFormat1.get_size () + valueFormat2.get_size ());
- }
-
- unsigned clone_range (split_context_t& split_context,
- unsigned start, unsigned end) const
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Cloning PairPosFormat2 (%u) range [%u, %u).", split_context.this_index, start, end);
-
- graph_t& graph = split_context.c.graph;
-
- unsigned num_records = end - start;
- unsigned prime_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size
- + num_records * split_context.class1_record_size;
-
- unsigned pair_pos_prime_id = split_context.c.create_node (prime_size);
- if (pair_pos_prime_id == (unsigned) -1) return -1;
-
- PairPosFormat2* pair_pos_prime =
- (PairPosFormat2*) graph.object (pair_pos_prime_id).head;
- pair_pos_prime->format = this->format;
- pair_pos_prime->valueFormat1 = this->valueFormat1;
- pair_pos_prime->valueFormat2 = this->valueFormat2;
- pair_pos_prime->class1Count = num_records;
- pair_pos_prime->class2Count = this->class2Count;
- clone_class1_records (split_context,
- pair_pos_prime_id,
- start,
- end);
-
- unsigned coverage_id =
- graph.index_for_offset (split_context.this_index, &coverage);
- unsigned class_def_1_id =
- graph.index_for_offset (split_context.this_index, &classDef1);
- auto& coverage_v = graph.vertices_[coverage_id];
- auto& class_def_1_v = graph.vertices_[class_def_1_id];
- Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
- ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head;
- if (!coverage_table
- || !coverage_table->sanitize (coverage_v)
- || !class_def_1_table
- || !class_def_1_table->sanitize (class_def_1_v))
- return -1;
-
- auto klass_map =
- + coverage_table->iter ()
- | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1_table->get_class (gid));
- })
- | hb_filter ([&] (hb_codepoint_t klass) {
- return klass >= start && klass < end;
- }, hb_second)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, hb_codepoint_t> gid_and_class) {
- // Classes must be from 0...N so subtract start
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid_and_class.first, gid_and_class.second - start);
- })
- ;
-
- if (!Coverage::add_coverage (split_context.c,
- pair_pos_prime_id,
- 2,
- + klass_map | hb_map_retains_sorting (hb_first),
- split_context.max_coverage_size))
- return -1;
-
- // classDef1
- if (!ClassDef::add_class_def (split_context.c,
- pair_pos_prime_id,
- 8,
- + klass_map,
- split_context.max_class_def_size))
- return -1;
-
- // classDef2
- unsigned class_def_2_id =
- graph.index_for_offset (split_context.this_index, &classDef2);
- auto* class_def_link = graph.vertices_[pair_pos_prime_id].obj.real_links.push ();
- class_def_link->width = SmallTypes::size;
- class_def_link->objidx = class_def_2_id;
- class_def_link->position = 10;
- graph.vertices_[class_def_2_id].parents.push (pair_pos_prime_id);
- graph.duplicate (pair_pos_prime_id, class_def_2_id);
-
- return pair_pos_prime_id;
- }
-
- void clone_class1_records (split_context_t& split_context,
- unsigned pair_pos_prime_id,
- unsigned start, unsigned end) const
- {
- PairPosFormat2* pair_pos_prime =
- (PairPosFormat2*) split_context.c.graph.object (pair_pos_prime_id).head;
-
- char* start_addr = ((char*)&values[0]) + start * split_context.class1_record_size;
- unsigned num_records = end - start;
- hb_memcpy (&pair_pos_prime->values[0],
- start_addr,
- num_records * split_context.class1_record_size);
-
- if (!split_context.format1_device_table_indices
- && !split_context.format2_device_table_indices)
- // No device tables to move over.
- return;
-
- unsigned class2_count = class2Count;
- for (unsigned i = start; i < end; i++)
- {
- for (unsigned j = 0; j < class2_count; j++)
- {
- unsigned value1_index = split_context.value_record_len * (class2_count * i + j);
- unsigned value2_index = value1_index + split_context.value1_record_len;
-
- unsigned new_value1_index = split_context.value_record_len * (class2_count * (i - start) + j);
- unsigned new_value2_index = new_value1_index + split_context.value1_record_len;
-
- transfer_device_tables (split_context,
- pair_pos_prime_id,
- split_context.format1_device_table_indices,
- value1_index,
- new_value1_index);
-
- transfer_device_tables (split_context,
- pair_pos_prime_id,
- split_context.format2_device_table_indices,
- value2_index,
- new_value2_index);
- }
- }
- }
-
- void transfer_device_tables (split_context_t& split_context,
- unsigned pair_pos_prime_id,
- const hb_vector_t<unsigned>& device_table_indices,
- unsigned old_value_record_index,
- unsigned new_value_record_index) const
- {
- PairPosFormat2* pair_pos_prime =
- (PairPosFormat2*) split_context.c.graph.object (pair_pos_prime_id).head;
-
- for (unsigned i : device_table_indices)
- {
- OT::Offset16* record = (OT::Offset16*) &values[old_value_record_index + i];
- unsigned record_position = ((char*) record) - ((char*) this);
- if (!split_context.device_tables.has (record_position)) continue;
-
- split_context.c.graph.move_child (
- split_context.this_index,
- record,
- pair_pos_prime_id,
- (OT::Offset16*) &pair_pos_prime->values[new_value_record_index + i]);
- }
- }
-
- bool shrink (split_context_t& split_context,
- unsigned count)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " Shrinking PairPosFormat2 (%u) to [0, %u).",
- split_context.this_index,
- count);
- unsigned old_count = class1Count;
- if (count >= old_count)
- return true;
-
- graph_t& graph = split_context.c.graph;
- class1Count = count;
- graph.vertices_[split_context.this_index].obj.tail -=
- (old_count - count) * split_context.class1_record_size;
-
- auto coverage =
- graph.as_mutable_table<Coverage> (split_context.this_index, &this->coverage);
- if (!coverage) return false;
-
- auto class_def_1 =
- graph.as_mutable_table<ClassDef> (split_context.this_index, &classDef1);
- if (!class_def_1) return false;
-
- auto klass_map =
- + coverage.table->iter ()
- | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1.table->get_class (gid));
- })
- | hb_filter ([&] (hb_codepoint_t klass) {
- return klass < count;
- }, hb_second)
- ;
-
- auto new_coverage = + klass_map | hb_map_retains_sorting (hb_first);
- if (!Coverage::make_coverage (split_context.c,
- + new_coverage,
- coverage.index,
- // existing ranges my not be kept, worst case size is a format 1
- // coverage table.
- 4 + new_coverage.len() * 2))
- return false;
-
- return ClassDef::make_class_def (split_context.c,
- + klass_map,
- class_def_1.index,
- class_def_1.vertex->table_size ());
- }
-
- hb_hashmap_t<unsigned, unsigned>
- get_all_device_tables (gsubgpos_graph_context_t& c,
- unsigned this_index) const
- {
- const auto& v = c.graph.vertices_[this_index];
- return v.position_to_index_map ();
- }
-
- const Coverage* get_coverage (gsubgpos_graph_context_t& c,
- unsigned this_index) const
- {
- unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage);
- auto& coverage_v = c.graph.vertices_[coverage_id];
-
- Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
- if (!coverage_table || !coverage_table->sanitize (coverage_v))
- return &Null(Coverage);
- return coverage_table;
- }
-
- const ClassDef* get_class_def_1 (gsubgpos_graph_context_t& c,
- unsigned this_index) const
- {
- unsigned class_def_1_id = c.graph.index_for_offset (this_index, &classDef1);
- auto& class_def_1_v = c.graph.vertices_[class_def_1_id];
-
- ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head;
- if (!class_def_1_table || !class_def_1_table->sanitize (class_def_1_v))
- return &Null(ClassDef);
- return class_def_1_table;
- }
-
- unsigned size_of_value_record_children (gsubgpos_graph_context_t& c,
- const hb_hashmap_t<unsigned, unsigned>& device_tables,
- const hb_vector_t<unsigned> device_table_indices,
- unsigned value_record_index,
- hb_set_t& visited)
- {
- unsigned size = 0;
- for (unsigned i : device_table_indices)
- {
- OT::Layout::GPOS_impl::Value* record = &values[value_record_index + i];
- unsigned record_position = ((char*) record) - ((char*) this);
- unsigned* obj_idx;
- if (!device_tables.has (record_position, &obj_idx)) continue;
- size += c.graph.find_subgraph_size (*obj_idx, visited);
- }
- return size;
- }
-
- unsigned size_of (gsubgpos_graph_context_t& c,
- unsigned this_index,
- const void* offset) const
- {
- const unsigned id = c.graph.index_for_offset (this_index, offset);
- return c.graph.vertices_[id].table_size ();
- }
-};
-
-struct PairPos : public OT::Layout::GPOS_impl::PairPos
-{
- hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
- unsigned parent_index,
- unsigned this_index)
- {
- switch (u.format) {
- case 1:
- return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
- case 2:
- return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index);
-#ifndef HB_NO_BEYOND_64K
- case 3: HB_FALLTHROUGH;
- case 4: HB_FALLTHROUGH;
- // Don't split 24bit PairPos's.
-#endif
- default:
- return hb_vector_t<unsigned> ();
- }
- }
-
- bool sanitize (graph_t::vertex_t& vertex) const
- {
- int64_t vertex_len = vertex.obj.tail - vertex.obj.head;
- if (vertex_len < u.format.get_size ()) return false;
-
- switch (u.format) {
- case 1:
- return ((PairPosFormat1*)(&u.format1))->sanitize (vertex);
- case 2:
- return ((PairPosFormat2*)(&u.format2))->sanitize (vertex);
-#ifndef HB_NO_BEYOND_64K
- case 3: HB_FALLTHROUGH;
- case 4: HB_FALLTHROUGH;
-#endif
- default:
- // We don't handle format 3 and 4 here.
- return false;
- }
- }
-};
-
-}
-
-#endif // GRAPH_PAIRPOS_GRAPH_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh b/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh
deleted file mode 100644
index 040fd1de5fd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#ifndef GRAPH_SERIALIZE_HH
-#define GRAPH_SERIALIZE_HH
-
-namespace graph {
-
-struct overflow_record_t
-{
- unsigned parent;
- unsigned child;
-
- bool operator != (const overflow_record_t o) const
- { return !(*this == o); }
-
- inline bool operator == (const overflow_record_t& o) const
- {
- return parent == o.parent &&
- child == o.child;
- }
-
- inline uint32_t hash () const
- {
- uint32_t current = 0;
- current = current * 31 + hb_hash (parent);
- current = current * 31 + hb_hash (child);
- return current;
- }
-};
-
-inline
-int64_t compute_offset (
- const graph_t& graph,
- unsigned parent_idx,
- const hb_serialize_context_t::object_t::link_t& link)
-{
- const auto& parent = graph.vertices_[parent_idx];
- const auto& child = graph.vertices_[link.objidx];
- int64_t offset = 0;
- switch ((hb_serialize_context_t::whence_t) link.whence) {
- case hb_serialize_context_t::whence_t::Head:
- offset = child.start - parent.start; break;
- case hb_serialize_context_t::whence_t::Tail:
- offset = child.start - parent.end; break;
- case hb_serialize_context_t::whence_t::Absolute:
- offset = child.start; break;
- }
-
- assert (offset >= link.bias);
- offset -= link.bias;
- return offset;
-}
-
-inline
-bool is_valid_offset (int64_t offset,
- const hb_serialize_context_t::object_t::link_t& link)
-{
- if (unlikely (!link.width))
- // Virtual links can't overflow.
- return link.is_signed || offset >= 0;
-
- if (link.is_signed)
- {
- if (link.width == 4)
- return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31);
- else
- return offset >= -(1 << 15) && offset < (1 << 15);
- }
- else
- {
- if (link.width == 4)
- return offset >= 0 && offset < ((int64_t) 1 << 32);
- else if (link.width == 3)
- return offset >= 0 && offset < ((int32_t) 1 << 24);
- else
- return offset >= 0 && offset < (1 << 16);
- }
-}
-
-/*
- * Will any offsets overflow on graph when it's serialized?
- */
-inline bool
-will_overflow (graph_t& graph,
- hb_vector_t<overflow_record_t>* overflows = nullptr)
-{
- if (overflows) overflows->resize (0);
- graph.update_positions ();
-
- hb_hashmap_t<overflow_record_t*, bool> record_set;
- const auto& vertices = graph.vertices_;
- for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
- {
- // Don't need to check virtual links for overflow
- for (const auto& link : vertices[parent_idx].obj.real_links)
- {
- int64_t offset = compute_offset (graph, parent_idx, link);
- if (is_valid_offset (offset, link))
- continue;
-
- if (!overflows) return true;
-
- overflow_record_t r;
- r.parent = parent_idx;
- r.child = link.objidx;
- if (record_set.has(&r)) continue; // don't keep duplicate overflows.
-
- overflows->push (r);
- record_set.set(&r, true);
- }
- }
-
- if (!overflows) return false;
- return overflows->length;
-}
-
-inline
-void print_overflows (graph_t& graph,
- const hb_vector_t<overflow_record_t>& overflows)
-{
- if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
-
- graph.update_parents ();
- int limit = 10;
- for (const auto& o : overflows)
- {
- if (!limit--) break;
- const auto& parent = graph.vertices_[o.parent];
- const auto& child = graph.vertices_[o.child];
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- " overflow from "
- "%4u (%4u in, %4u out, space %2u) => "
- "%4u (%4u in, %4u out, space %2u)",
- o.parent,
- parent.incoming_edges (),
- parent.obj.real_links.length + parent.obj.virtual_links.length,
- graph.space_for (o.parent),
- o.child,
- child.incoming_edges (),
- child.obj.real_links.length + child.obj.virtual_links.length,
- graph.space_for (o.child));
- }
- if (overflows.length > 10) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %u more overflows.", overflows.length - 10);
- }
-}
-
-template <typename O> inline void
-serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link,
- char* head,
- hb_serialize_context_t* c)
-{
- OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position);
- *offset = 0;
- c->add_link (*offset,
- // serializer has an extra nil object at the start of the
- // object array. So all id's are +1 of what our id's are.
- link.objidx + 1,
- (hb_serialize_context_t::whence_t) link.whence,
- link.bias);
-}
-
-inline
-void serialize_link (const hb_serialize_context_t::object_t::link_t& link,
- char* head,
- hb_serialize_context_t* c)
-{
- switch (link.width)
- {
- case 0:
- // Virtual links aren't serialized.
- return;
- case 4:
- if (link.is_signed)
- {
- serialize_link_of_type<OT::HBINT32> (link, head, c);
- } else {
- serialize_link_of_type<OT::HBUINT32> (link, head, c);
- }
- return;
- case 2:
- if (link.is_signed)
- {
- serialize_link_of_type<OT::HBINT16> (link, head, c);
- } else {
- serialize_link_of_type<OT::HBUINT16> (link, head, c);
- }
- return;
- case 3:
- serialize_link_of_type<OT::HBUINT24> (link, head, c);
- return;
- default:
- // Unexpected link width.
- assert (0);
- }
-}
-
-/*
- * serialize graph into the provided serialization buffer.
- */
-inline hb_blob_t* serialize (const graph_t& graph)
-{
- hb_vector_t<char> buffer;
- size_t size = graph.total_size_in_bytes ();
- if (!buffer.alloc (size)) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
- return nullptr;
- }
- hb_serialize_context_t c((void *) buffer, size);
-
- c.start_serialize<void> ();
- const auto& vertices = graph.vertices_;
- for (unsigned i = 0; i < vertices.length; i++) {
- c.push ();
-
- size_t size = vertices[i].obj.tail - vertices[i].obj.head;
- char* start = c.allocate_size <char> (size);
- if (!start) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space.");
- return nullptr;
- }
-
- hb_memcpy (start, vertices[i].obj.head, size);
-
- // Only real links needs to be serialized.
- for (const auto& link : vertices[i].obj.real_links)
- serialize_link (link, start, &c);
-
- // All duplications are already encoded in the graph, so don't
- // enable sharing during packing.
- c.pop_pack (false);
- }
- c.end_serialize ();
-
- if (c.in_error ()) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d",
- c.errors);
- return nullptr;
- }
-
- return c.copy_blob ();
-}
-
-} // namespace graph
-
-#endif // GRAPH_SERIALIZE_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/split-helpers.hh b/src/3rdparty/harfbuzz-ng/src/graph/split-helpers.hh
deleted file mode 100644
index 61fd7c2d2ff..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/split-helpers.hh
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#ifndef GRAPH_SPLIT_HELPERS_HH
-#define GRAPH_SPLIT_HELPERS_HH
-
-namespace graph {
-
-template<typename Context>
-HB_INTERNAL
-hb_vector_t<unsigned> actuate_subtable_split (Context& split_context,
- const hb_vector_t<unsigned>& split_points)
-{
- hb_vector_t<unsigned> new_objects;
- if (!split_points)
- return new_objects;
-
- for (unsigned i = 0; i < split_points.length; i++)
- {
- unsigned start = split_points[i];
- unsigned end = (i < split_points.length - 1)
- ? split_points[i + 1]
- : split_context.original_count ();
- unsigned id = split_context.clone_range (start, end);
-
- if (id == (unsigned) -1)
- {
- new_objects.reset ();
- new_objects.allocated = -1; // mark error
- return new_objects;
- }
- new_objects.push (id);
- }
-
- if (!split_context.shrink (split_points[0]))
- {
- new_objects.reset ();
- new_objects.allocated = -1; // mark error
- }
-
- return new_objects;
-}
-
-}
-
-#endif // GRAPH_SPLIT_HELPERS_HH
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc b/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
deleted file mode 100644
index 55854ff5c29..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#include "gsubgpos-context.hh"
-#include "classdef-graph.hh"
-
-typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> gid_and_class_t;
-typedef hb_vector_t<gid_and_class_t> gid_and_class_list_t;
-
-
-static bool incremental_size_is (const gid_and_class_list_t& list, unsigned klass,
- unsigned cov_expected, unsigned class_def_expected)
-{
- graph::class_def_size_estimator_t estimator (list.iter ());
-
- unsigned result = estimator.incremental_coverage_size (klass);
- if (result != cov_expected)
- {
- printf ("FAIL: coverage expected size %u but was %u\n", cov_expected, result);
- return false;
- }
-
- result = estimator.incremental_class_def_size (klass);
- if (result != class_def_expected)
- {
- printf ("FAIL: class def expected size %u but was %u\n", class_def_expected, result);
- return false;
- }
-
- return true;
-}
-
-static void test_class_and_coverage_size_estimates ()
-{
- gid_and_class_list_t empty = {
- };
- assert (incremental_size_is (empty, 0, 0, 0));
- assert (incremental_size_is (empty, 1, 0, 0));
-
- gid_and_class_list_t class_zero = {
- {5, 0},
- };
- assert (incremental_size_is (class_zero, 0, 2, 0));
-
- gid_and_class_list_t consecutive = {
- {4, 0},
- {5, 0},
- {6, 1},
- {7, 1},
- {8, 2},
- {9, 2},
- {10, 2},
- {11, 2},
- };
- assert (incremental_size_is (consecutive, 0, 4, 0));
- assert (incremental_size_is (consecutive, 1, 4, 4));
- assert (incremental_size_is (consecutive, 2, 8, 6));
-
- gid_and_class_list_t non_consecutive = {
- {4, 0},
- {5, 0},
-
- {6, 1},
- {7, 1},
-
- {9, 2},
- {10, 2},
- {11, 2},
- {12, 2},
- };
- assert (incremental_size_is (non_consecutive, 0, 4, 0));
- assert (incremental_size_is (non_consecutive, 1, 4, 6));
- assert (incremental_size_is (non_consecutive, 2, 8, 6));
-
- gid_and_class_list_t multiple_ranges = {
- {4, 0},
- {5, 0},
-
- {6, 1},
- {7, 1},
-
- {9, 1},
-
- {11, 1},
- {12, 1},
- {13, 1},
- };
- assert (incremental_size_is (multiple_ranges, 0, 4, 0));
- assert (incremental_size_is (multiple_ranges, 1, 2 * 6, 3 * 6));
-}
-
-int
-main (int argc, char **argv)
-{
- test_class_and_coverage_size_estimates ();
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc
deleted file mode 100644
index c0e23b3eb82..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "graph/gsubgpos-context.cc"
-#include "hb-aat-layout.cc"
-#include "hb-aat-map.cc"
-#include "hb-blob.cc"
-#include "hb-buffer-serialize.cc"
-#include "hb-buffer-verify.cc"
-#include "hb-buffer.cc"
-#include "hb-common.cc"
-#include "hb-draw.cc"
-#include "hb-face-builder.cc"
-#include "hb-face.cc"
-#include "hb-fallback-shape.cc"
-#include "hb-font.cc"
-#include "hb-map.cc"
-#include "hb-number.cc"
-#include "hb-ot-cff1-table.cc"
-#include "hb-ot-cff2-table.cc"
-#include "hb-ot-color.cc"
-#include "hb-ot-face.cc"
-#include "hb-ot-font.cc"
-#include "hb-ot-layout.cc"
-#include "hb-ot-map.cc"
-#include "hb-ot-math.cc"
-#include "hb-ot-meta.cc"
-#include "hb-ot-metrics.cc"
-#include "hb-ot-name.cc"
-#include "hb-ot-shape-fallback.cc"
-#include "hb-ot-shape-normalize.cc"
-#include "hb-ot-shape.cc"
-#include "hb-ot-shaper-arabic.cc"
-#include "hb-ot-shaper-default.cc"
-#include "hb-ot-shaper-hangul.cc"
-#include "hb-ot-shaper-hebrew.cc"
-#include "hb-ot-shaper-indic-table.cc"
-#include "hb-ot-shaper-indic.cc"
-#include "hb-ot-shaper-khmer.cc"
-#include "hb-ot-shaper-myanmar.cc"
-#include "hb-ot-shaper-syllabic.cc"
-#include "hb-ot-shaper-thai.cc"
-#include "hb-ot-shaper-use.cc"
-#include "hb-ot-shaper-vowel-constraints.cc"
-#include "hb-ot-tag.cc"
-#include "hb-ot-var.cc"
-#include "hb-outline.cc"
-#include "hb-paint-extents.cc"
-#include "hb-paint.cc"
-#include "hb-set.cc"
-#include "hb-shape-plan.cc"
-#include "hb-shape.cc"
-#include "hb-shaper.cc"
-#include "hb-static.cc"
-#include "hb-style.cc"
-#include "hb-subset-cff-common.cc"
-#include "hb-subset-cff1.cc"
-#include "hb-subset-cff2.cc"
-#include "hb-subset-input.cc"
-#include "hb-subset-instancer-solver.cc"
-#include "hb-subset-plan.cc"
-#include "hb-subset-repacker.cc"
-#include "hb-subset.cc"
-#include "hb-ucd.cc"
-#include "hb-unicode.cc"
diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc
deleted file mode 100644
index d7e8a93f393..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/harfbuzz.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "hb-aat-layout.cc"
-#include "hb-aat-map.cc"
-#include "hb-blob.cc"
-#include "hb-buffer-serialize.cc"
-#include "hb-buffer-verify.cc"
-#include "hb-buffer.cc"
-#include "hb-common.cc"
-#include "hb-coretext.cc"
-#include "hb-directwrite.cc"
-#include "hb-draw.cc"
-#include "hb-face-builder.cc"
-#include "hb-face.cc"
-#include "hb-fallback-shape.cc"
-#include "hb-font.cc"
-#include "hb-ft.cc"
-#include "hb-gdi.cc"
-#include "hb-glib.cc"
-#include "hb-graphite2.cc"
-#include "hb-map.cc"
-#include "hb-number.cc"
-#include "hb-ot-cff1-table.cc"
-#include "hb-ot-cff2-table.cc"
-#include "hb-ot-color.cc"
-#include "hb-ot-face.cc"
-#include "hb-ot-font.cc"
-#include "hb-ot-layout.cc"
-#include "hb-ot-map.cc"
-#include "hb-ot-math.cc"
-#include "hb-ot-meta.cc"
-#include "hb-ot-metrics.cc"
-#include "hb-ot-name.cc"
-#include "hb-ot-shape-fallback.cc"
-#include "hb-ot-shape-normalize.cc"
-#include "hb-ot-shape.cc"
-#include "hb-ot-shaper-arabic.cc"
-#include "hb-ot-shaper-default.cc"
-#include "hb-ot-shaper-hangul.cc"
-#include "hb-ot-shaper-hebrew.cc"
-#include "hb-ot-shaper-indic-table.cc"
-#include "hb-ot-shaper-indic.cc"
-#include "hb-ot-shaper-khmer.cc"
-#include "hb-ot-shaper-myanmar.cc"
-#include "hb-ot-shaper-syllabic.cc"
-#include "hb-ot-shaper-thai.cc"
-#include "hb-ot-shaper-use.cc"
-#include "hb-ot-shaper-vowel-constraints.cc"
-#include "hb-ot-tag.cc"
-#include "hb-ot-var.cc"
-#include "hb-outline.cc"
-#include "hb-paint-extents.cc"
-#include "hb-paint.cc"
-#include "hb-set.cc"
-#include "hb-shape-plan.cc"
-#include "hb-shape.cc"
-#include "hb-shaper.cc"
-#include "hb-static.cc"
-#include "hb-style.cc"
-#include "hb-ucd.cc"
-#include "hb-unicode.cc"
-#include "hb-uniscribe.cc"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh
deleted file mode 100644
index 63fac84524f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-ankr-table.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LAYOUT_ANKR_TABLE_HH
-#define HB_AAT_LAYOUT_ANKR_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-
-/*
- * ankr -- Anchor Point
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html
- */
-#define HB_AAT_TAG_ankr HB_TAG('a','n','k','r')
-
-
-namespace AAT {
-
-using namespace OT;
-
-
-struct Anchor
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- FWORD xCoordinate;
- FWORD yCoordinate;
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-typedef Array32Of<Anchor> GlyphAnchors;
-
-struct ankr
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_ankr;
-
- const Anchor &get_anchor (hb_codepoint_t glyph_id,
- unsigned int i,
- unsigned int num_glyphs) const
- {
- const NNOffset16To<GlyphAnchors> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs);
- if (!offset)
- return Null (Anchor);
- const GlyphAnchors &anchors = &(this+anchorData) + *offset;
- return anchors[i];
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version == 0 &&
- c->check_range (this, anchorData) &&
- lookupTable.sanitize (c, this, &(this+anchorData))));
- }
-
- protected:
- HBUINT16 version; /* Version number (set to zero) */
- HBUINT16 flags; /* Flags (currently unused; set to zero) */
- Offset32To<Lookup<NNOffset16To<GlyphAnchors>>>
- lookupTable; /* Offset to the table's lookup table */
- NNOffset32To<HBUINT8>
- anchorData; /* Offset to the glyph data table */
-
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_ANKR_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh
deleted file mode 100644
index bf12d2e699f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-bsln-table.hh
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LAYOUT_BSLN_TABLE_HH
-#define HB_AAT_LAYOUT_BSLN_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-
-/*
- * bsln -- Baseline
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bsln.html
- */
-#define HB_AAT_TAG_bsln HB_TAG('b','s','l','n')
-
-
-namespace AAT {
-
-
-struct BaselineTableFormat0Part
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- // Roman, Ideographic centered, Ideographic low, Hanging and Math
- // are the default defined ones, but any other maybe accessed also.
- HBINT16 deltas[32]; /* These are the FUnit distance deltas from
- * the font's natural baseline to the other
- * baselines used in the font. */
- public:
- DEFINE_SIZE_STATIC (64);
-};
-
-struct BaselineTableFormat1Part
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- lookupTable.sanitize (c)));
- }
-
- protected:
- HBINT16 deltas[32]; /* ditto */
- Lookup<HBUINT16>
- lookupTable; /* Lookup table that maps glyphs to their
- * baseline values. */
- public:
- DEFINE_SIZE_MIN (66);
-};
-
-struct BaselineTableFormat2Part
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBGlyphID16 stdGlyph; /* The specific glyph index number in this
- * font that is used to set the baseline values.
- * This is the standard glyph.
- * This glyph must contain a set of control points
- * (whose numbers are contained in the ctlPoints field)
- * that are used to determine baseline distances. */
- HBUINT16 ctlPoints[32]; /* Set of control point numbers,
- * associated with the standard glyph.
- * A value of 0xFFFF means there is no corresponding
- * control point in the standard glyph. */
- public:
- DEFINE_SIZE_STATIC (66);
-};
-
-struct BaselineTableFormat3Part
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c)));
- }
-
- protected:
- HBGlyphID16 stdGlyph; /* ditto */
- HBUINT16 ctlPoints[32]; /* ditto */
- Lookup<HBUINT16>
- lookupTable; /* Lookup table that maps glyphs to their
- * baseline values. */
- public:
- DEFINE_SIZE_MIN (68);
-};
-
-struct bsln
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_bsln;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!(c->check_struct (this) && defaultBaseline < 32)))
- return_trace (false);
-
- switch (format)
- {
- case 0: return_trace (parts.format0.sanitize (c));
- case 1: return_trace (parts.format1.sanitize (c));
- case 2: return_trace (parts.format2.sanitize (c));
- case 3: return_trace (parts.format3.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- FixedVersion<>version; /* Version number of the Baseline table. */
- HBUINT16 format; /* Format of the baseline table. Only one baseline
- * format may be selected for the font. */
- HBUINT16 defaultBaseline;/* Default baseline value for all glyphs.
- * This value can be from 0 through 31. */
- union {
- // Distance-Based Formats
- BaselineTableFormat0Part format0;
- BaselineTableFormat1Part format1;
- // Control Point-based Formats
- BaselineTableFormat2Part format2;
- BaselineTableFormat3Part format3;
- } parts;
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_BSLN_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
deleted file mode 100644
index 7d53c354dab..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * 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_AAT_LAYOUT_COMMON_HH
-#define HB_AAT_LAYOUT_COMMON_HH
-
-#include "hb-aat-layout.hh"
-#include "hb-aat-map.hh"
-#include "hb-open-type.hh"
-
-namespace OT {
-struct GDEF;
-};
-
-namespace AAT {
-
-using namespace OT;
-
-
-struct ankr;
-
-struct hb_aat_apply_context_t :
- hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
-{
- const char *get_name () { return "APPLY"; }
- template <typename T>
- return_t dispatch (const T &obj) { return obj.apply (this); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- const hb_ot_shape_plan_t *plan;
- hb_font_t *font;
- hb_face_t *face;
- hb_buffer_t *buffer;
- hb_sanitize_context_t sanitizer;
- const ankr *ankr_table;
- const OT::GDEF *gdef_table;
- const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
- hb_mask_t subtable_flags = 0;
-
- /* Unused. For debug tracing only. */
- unsigned int lookup_index;
-
- HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
- hb_font_t *font_,
- hb_buffer_t *buffer_,
- hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
-
- HB_INTERNAL ~hb_aat_apply_context_t ();
-
- HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
-
- void set_lookup_index (unsigned int i) { lookup_index = i; }
-};
-
-
-/*
- * Lookup Table
- */
-
-template <typename T> struct Lookup;
-
-template <typename T>
-struct LookupFormat0
-{
- friend struct Lookup<T>;
-
- private:
- const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
- {
- if (unlikely (glyph_id >= num_glyphs)) return nullptr;
- return &arrayZ[glyph_id];
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 0 */
- UnsizedArrayOf<T>
- arrayZ; /* Array of lookup values, indexed by glyph index. */
- public:
- DEFINE_SIZE_UNBOUNDED (2);
-};
-
-
-template <typename T>
-struct LookupSegmentSingle
-{
- static constexpr unsigned TerminationWordCount = 2u;
-
- int cmp (hb_codepoint_t g) const
- { return g < first ? -1 : g <= last ? 0 : +1 ; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c, base));
- }
-
- HBGlyphID16 last; /* Last GlyphID in this segment */
- HBGlyphID16 first; /* First GlyphID in this segment */
- T value; /* The lookup value (only one) */
- public:
- DEFINE_SIZE_STATIC (4 + T::static_size);
-};
-
-template <typename T>
-struct LookupFormat2
-{
- friend struct Lookup<T>;
-
- private:
- const T* get_value (hb_codepoint_t glyph_id) const
- {
- const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
- return v ? &v->value : nullptr;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (segments.sanitize (c));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (segments.sanitize (c, base));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- VarSizedBinSearchArrayOf<LookupSegmentSingle<T>>
- segments; /* The actual segments. These must already be sorted,
- * according to the first word in each one (the last
- * glyph in each segment). */
- public:
- DEFINE_SIZE_ARRAY (8, segments);
-};
-
-template <typename T>
-struct LookupSegmentArray
-{
- static constexpr unsigned TerminationWordCount = 2u;
-
- const T* get_value (hb_codepoint_t glyph_id, const void *base) const
- {
- return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
- }
-
- int cmp (hb_codepoint_t g) const
- { return g < first ? -1 : g <= last ? 0 : +1; }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- first <= last &&
- valuesZ.sanitize (c, base, last - first + 1));
- }
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- first <= last &&
- valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
- }
-
- HBGlyphID16 last; /* Last GlyphID in this segment */
- HBGlyphID16 first; /* First GlyphID in this segment */
- NNOffset16To<UnsizedArrayOf<T>>
- valuesZ; /* A 16-bit offset from the start of
- * the table to the data. */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-template <typename T>
-struct LookupFormat4
-{
- friend struct Lookup<T>;
-
- private:
- const T* get_value (hb_codepoint_t glyph_id) const
- {
- const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
- return v ? v->get_value (glyph_id, this) : nullptr;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (segments.sanitize (c, this));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (segments.sanitize (c, this, base));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 4 */
- VarSizedBinSearchArrayOf<LookupSegmentArray<T>>
- segments; /* The actual segments. These must already be sorted,
- * according to the first word in each one (the last
- * glyph in each segment). */
- public:
- DEFINE_SIZE_ARRAY (8, segments);
-};
-
-template <typename T>
-struct LookupSingle
-{
- static constexpr unsigned TerminationWordCount = 1u;
-
- int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && value.sanitize (c, base));
- }
-
- HBGlyphID16 glyph; /* Last GlyphID */
- T value; /* The lookup value (only one) */
- public:
- DEFINE_SIZE_STATIC (2 + T::static_size);
-};
-
-template <typename T>
-struct LookupFormat6
-{
- friend struct Lookup<T>;
-
- private:
- const T* get_value (hb_codepoint_t glyph_id) const
- {
- const LookupSingle<T> *v = entries.bsearch (glyph_id);
- return v ? &v->value : nullptr;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (entries.sanitize (c));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (entries.sanitize (c, base));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 6 */
- VarSizedBinSearchArrayOf<LookupSingle<T>>
- entries; /* The actual entries, sorted by glyph index. */
- public:
- DEFINE_SIZE_ARRAY (8, entries);
-};
-
-template <typename T>
-struct LookupFormat8
-{
- friend struct Lookup<T>;
-
- private:
- const T* get_value (hb_codepoint_t glyph_id) const
- {
- return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
- &valueArrayZ[glyph_id - firstGlyph] : nullptr;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 8 */
- HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
- HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
- * glyph minus the value of firstGlyph plus 1). */
- UnsizedArrayOf<T>
- valueArrayZ; /* The lookup values (indexed by the glyph index
- * minus the value of firstGlyph). */
- public:
- DEFINE_SIZE_ARRAY (6, valueArrayZ);
-};
-
-template <typename T>
-struct LookupFormat10
-{
- friend struct Lookup<T>;
-
- private:
- const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const
- {
- if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
- return Null (T);
-
- const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
-
- unsigned int v = 0;
- unsigned int count = valueSize;
- for (unsigned int i = 0; i < count; i++)
- v = (v << 8) | *p++;
-
- return v;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- valueSize <= 4 &&
- valueArrayZ.sanitize (c, glyphCount * valueSize));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 8 */
- HBUINT16 valueSize; /* Byte size of each value. */
- HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
- HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
- * glyph minus the value of firstGlyph plus 1). */
- UnsizedArrayOf<HBUINT8>
- valueArrayZ; /* The lookup values (indexed by the glyph index
- * minus the value of firstGlyph). */
- public:
- DEFINE_SIZE_ARRAY (8, valueArrayZ);
-};
-
-template <typename T>
-struct Lookup
-{
- const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
- {
- switch (u.format) {
- case 0: return u.format0.get_value (glyph_id, num_glyphs);
- case 2: return u.format2.get_value (glyph_id);
- case 4: return u.format4.get_value (glyph_id);
- case 6: return u.format6.get_value (glyph_id);
- case 8: return u.format8.get_value (glyph_id);
- default:return nullptr;
- }
- }
-
- const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
- {
- switch (u.format) {
- /* Format 10 cannot return a pointer. */
- case 10: return u.format10.get_value_or_null (glyph_id);
- default:
- const T *v = get_value (glyph_id, num_glyphs);
- return v ? *v : Null (T);
- }
- }
-
- typename T::type get_class (hb_codepoint_t glyph_id,
- unsigned int num_glyphs,
- unsigned int outOfRange) const
- {
- const T *v = get_value (glyph_id, num_glyphs);
- return v ? *v : outOfRange;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 0: return_trace (u.format0.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 4: return_trace (u.format4.sanitize (c));
- case 6: return_trace (u.format6.sanitize (c));
- case 8: return_trace (u.format8.sanitize (c));
- case 10: return_trace (u.format10.sanitize (c));
- default:return_trace (true);
- }
- }
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 0: return_trace (u.format0.sanitize (c, base));
- case 2: return_trace (u.format2.sanitize (c, base));
- case 4: return_trace (u.format4.sanitize (c, base));
- case 6: return_trace (u.format6.sanitize (c, base));
- case 8: return_trace (u.format8.sanitize (c, base));
- case 10: return_trace (false); /* We don't support format10 here currently. */
- default:return_trace (true);
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- LookupFormat0<T> format0;
- LookupFormat2<T> format2;
- LookupFormat4<T> format4;
- LookupFormat6<T> format6;
- LookupFormat8<T> format8;
- LookupFormat10<T> format10;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2);
-
-enum { DELETED_GLYPH = 0xFFFF };
-
-/*
- * (Extended) State Table
- */
-
-template <typename T>
-struct Entry
-{
- // This does seem like it's ever called.
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* Note, we don't recurse-sanitize data because we don't access it.
- * That said, in our DEFINE_SIZE_STATIC we access T::static_size,
- * which ensures that data has a simple sanitize(). To be determined
- * if I need to remove that as well.
- *
- * HOWEVER! Because we are a template, our DEFINE_SIZE_STATIC
- * assertion wouldn't be checked, hence the line below. */
- static_assert (T::static_size, "");
-
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT16 newState; /* Byte offset from beginning of state table
- * to the new state. Really?!?! Or just state
- * number? The latter in morx for sure. */
- HBUINT16 flags; /* Table specific. */
- T data; /* Optional offsets to per-glyph tables. */
- public:
- DEFINE_SIZE_STATIC (4 + T::static_size);
-};
-
-template <>
-struct Entry<void>
-{
- // This does seem like it's ever called.
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT16 newState; /* Byte offset from beginning of state table to the new state. */
- HBUINT16 flags; /* Table specific. */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-template <typename Types, typename Extra>
-struct StateTable
-{
- typedef typename Types::HBUINT HBUINT;
- typedef typename Types::HBUSHORT HBUSHORT;
- typedef typename Types::ClassTypeNarrow ClassType;
-
- enum State
- {
- STATE_START_OF_TEXT = 0,
- STATE_START_OF_LINE = 1,
- };
- enum Class
- {
- CLASS_END_OF_TEXT = 0,
- CLASS_OUT_OF_BOUNDS = 1,
- CLASS_DELETED_GLYPH = 2,
- CLASS_END_OF_LINE = 3,
- };
-
- int new_state (unsigned int newState) const
- { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
-
- unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
- {
- if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
- return (this+classTable).get_class (glyph_id, num_glyphs, 1);
- }
-
- const Entry<Extra> *get_entries () const
- { return (this+entryTable).arrayZ; }
-
- const Entry<Extra> &get_entry (int state, unsigned int klass) const
- {
- if (unlikely (klass >= nClasses))
- klass = StateTable::CLASS_OUT_OF_BOUNDS;
-
- const HBUSHORT *states = (this+stateArrayTable).arrayZ;
- const Entry<Extra> *entries = (this+entryTable).arrayZ;
-
- unsigned int entry = states[state * nClasses + klass];
- DEBUG_MSG (APPLY, nullptr, "e%u", entry);
-
- return entries[entry];
- }
-
- bool sanitize (hb_sanitize_context_t *c,
- unsigned int *num_entries_out = nullptr) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!(c->check_struct (this) &&
- nClasses >= 4 /* Ensure pre-defined classes fit. */ &&
- classTable.sanitize (c, this)))) return_trace (false);
-
- const HBUSHORT *states = (this+stateArrayTable).arrayZ;
- const Entry<Extra> *entries = (this+entryTable).arrayZ;
-
- unsigned int num_classes = nClasses;
- if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
- return_trace (false);
- unsigned int row_stride = num_classes * states[0].static_size;
-
- /* Apple 'kern' table has this peculiarity:
- *
- * "Because the stateTableOffset in the state table header is (strictly
- * speaking) redundant, some 'kern' tables use it to record an initial
- * state where that should not be StartOfText. To determine if this is
- * done, calculate what the stateTableOffset should be. If it's different
- * from the actual stateTableOffset, use it as the initial state."
- *
- * We implement this by calling the initial state zero, but allow *negative*
- * states if the start state indeed was not the first state. Since the code
- * is shared, this will also apply to 'mort' table. The 'kerx' / 'morx'
- * tables are not affected since those address states by index, not offset.
- */
-
- int min_state = 0;
- int max_state = 0;
- unsigned int num_entries = 0;
-
- int state_pos = 0;
- int state_neg = 0;
- unsigned int entry = 0;
- while (min_state < state_neg || state_pos <= max_state)
- {
- if (min_state < state_neg)
- {
- /* Negative states. */
- if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
- return_trace (false);
- if (unlikely (!c->check_range (&states[min_state * num_classes],
- -min_state,
- row_stride)))
- return_trace (false);
- if ((c->max_ops -= state_neg - min_state) <= 0)
- return_trace (false);
- { /* Sweep new states. */
- const HBUSHORT *stop = &states[min_state * num_classes];
- if (unlikely (stop > states))
- return_trace (false);
- for (const HBUSHORT *p = states; stop < p; p--)
- num_entries = hb_max (num_entries, *(p - 1) + 1u);
- state_neg = min_state;
- }
- }
-
- if (state_pos <= max_state)
- {
- /* Positive states. */
- if (unlikely (!c->check_range (states,
- max_state + 1,
- row_stride)))
- return_trace (false);
- if ((c->max_ops -= max_state - state_pos + 1) <= 0)
- return_trace (false);
- { /* Sweep new states. */
- if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
- return_trace (false);
- const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
- if (unlikely (stop < states))
- return_trace (false);
- for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
- num_entries = hb_max (num_entries, *p + 1u);
- state_pos = max_state + 1;
- }
- }
-
- if (unlikely (!c->check_array (entries, num_entries)))
- return_trace (false);
- if ((c->max_ops -= num_entries - entry) <= 0)
- return_trace (false);
- { /* Sweep new entries. */
- const Entry<Extra> *stop = &entries[num_entries];
- for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
- {
- int newState = new_state (p->newState);
- min_state = hb_min (min_state, newState);
- max_state = hb_max (max_state, newState);
- }
- entry = num_entries;
- }
- }
-
- if (num_entries_out)
- *num_entries_out = num_entries;
-
- return_trace (true);
- }
-
- protected:
- HBUINT nClasses; /* Number of classes, which is the number of indices
- * in a single line in the state array. */
- NNOffsetTo<ClassType, HBUINT>
- classTable; /* Offset to the class table. */
- NNOffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT>
- stateArrayTable;/* Offset to the state array. */
- NNOffsetTo<UnsizedArrayOf<Entry<Extra>>, HBUINT>
- entryTable; /* Offset to the entry array. */
-
- public:
- DEFINE_SIZE_STATIC (4 * sizeof (HBUINT));
-};
-
-template <typename HBUCHAR>
-struct ClassTable
-{
- unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const
- {
- unsigned int i = glyph_id - firstGlyph;
- return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
- }
- unsigned int get_class (hb_codepoint_t glyph_id,
- unsigned int num_glyphs HB_UNUSED,
- unsigned int outOfRange) const
- {
- return get_class (glyph_id, outOfRange);
- }
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && classArray.sanitize (c));
- }
- protected:
- HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
- Array16Of<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus
- * firstGlyph). */
- public:
- DEFINE_SIZE_ARRAY (4, classArray);
-};
-
-struct ObsoleteTypes
-{
- static constexpr bool extended = false;
- typedef HBUINT16 HBUINT;
- typedef HBUINT8 HBUSHORT;
- typedef ClassTable<HBUINT8> ClassTypeNarrow;
- typedef ClassTable<HBUINT16> ClassTypeWide;
-
- template <typename T>
- static unsigned int offsetToIndex (unsigned int offset,
- const void *base,
- const T *array)
- {
- /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
- /* If offset is less than base, return an offset that would
- * result in an address half a 32bit address-space away,
- * to make sure sanitize fails even on 32bit builds. */
- if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
- return INT_MAX / T::static_size;
-
- /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
- return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
- }
- template <typename T>
- static unsigned int byteOffsetToIndex (unsigned int offset,
- const void *base,
- const T *array)
- {
- return offsetToIndex (offset, base, array);
- }
- template <typename T>
- static unsigned int wordOffsetToIndex (unsigned int offset,
- const void *base,
- const T *array)
- {
- return offsetToIndex (2 * offset, base, array);
- }
-};
-struct ExtendedTypes
-{
- static constexpr bool extended = true;
- typedef HBUINT32 HBUINT;
- typedef HBUINT16 HBUSHORT;
- typedef Lookup<HBUINT16> ClassTypeNarrow;
- typedef Lookup<HBUINT16> ClassTypeWide;
-
- template <typename T>
- static unsigned int offsetToIndex (unsigned int offset,
- const void *base HB_UNUSED,
- const T *array HB_UNUSED)
- {
- return offset;
- }
- template <typename T>
- static unsigned int byteOffsetToIndex (unsigned int offset,
- const void *base HB_UNUSED,
- const T *array HB_UNUSED)
- {
- return offset / 2;
- }
- template <typename T>
- static unsigned int wordOffsetToIndex (unsigned int offset,
- const void *base HB_UNUSED,
- const T *array HB_UNUSED)
- {
- return offset;
- }
-};
-
-template <typename Types, typename EntryData>
-struct StateTableDriver
-{
- using StateTableT = StateTable<Types, EntryData>;
- using EntryT = Entry<EntryData>;
-
- StateTableDriver (const StateTableT &machine_,
- hb_buffer_t *buffer_,
- hb_face_t *face_) :
- machine (machine_),
- buffer (buffer_),
- num_glyphs (face_->get_num_glyphs ()) {}
-
- template <typename context_t>
- void drive (context_t *c, hb_aat_apply_context_t *ac)
- {
- if (!c->in_place)
- buffer->clear_output ();
-
- int state = StateTableT::STATE_START_OF_TEXT;
- // If there's only one range, we already checked the flag.
- auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
- for (buffer->idx = 0; buffer->successful;)
- {
- /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
- if (last_range)
- {
- auto *range = last_range;
- if (buffer->idx < buffer->len)
- {
- unsigned cluster = buffer->cur().cluster;
- while (cluster < range->cluster_first)
- range--;
- while (cluster > range->cluster_last)
- range++;
-
-
- last_range = range;
- }
- if (!(range->flags & ac->subtable_flags))
- {
- if (buffer->idx == buffer->len || unlikely (!buffer->successful))
- break;
-
- state = StateTableT::STATE_START_OF_TEXT;
- (void) buffer->next_glyph ();
- continue;
- }
- }
-
- unsigned int klass = buffer->idx < buffer->len ?
- machine.get_class (buffer->cur().codepoint, num_glyphs) :
- (unsigned) StateTableT::CLASS_END_OF_TEXT;
- DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
- const EntryT &entry = machine.get_entry (state, klass);
- const int next_state = machine.new_state (entry.newState);
-
- /* Conditions under which it's guaranteed safe-to-break before current glyph:
- *
- * 1. There was no action in this transition; and
- *
- * 2. If we break before current glyph, the results will be the same. That
- * is guaranteed if:
- *
- * 2a. We were already in start-of-text state; or
- *
- * 2b. We are epsilon-transitioning to start-of-text state; or
- *
- * 2c. Starting from start-of-text state seeing current glyph:
- *
- * 2c'. There won't be any actions; and
- *
- * 2c". We would end up in the same state that we were going to end up
- * in now, including whether epsilon-transitioning.
- *
- * and
- *
- * 3. If we break before current glyph, there won't be any end-of-text action
- * after previous glyph.
- *
- * This triples the transitions we need to look up, but is worth returning
- * granular unsafe-to-break results. See eg.:
- *
- * https://github.com/harfbuzz/harfbuzz/issues/2860
- */
- const EntryT *wouldbe_entry;
- bool safe_to_break =
- /* 1. */
- !c->is_actionable (this, entry)
- &&
- /* 2. */
- (
- /* 2a. */
- state == StateTableT::STATE_START_OF_TEXT
- ||
- /* 2b. */
- (
- (entry.flags & context_t::DontAdvance) &&
- next_state == StateTableT::STATE_START_OF_TEXT
- )
- ||
- /* 2c. */
- (
- wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
- ,
- /* 2c'. */
- !c->is_actionable (this, *wouldbe_entry)
- &&
- /* 2c". */
- (
- next_state == machine.new_state (wouldbe_entry->newState)
- &&
- (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
- )
- )
- )
- &&
- /* 3. */
- !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
- ;
-
- if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
- buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
-
- c->transition (this, entry);
-
- state = next_state;
- DEBUG_MSG (APPLY, nullptr, "s%d", state);
-
- if (buffer->idx == buffer->len || unlikely (!buffer->successful))
- break;
-
- if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
- (void) buffer->next_glyph ();
- }
-
- if (!c->in_place)
- buffer->sync ();
- }
-
- public:
- const StateTableT &machine;
- hb_buffer_t *buffer;
- unsigned int num_glyphs;
-};
-
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh
deleted file mode 100644
index 815a1fd2aa9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-feat-table.hh
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LAYOUT_FEAT_TABLE_HH
-#define HB_AAT_LAYOUT_FEAT_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-
-/*
- * feat -- Feature Name
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html
- */
-#define HB_AAT_TAG_feat HB_TAG('f','e','a','t')
-
-
-namespace AAT {
-
-
-struct SettingName
-{
- friend struct FeatureName;
-
- int cmp (hb_aat_layout_feature_selector_t key) const
- { return (int) key - (int) setting; }
-
- hb_aat_layout_feature_selector_t get_selector () const
- { return (hb_aat_layout_feature_selector_t) (unsigned) setting; }
-
- hb_aat_layout_feature_selector_info_t get_info (hb_aat_layout_feature_selector_t default_selector) const
- {
- return {
- nameIndex,
- (hb_aat_layout_feature_selector_t) (unsigned int) setting,
- default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID
- ? (hb_aat_layout_feature_selector_t) (setting + 1)
- : default_selector,
- 0
- };
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 setting; /* The setting. */
- NameID nameIndex; /* The name table index for the setting's name. */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-DECLARE_NULL_NAMESPACE_BYTES (AAT, SettingName);
-
-struct feat;
-
-struct FeatureName
-{
- int cmp (hb_aat_layout_feature_type_t key) const
- { return (int) key - (int) feature; }
-
- enum {
- Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */
- NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in
- * the setting name array for this feature should
- * be taken as the default for the feature
- * (if one is required). If set, then bits 0-15 of this
- * featureFlags field contain the index of the setting
- * which is to be taken as the default. */
- IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits
- * indicate the index of the setting in the setting name
- * array for this feature which should be taken
- * as the default. */
- };
-
- unsigned int get_selector_infos (unsigned int start_offset,
- unsigned int *selectors_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
- unsigned int *pdefault_index, /* OUT. May be NULL. */
- const void *base) const
- {
- hb_array_t< const SettingName> settings_table = (base+settingTableZ).as_array (nSettings);
-
- static_assert (Index::NOT_FOUND_INDEX == HB_AAT_LAYOUT_NO_SELECTOR_INDEX, "");
-
- hb_aat_layout_feature_selector_t default_selector = HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID;
- unsigned int default_index = Index::NOT_FOUND_INDEX;
- if (featureFlags & Exclusive)
- {
- default_index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0;
- default_selector = settings_table[default_index].get_selector ();
- }
- if (pdefault_index)
- *pdefault_index = default_index;
-
- if (selectors_count)
- {
- + settings_table.sub_array (start_offset, selectors_count)
- | hb_map ([=] (const SettingName& setting) { return setting.get_info (default_selector); })
- | hb_sink (hb_array (selectors, *selectors_count))
- ;
- }
- return settings_table.length;
- }
-
- hb_aat_layout_feature_type_t get_feature_type () const
- { return (hb_aat_layout_feature_type_t) (unsigned int) feature; }
-
- hb_ot_name_id_t get_feature_name_id () const { return nameIndex; }
-
- bool is_exclusive () const { return featureFlags & Exclusive; }
-
- /* A FeatureName with no settings is meaningless */
- bool has_data () const { return nSettings; }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (base+settingTableZ).sanitize (c, nSettings)));
- }
-
- protected:
- HBUINT16 feature; /* Feature type. */
- HBUINT16 nSettings; /* The number of records in the setting name array. */
- NNOffset32To<UnsizedArrayOf<SettingName>>
- settingTableZ; /* Offset in bytes from the beginning of this table to
- * this feature's setting name array. The actual type of
- * record this offset refers to will depend on the
- * exclusivity value, as described below. */
- HBUINT16 featureFlags; /* Single-bit flags associated with the feature type. */
- HBINT16 nameIndex; /* The name table index for the feature's name.
- * This index has values greater than 255 and
- * less than 32768. */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct feat
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_feat;
-
- bool has_data () const { return version.to_int (); }
-
- unsigned int get_feature_types (unsigned int start_offset,
- unsigned int *count,
- hb_aat_layout_feature_type_t *features) const
- {
- if (count)
- {
- + namesZ.as_array (featureNameCount).sub_array (start_offset, count)
- | hb_map (&FeatureName::get_feature_type)
- | hb_sink (hb_array (features, *count))
- ;
- }
- return featureNameCount;
- }
-
- bool exposes_feature (hb_aat_layout_feature_type_t feature_type) const
- { return get_feature (feature_type).has_data (); }
-
- const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
- { return namesZ.bsearch (featureNameCount, feature_type); }
-
- hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
- { return get_feature (feature).get_feature_name_id (); }
-
- unsigned int get_selector_infos (hb_aat_layout_feature_type_t feature_type,
- unsigned int start_offset,
- unsigned int *selectors_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
- unsigned int *default_index /* OUT. May be NULL. */) const
- {
- return get_feature (feature_type).get_selector_infos (start_offset, selectors_count, selectors,
- default_index, this);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version.major == 1 &&
- namesZ.sanitize (c, featureNameCount, this)));
- }
-
- protected:
- FixedVersion<>version; /* Version number of the feature name table
- * (0x00010000 for the current version). */
- HBUINT16 featureNameCount;
- /* The number of entries in the feature name array. */
- HBUINT16 reserved1; /* Reserved (set to zero). */
- HBUINT32 reserved2; /* Reserved (set to zero). */
- SortedUnsizedArrayOf<FeatureName>
- namesZ; /* The feature name array. */
- public:
- DEFINE_SIZE_ARRAY (12, namesZ);
-};
-
-} /* namespace AAT */
-
-#endif /* HB_AAT_LAYOUT_FEAT_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh
deleted file mode 100644
index 8fd3990f887..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-just-table.hh
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LAYOUT_JUST_TABLE_HH
-#define HB_AAT_LAYOUT_JUST_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-#include "hb-ot-layout.hh"
-#include "hb-open-type.hh"
-
-#include "hb-aat-layout-morx-table.hh"
-
-/*
- * just -- Justification
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html
- */
-#define HB_AAT_TAG_just HB_TAG('j','u','s','t')
-
-
-namespace AAT {
-
-using namespace OT;
-
-
-struct ActionSubrecordHeader
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 actionClass; /* The JustClass value associated with this
- * ActionSubrecord. */
- HBUINT16 actionType; /* The type of postcompensation action. */
- HBUINT16 actionLength; /* Length of this ActionSubrecord record, which
- * must be a multiple of 4. */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct DecompositionAction
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- ActionSubrecordHeader
- header;
- F16DOT16 lowerLimit; /* If the distance factor is less than this value,
- * then the ligature is decomposed. */
- F16DOT16 upperLimit; /* If the distance factor is greater than this value,
- * then the ligature is decomposed. */
- HBUINT16 order; /* Numerical order in which this ligature will
- * be decomposed; you may want infrequent ligatures
- * to decompose before more frequent ones. The ligatures
- * on the line of text will decompose in increasing
- * value of this field. */
- Array16Of<HBUINT16>
- decomposedglyphs;
- /* Number of 16-bit glyph indexes that follow;
- * the ligature will be decomposed into these glyphs.
- *
- * Array of decomposed glyphs. */
- public:
- DEFINE_SIZE_ARRAY (18, decomposedglyphs);
-};
-
-struct UnconditionalAddGlyphAction
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- ActionSubrecordHeader
- header;
- HBGlyphID16 addGlyph; /* Glyph that should be added if the distance factor
- * is growing. */
-
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct ConditionalAddGlyphAction
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- ActionSubrecordHeader
- header;
- F16DOT16 substThreshold; /* Distance growth factor (in ems) at which
- * this glyph is replaced and the growth factor
- * recalculated. */
- HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is
- * 0xFFFF, no extra glyph will be added. Note that
- * generally when a glyph is added, justification
- * will need to be redone. */
- HBGlyphID16 substGlyph; /* Glyph to be substituted for this glyph if the
- * growth factor equals or exceeds the value of
- * substThreshold. */
- public:
- DEFINE_SIZE_STATIC (14);
-};
-
-struct DuctileGlyphAction
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- ActionSubrecordHeader
- header;
- HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
- * This would normally be 0x64756374 ('duct'),
- * but you may use any axis the font contains. */
- F16DOT16 minimumLimit; /* The lowest value for the ductility axis that
- * still yields an acceptable appearance. Normally
- * this will be 1.0. */
- F16DOT16 noStretchValue; /* This is the default value that corresponds to
- * no change in appearance. Normally, this will
- * be 1.0. */
- F16DOT16 maximumLimit; /* The highest value for the ductility axis that
- * still yields an acceptable appearance. */
- public:
- DEFINE_SIZE_STATIC (22);
-};
-
-struct RepeatedAddGlyphAction
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- ActionSubrecordHeader
- header;
- HBUINT16 flags; /* Currently unused; set to 0. */
- HBGlyphID16 glyph; /* Glyph that should be added if the distance factor
- * is growing. */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-struct ActionSubrecord
-{
- unsigned int get_length () const { return u.header.actionLength; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (u.header.actionType)
- {
- case 0: return_trace (u.decompositionAction.sanitize (c));
- case 1: return_trace (u.unconditionalAddGlyphAction.sanitize (c));
- case 2: return_trace (u.conditionalAddGlyphAction.sanitize (c));
- // case 3: return_trace (u.stretchGlyphAction.sanitize (c));
- case 4: return_trace (u.decompositionAction.sanitize (c));
- case 5: return_trace (u.decompositionAction.sanitize (c));
- default: return_trace (true);
- }
- }
-
- protected:
- union {
- ActionSubrecordHeader header;
- DecompositionAction decompositionAction;
- UnconditionalAddGlyphAction unconditionalAddGlyphAction;
- ConditionalAddGlyphAction conditionalAddGlyphAction;
- /* StretchGlyphAction stretchGlyphAction; -- Not supported by CoreText */
- DuctileGlyphAction ductileGlyphAction;
- RepeatedAddGlyphAction repeatedAddGlyphAction;
- } u; /* Data. The format of this data depends on
- * the value of the actionType field. */
- public:
- DEFINE_SIZE_UNION (6, header);
-};
-
-struct PostcompensationActionChain
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- unsigned int offset = min_size;
- for (unsigned int i = 0; i < count; i++)
- {
- const ActionSubrecord& subrecord = StructAtOffset<ActionSubrecord> (this, offset);
- if (unlikely (!subrecord.sanitize (c))) return_trace (false);
- offset += subrecord.get_length ();
- }
-
- return_trace (true);
- }
-
- protected:
- HBUINT32 count;
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct JustWidthDeltaEntry
-{
- enum Flags
- {
- Reserved1 =0xE000,/* Reserved. You should set these bits to zero. */
- UnlimiteGap =0x1000,/* The glyph can take unlimited gap. When this
- * glyph participates in the justification process,
- * it and any other glyphs on the line having this
- * bit set absorb all the remaining gap. */
- Reserved2 =0x0FF0,/* Reserved. You should set these bits to zero. */
- Priority =0x000F /* The justification priority of the glyph. */
- };
-
- enum Priority
- {
- Kashida = 0, /* Kashida priority. This is the highest priority
- * during justification. */
- Whitespace = 1, /* Whitespace priority. Any whitespace glyphs (as
- * identified in the glyph properties table) will
- * get this priority. */
- InterCharacter = 2, /* Inter-character priority. Give this to any
- * remaining glyphs. */
- NullPriority = 3 /* Null priority. You should set this priority for
- * glyphs that only participate in justification
- * after the above priorities. Normally all glyphs
- * have one of the previous three values. If you
- * don't want a glyph to participate in justification,
- * and you don't want to set its factors to zero,
- * you may instead assign it to the null priority. */
- };
-
- protected:
- F16DOT16 beforeGrowLimit;/* The ratio by which the advance width of the
- * glyph is permitted to grow on the left or top side. */
- F16DOT16 beforeShrinkLimit;
- /* The ratio by which the advance width of the
- * glyph is permitted to shrink on the left or top side. */
- F16DOT16 afterGrowLimit; /* The ratio by which the advance width of the glyph
- * is permitted to shrink on the left or top side. */
- F16DOT16 afterShrinkLimit;
- /* The ratio by which the advance width of the glyph
- * is at most permitted to shrink on the right or
- * bottom side. */
- HBUINT16 growFlags; /* Flags controlling the grow case. */
- HBUINT16 shrinkFlags; /* Flags controlling the shrink case. */
-
- public:
- DEFINE_SIZE_STATIC (20);
-};
-
-struct WidthDeltaPair
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT32 justClass; /* The justification category associated
- * with the wdRecord field. Only 7 bits of
- * this field are used. (The other bits are
- * used as padding to guarantee longword
- * alignment of the following record). */
- JustWidthDeltaEntry
- wdRecord; /* The actual width delta record. */
-
- public:
- DEFINE_SIZE_STATIC (24);
-};
-
-typedef OT::Array32Of<WidthDeltaPair> WidthDeltaCluster;
-
-struct JustificationCategory
-{
- typedef void EntryData;
-
- enum Flags
- {
- SetMark =0x8000,/* If set, make the current glyph the marked
- * glyph. */
- DontAdvance =0x4000,/* If set, don't advance to the next glyph before
- * going to the new state. */
- MarkCategory =0x3F80,/* The justification category for the marked
- * glyph if nonzero. */
- CurrentCategory =0x007F /* The justification category for the current
- * glyph if nonzero. */
- };
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- morphHeader.sanitize (c) &&
- stHeader.sanitize (c)));
- }
-
- protected:
- ChainSubtable<ObsoleteTypes>
- morphHeader; /* Metamorphosis-style subtable header. */
- StateTable<ObsoleteTypes, EntryData>
- stHeader; /* The justification insertion state table header */
- public:
- DEFINE_SIZE_STATIC (30);
-};
-
-struct JustificationHeader
-{
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- justClassTable.sanitize (c, base, base) &&
- wdcTable.sanitize (c, base) &&
- pcTable.sanitize (c, base) &&
- lookupTable.sanitize (c, base)));
- }
-
- protected:
- Offset16To<JustificationCategory>
- justClassTable; /* Offset to the justification category state table. */
- Offset16To<WidthDeltaCluster>
- wdcTable; /* Offset from start of justification table to start
- * of the subtable containing the width delta factors
- * for the glyphs in your font.
- *
- * The width delta clusters table. */
- Offset16To<PostcompensationActionChain>
- pcTable; /* Offset from start of justification table to start
- * of postcompensation subtable (set to zero if none).
- *
- * The postcompensation subtable, if present in the font. */
- Lookup<Offset16To<WidthDeltaCluster>>
- lookupTable; /* Lookup table associating glyphs with width delta
- * clusters. See the description of Width Delta Clusters
- * table for details on how to interpret the lookup values. */
-
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-struct just
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_just;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
-
- return_trace (likely (c->check_struct (this) &&
- version.major == 1 &&
- horizData.sanitize (c, this, this) &&
- vertData.sanitize (c, this, this)));
- }
-
- protected:
- FixedVersion<>version; /* Version of the justification table
- * (0x00010000u for version 1.0). */
- HBUINT16 format; /* Format of the justification table (set to 0). */
- Offset16To<JustificationHeader>
- horizData; /* Byte offset from the start of the justification table
- * to the header for tables that contain justification
- * information for horizontal text.
- * If you are not including this information,
- * store 0. */
- Offset16To<JustificationHeader>
- vertData; /* ditto, vertical */
-
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_JUST_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh
deleted file mode 100644
index 35d7c84c2bc..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-kerx-table.hh
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- * Copyright © 2018 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_AAT_LAYOUT_KERX_TABLE_HH
-#define HB_AAT_LAYOUT_KERX_TABLE_HH
-
-#include "hb-kern.hh"
-#include "hb-aat-layout-ankr-table.hh"
-
-/*
- * kerx -- Extended Kerning
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
- */
-#define HB_AAT_TAG_kerx HB_TAG('k','e','r','x')
-
-
-namespace AAT {
-
-using namespace OT;
-
-
-static inline int
-kerxTupleKern (int value,
- unsigned int tupleCount,
- const void *base,
- hb_aat_apply_context_t *c)
-{
- if (likely (!tupleCount || !c)) return value;
-
- unsigned int offset = value;
- const FWORD *pv = &StructAtOffset<FWORD> (base, offset);
- if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0;
- return *pv;
-}
-
-
-struct hb_glyph_pair_t
-{
- hb_codepoint_t left;
- hb_codepoint_t right;
-};
-
-struct KernPair
-{
- int get_kerning () const { return value; }
-
- int cmp (const hb_glyph_pair_t &o) const
- {
- int ret = left.cmp (o.left);
- if (ret) return ret;
- return right.cmp (o.right);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBGlyphID16 left;
- HBGlyphID16 right;
- FWORD value;
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-template <typename KernSubTableHeader>
-struct KerxSubTableFormat0
-{
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
- hb_aat_apply_context_t *c = nullptr) const
- {
- hb_glyph_pair_t pair = {left, right};
- int v = pairs.bsearch (pair).get_kerning ();
- return kerxTupleKern (v, header.tuple_count (), this, c);
- }
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- if (!c->plan->requested_kerning)
- return false;
-
- if (header.coverage & header.Backwards)
- return false;
-
- accelerator_t accel (*this, c);
- hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
- machine.kern (c->font, c->buffer, c->plan->kern_mask);
-
- return_trace (true);
- }
-
- struct accelerator_t
- {
- const KerxSubTableFormat0 &table;
- hb_aat_apply_context_t *c;
-
- accelerator_t (const KerxSubTableFormat0 &table_,
- hb_aat_apply_context_t *c_) :
- table (table_), c (c_) {}
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return table.get_kerning (left, right, c); }
- };
-
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (pairs.sanitize (c)));
- }
-
- protected:
- KernSubTableHeader header;
- BinSearchArrayOf<KernPair, typename KernSubTableHeader::Types::HBUINT>
- pairs; /* Sorted kern records. */
- public:
- DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 16, pairs);
-};
-
-
-template <bool extended>
-struct Format1Entry;
-
-template <>
-struct Format1Entry<true>
-{
- enum Flags
- {
- Push = 0x8000, /* If set, push this glyph on the kerning stack. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph
- * before going to the new state. */
- Reset = 0x2000, /* If set, reset the kerning data (clear the stack) */
- Reserved = 0x1FFF, /* Not used; set to 0. */
- };
-
- struct EntryData
- {
- HBUINT16 kernActionIndex;/* Index into the kerning value array. If
- * this index is 0xFFFF, then no kerning
- * is to be performed. */
- public:
- DEFINE_SIZE_STATIC (2);
- };
-
- static bool performAction (const Entry<EntryData> &entry)
- { return entry.data.kernActionIndex != 0xFFFF; }
-
- static unsigned int kernActionIndex (const Entry<EntryData> &entry)
- { return entry.data.kernActionIndex; }
-};
-template <>
-struct Format1Entry<false>
-{
- enum Flags
- {
- Push = 0x8000, /* If set, push this glyph on the kerning stack. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph
- * before going to the new state. */
- Offset = 0x3FFF, /* Byte offset from beginning of subtable to the
- * value table for the glyphs on the kerning stack. */
-
- Reset = 0x0000, /* Not supported? */
- };
-
- typedef void EntryData;
-
- static bool performAction (const Entry<EntryData> &entry)
- { return entry.flags & Offset; }
-
- static unsigned int kernActionIndex (const Entry<EntryData> &entry)
- { return entry.flags & Offset; }
-};
-
-template <typename KernSubTableHeader>
-struct KerxSubTableFormat1
-{
- typedef typename KernSubTableHeader::Types Types;
- typedef typename Types::HBUINT HBUINT;
-
- typedef Format1Entry<Types::extended> Format1EntryT;
- typedef typename Format1EntryT::EntryData EntryData;
-
- struct driver_context_t
- {
- static constexpr bool in_place = true;
- enum
- {
- DontAdvance = Format1EntryT::DontAdvance,
- };
-
- driver_context_t (const KerxSubTableFormat1 *table_,
- hb_aat_apply_context_t *c_) :
- c (c_),
- table (table_),
- /* Apparently the offset kernAction is from the beginning of the state-machine,
- * similar to offsets in morx table, NOT from beginning of this table, like
- * other subtables in kerx. Discovered via testing. */
- kernAction (&table->machine + table->kernAction),
- depth (0),
- crossStream (table->header.coverage & table->header.CrossStream) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
- const Entry<EntryData> &entry)
- { return Format1EntryT::performAction (entry); }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
- unsigned int flags = entry.flags;
-
- if (flags & Format1EntryT::Reset)
- depth = 0;
-
- if (flags & Format1EntryT::Push)
- {
- if (likely (depth < ARRAY_LENGTH (stack)))
- stack[depth++] = buffer->idx;
- else
- depth = 0; /* Probably not what CoreText does, but better? */
- }
-
- if (Format1EntryT::performAction (entry) && depth)
- {
- unsigned int tuple_count = hb_max (1u, table->header.tuple_count ());
-
- unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
- kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
- const FWORD *actions = &kernAction[kern_idx];
- if (!c->sanitizer.check_array (actions, depth, tuple_count))
- {
- depth = 0;
- return;
- }
-
- hb_mask_t kern_mask = c->plan->kern_mask;
-
- /* From Apple 'kern' spec:
- * "Each pops one glyph from the kerning stack and applies the kerning value to it.
- * The end of the list is marked by an odd value... */
- bool last = false;
- while (!last && depth)
- {
- unsigned int idx = stack[--depth];
- int v = *actions;
- actions += tuple_count;
- if (idx >= buffer->len) continue;
-
- /* "The end of the list is marked by an odd value..." */
- last = v & 1;
- v &= ~1;
-
- hb_glyph_position_t &o = buffer->pos[idx];
-
- if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- {
- if (crossStream)
- {
- /* The following flag is undocumented in the spec, but described
- * in the 'kern' table example. */
- if (v == -0x8000)
- {
- o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_NONE;
- o.attach_chain() = 0;
- o.y_offset = 0;
- }
- else if (o.attach_type())
- {
- o.y_offset += c->font->em_scale_y (v);
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- }
- }
- else if (buffer->info[idx].mask & kern_mask)
- {
- o.x_advance += c->font->em_scale_x (v);
- o.x_offset += c->font->em_scale_x (v);
- }
- }
- else
- {
- if (crossStream)
- {
- /* CoreText doesn't do crossStream kerning in vertical. We do. */
- if (v == -0x8000)
- {
- o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_NONE;
- o.attach_chain() = 0;
- o.x_offset = 0;
- }
- else if (o.attach_type())
- {
- o.x_offset += c->font->em_scale_x (v);
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- }
- }
- else if (buffer->info[idx].mask & kern_mask)
- {
- o.y_advance += c->font->em_scale_y (v);
- o.y_offset += c->font->em_scale_y (v);
- }
- }
- }
- }
- }
-
- private:
- hb_aat_apply_context_t *c;
- const KerxSubTableFormat1 *table;
- const UnsizedArrayOf<FWORD> &kernAction;
- unsigned int stack[8];
- unsigned int depth;
- bool crossStream;
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- if (!c->plan->requested_kerning &&
- !(header.coverage & header.CrossStream))
- return false;
-
- driver_context_t dc (this, c);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
- driver.drive (&dc, c);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* The rest of array sanitizations are done at run-time. */
- return_trace (likely (c->check_struct (this) &&
- machine.sanitize (c)));
- }
-
- protected:
- KernSubTableHeader header;
- StateTable<Types, EntryData> machine;
- NNOffsetTo<UnsizedArrayOf<FWORD>, HBUINT> kernAction;
- public:
- DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 5 * sizeof (HBUINT));
-};
-
-template <typename KernSubTableHeader>
-struct KerxSubTableFormat2
-{
- typedef typename KernSubTableHeader::Types Types;
- typedef typename Types::HBUINT HBUINT;
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
- hb_aat_apply_context_t *c) const
- {
- unsigned int num_glyphs = c->sanitizer.get_num_glyphs ();
- unsigned int l = (this+leftClassTable).get_class (left, num_glyphs, 0);
- unsigned int r = (this+rightClassTable).get_class (right, num_glyphs, 0);
-
- const UnsizedArrayOf<FWORD> &arrayZ = this+array;
- unsigned int kern_idx = l + r;
- kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ);
- const FWORD *v = &arrayZ[kern_idx];
- if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
-
- return kerxTupleKern (*v, header.tuple_count (), this, c);
- }
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- if (!c->plan->requested_kerning)
- return false;
-
- if (header.coverage & header.Backwards)
- return false;
-
- accelerator_t accel (*this, c);
- hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
- machine.kern (c->font, c->buffer, c->plan->kern_mask);
-
- return_trace (true);
- }
-
- struct accelerator_t
- {
- const KerxSubTableFormat2 &table;
- hb_aat_apply_context_t *c;
-
- accelerator_t (const KerxSubTableFormat2 &table_,
- hb_aat_apply_context_t *c_) :
- table (table_), c (c_) {}
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return table.get_kerning (left, right, c); }
- };
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- leftClassTable.sanitize (c, this) &&
- rightClassTable.sanitize (c, this) &&
- c->check_range (this, array)));
- }
-
- protected:
- KernSubTableHeader header;
- HBUINT rowWidth; /* The width, in bytes, of a row in the table. */
- NNOffsetTo<typename Types::ClassTypeWide, HBUINT>
- leftClassTable; /* Offset from beginning of this subtable to
- * left-hand class table. */
- NNOffsetTo<typename Types::ClassTypeWide, HBUINT>
- rightClassTable;/* Offset from beginning of this subtable to
- * right-hand class table. */
- NNOffsetTo<UnsizedArrayOf<FWORD>, HBUINT>
- array; /* Offset from beginning of this subtable to
- * the start of the kerning array. */
- public:
- DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 4 * sizeof (HBUINT));
-};
-
-template <typename KernSubTableHeader>
-struct KerxSubTableFormat4
-{
- typedef ExtendedTypes Types;
-
- struct EntryData
- {
- HBUINT16 ankrActionIndex;/* Either 0xFFFF (for no action) or the index of
- * the action to perform. */
- public:
- DEFINE_SIZE_STATIC (2);
- };
-
- struct driver_context_t
- {
- static constexpr bool in_place = true;
- enum Flags
- {
- Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
- * going to the new state. */
- Reserved = 0x3FFF, /* Not used; set to 0. */
- };
-
- enum SubTableFlags
- {
- ActionType = 0xC0000000, /* A two-bit field containing the action type. */
- Unused = 0x3F000000, /* Unused - must be zero. */
- Offset = 0x00FFFFFF, /* Masks the offset in bytes from the beginning
- * of the subtable to the beginning of the control
- * point table. */
- };
-
- driver_context_t (const KerxSubTableFormat4 *table,
- hb_aat_apply_context_t *c_) :
- c (c_),
- action_type ((table->flags & ActionType) >> 30),
- ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))),
- mark_set (false),
- mark (0) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
- const Entry<EntryData> &entry)
- { return entry.data.ankrActionIndex != 0xFFFF; }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
-
- if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len)
- {
- hb_glyph_position_t &o = buffer->cur_pos();
- switch (action_type)
- {
- case 0: /* Control Point Actions.*/
- {
- /* Indexed into glyph outline. */
- /* Each action (record in ankrData) contains two 16-bit fields, so we must
- double the ankrActionIndex to get the correct offset here. */
- const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2];
- if (!c->sanitizer.check_array (data, 2)) return;
- unsigned int markControlPoint = *data++;
- unsigned int currControlPoint = *data++;
- hb_position_t markX = 0;
- hb_position_t markY = 0;
- hb_position_t currX = 0;
- hb_position_t currY = 0;
- if (!c->font->get_glyph_contour_point_for_origin (c->buffer->info[mark].codepoint,
- markControlPoint,
- HB_DIRECTION_LTR /*XXX*/,
- &markX, &markY) ||
- !c->font->get_glyph_contour_point_for_origin (c->buffer->cur ().codepoint,
- currControlPoint,
- HB_DIRECTION_LTR /*XXX*/,
- &currX, &currY))
- return;
-
- o.x_offset = markX - currX;
- o.y_offset = markY - currY;
- }
- break;
-
- case 1: /* Anchor Point Actions. */
- {
- /* Indexed into 'ankr' table. */
- /* Each action (record in ankrData) contains two 16-bit fields, so we must
- double the ankrActionIndex to get the correct offset here. */
- const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex * 2];
- if (!c->sanitizer.check_array (data, 2)) return;
- unsigned int markAnchorPoint = *data++;
- unsigned int currAnchorPoint = *data++;
- const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint,
- markAnchorPoint,
- c->sanitizer.get_num_glyphs ());
- const Anchor &currAnchor = c->ankr_table->get_anchor (c->buffer->cur ().codepoint,
- currAnchorPoint,
- c->sanitizer.get_num_glyphs ());
-
- o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
- o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
- }
- break;
-
- case 2: /* Control Point Coordinate Actions. */
- {
- /* Each action contains four 16-bit fields, so we multiply the ankrActionIndex
- by 4 to get the correct offset for the given action. */
- const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex * 4];
- if (!c->sanitizer.check_array (data, 4)) return;
- int markX = *data++;
- int markY = *data++;
- int currX = *data++;
- int currY = *data++;
-
- o.x_offset = c->font->em_scale_x (markX) - c->font->em_scale_x (currX);
- o.y_offset = c->font->em_scale_y (markY) - c->font->em_scale_y (currY);
- }
- break;
- }
- o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK;
- o.attach_chain() = (int) mark - (int) buffer->idx;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- }
-
- if (entry.flags & Mark)
- {
- mark_set = true;
- mark = buffer->idx;
- }
- }
-
- private:
- hb_aat_apply_context_t *c;
- unsigned int action_type;
- const HBUINT16 *ankrData;
- bool mark_set;
- unsigned int mark;
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- driver_context_t dc (this, c);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
- driver.drive (&dc, c);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* The rest of array sanitizations are done at run-time. */
- return_trace (likely (c->check_struct (this) &&
- machine.sanitize (c)));
- }
-
- protected:
- KernSubTableHeader header;
- StateTable<Types, EntryData> machine;
- HBUINT32 flags;
- public:
- DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 20);
-};
-
-template <typename KernSubTableHeader>
-struct KerxSubTableFormat6
-{
- enum Flags
- {
- ValuesAreLong = 0x00000001,
- };
-
- bool is_long () const { return flags & ValuesAreLong; }
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
- hb_aat_apply_context_t *c) const
- {
- unsigned int num_glyphs = c->sanitizer.get_num_glyphs ();
- if (is_long ())
- {
- const typename U::Long &t = u.l;
- unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
- unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
- unsigned int offset = l + r;
- if (unlikely (offset < l)) return 0; /* Addition overflow. */
- if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0;
- const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
- if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
- return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c);
- }
- else
- {
- const typename U::Short &t = u.s;
- unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
- unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
- unsigned int offset = l + r;
- const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
- if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
- return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c);
- }
- }
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- if (!c->plan->requested_kerning)
- return false;
-
- if (header.coverage & header.Backwards)
- return false;
-
- accelerator_t accel (*this, c);
- hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
- machine.kern (c->font, c->buffer, c->plan->kern_mask);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (is_long () ?
- (
- u.l.rowIndexTable.sanitize (c, this) &&
- u.l.columnIndexTable.sanitize (c, this) &&
- c->check_range (this, u.l.array)
- ) : (
- u.s.rowIndexTable.sanitize (c, this) &&
- u.s.columnIndexTable.sanitize (c, this) &&
- c->check_range (this, u.s.array)
- )) &&
- (header.tuple_count () == 0 ||
- c->check_range (this, vector))));
- }
-
- struct accelerator_t
- {
- const KerxSubTableFormat6 &table;
- hb_aat_apply_context_t *c;
-
- accelerator_t (const KerxSubTableFormat6 &table_,
- hb_aat_apply_context_t *c_) :
- table (table_), c (c_) {}
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return table.get_kerning (left, right, c); }
- };
-
- protected:
- KernSubTableHeader header;
- HBUINT32 flags;
- HBUINT16 rowCount;
- HBUINT16 columnCount;
- union U
- {
- struct Long
- {
- NNOffset32To<Lookup<HBUINT32>> rowIndexTable;
- NNOffset32To<Lookup<HBUINT32>> columnIndexTable;
- NNOffset32To<UnsizedArrayOf<FWORD32>> array;
- } l;
- struct Short
- {
- NNOffset32To<Lookup<HBUINT16>> rowIndexTable;
- NNOffset32To<Lookup<HBUINT16>> columnIndexTable;
- NNOffset32To<UnsizedArrayOf<FWORD>> array;
- } s;
- } u;
- NNOffset32To<UnsizedArrayOf<FWORD>> vector;
- public:
- DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24);
-};
-
-
-struct KerxSubTableHeader
-{
- typedef ExtendedTypes Types;
-
- unsigned tuple_count () const { return tupleCount; }
- bool is_horizontal () const { return !(coverage & Vertical); }
-
- enum Coverage
- {
- Vertical = 0x80000000u, /* Set if table has vertical kerning values. */
- CrossStream = 0x40000000u, /* Set if table has cross-stream kerning values. */
- Variation = 0x20000000u, /* Set if table has variation kerning values. */
- Backwards = 0x10000000u, /* If clear, process the glyphs forwards, that
- * is, from first to last in the glyph stream.
- * If we, process them from last to first.
- * This flag only applies to state-table based
- * 'kerx' subtables (types 1 and 4). */
- Reserved = 0x0FFFFF00u, /* Reserved, set to zero. */
- SubtableType= 0x000000FFu, /* Subtable type. */
- };
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT32 length;
- HBUINT32 coverage;
- HBUINT32 tupleCount;
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct KerxSubTable
-{
- friend struct kerx;
-
- unsigned int get_size () const { return u.header.length; }
- unsigned int get_type () const { return u.header.coverage & u.header.SubtableType; }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- unsigned int subtable_type = get_type ();
- TRACE_DISPATCH (this, subtable_type);
- switch (subtable_type) {
- case 0: return_trace (c->dispatch (u.format0, std::forward<Ts> (ds)...));
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
- case 6: return_trace (c->dispatch (u.format6, std::forward<Ts> (ds)...));
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.header.sanitize (c) ||
- u.header.length <= u.header.static_size ||
- !c->check_range (this, u.header.length))
- return_trace (false);
-
- return_trace (dispatch (c));
- }
-
- public:
- union {
- KerxSubTableHeader header;
- KerxSubTableFormat0<KerxSubTableHeader> format0;
- KerxSubTableFormat1<KerxSubTableHeader> format1;
- KerxSubTableFormat2<KerxSubTableHeader> format2;
- KerxSubTableFormat4<KerxSubTableHeader> format4;
- KerxSubTableFormat6<KerxSubTableHeader> format6;
- } u;
- public:
- DEFINE_SIZE_MIN (12);
-};
-
-
-/*
- * The 'kerx' Table
- */
-
-template <typename T>
-struct KerxTable
-{
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- const T* thiz () const { return static_cast<const T *> (this); }
-
- bool has_state_machine () const
- {
- typedef typename T::SubTable SubTable;
-
- const SubTable *st = &thiz()->firstSubTable;
- unsigned int count = thiz()->tableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if (st->get_type () == 1)
- return true;
- st = &StructAfter<SubTable> (*st);
- }
- return false;
- }
-
- bool has_cross_stream () const
- {
- typedef typename T::SubTable SubTable;
-
- const SubTable *st = &thiz()->firstSubTable;
- unsigned int count = thiz()->tableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if (st->u.header.coverage & st->u.header.CrossStream)
- return true;
- st = &StructAfter<SubTable> (*st);
- }
- return false;
- }
-
- int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- {
- typedef typename T::SubTable SubTable;
-
- int v = 0;
- const SubTable *st = &thiz()->firstSubTable;
- unsigned int count = thiz()->tableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
- !st->u.header.is_horizontal ())
- continue;
- v += st->get_kerning (left, right);
- st = &StructAfter<SubTable> (*st);
- }
- return v;
- }
-
- bool apply (AAT::hb_aat_apply_context_t *c) const
- {
- c->buffer->unsafe_to_concat ();
-
- typedef typename T::SubTable SubTable;
-
- bool ret = false;
- bool seenCrossStream = false;
- c->set_lookup_index (0);
- const SubTable *st = &thiz()->firstSubTable;
- unsigned int count = thiz()->tableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- bool reverse;
-
- if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
- goto skip;
-
- if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
- goto skip;
-
- reverse = bool (st->u.header.coverage & st->u.header.Backwards) !=
- HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
-
- if (!c->buffer->message (c->font, "start subtable %u", c->lookup_index))
- goto skip;
-
- if (!seenCrossStream &&
- (st->u.header.coverage & st->u.header.CrossStream))
- {
- /* Attach all glyphs into a chain. */
- seenCrossStream = true;
- hb_glyph_position_t *pos = c->buffer->pos;
- unsigned int count = c->buffer->len;
- for (unsigned int i = 0; i < count; i++)
- {
- pos[i].attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_CURSIVE;
- pos[i].attach_chain() = HB_DIRECTION_IS_FORWARD (c->buffer->props.direction) ? -1 : +1;
- /* We intentionally don't set HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT,
- * since there needs to be a non-zero attachment for post-positioning to
- * be needed. */
- }
- }
-
- if (reverse)
- c->buffer->reverse ();
-
- {
- /* See comment in sanitize() for conditional here. */
- hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr);
- ret |= st->dispatch (c);
- }
-
- if (reverse)
- c->buffer->reverse ();
-
- (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index);
-
- skip:
- st = &StructAfter<SubTable> (*st);
- c->set_lookup_index (c->lookup_index + 1);
- }
-
- return ret;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!thiz()->version.sanitize (c) ||
- (unsigned) thiz()->version < (unsigned) T::minVersion ||
- !thiz()->tableCount.sanitize (c)))
- return_trace (false);
-
- typedef typename T::SubTable SubTable;
-
- const SubTable *st = &thiz()->firstSubTable;
- unsigned int count = thiz()->tableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if (unlikely (!st->u.header.sanitize (c)))
- return_trace (false);
- /* OpenType kern table has 2-byte subtable lengths. That's limiting.
- * MS implementation also only supports one subtable, of format 0,
- * anyway. Certain versions of some fonts, like Calibry, contain
- * kern subtable that exceeds 64kb. Looks like, the subtable length
- * is simply ignored. Which makes sense. It's only needed if you
- * have multiple subtables. To handle such fonts, we just ignore
- * the length for the last subtable. */
- hb_sanitize_with_object_t with (c, i < count - 1 ? st : (const SubTable *) nullptr);
-
- if (unlikely (!st->sanitize (c)))
- return_trace (false);
-
- st = &StructAfter<SubTable> (*st);
- }
-
- return_trace (true);
- }
-};
-
-struct kerx : KerxTable<kerx>
-{
- friend struct KerxTable<kerx>;
-
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_kerx;
- static constexpr unsigned minVersion = 2u;
-
- typedef KerxSubTableHeader SubTableHeader;
- typedef SubTableHeader::Types Types;
- typedef KerxSubTable SubTable;
-
- bool has_data () const { return version; }
-
- protected:
- HBUINT16 version; /* The version number of the extended kerning table
- * (currently 2, 3, or 4). */
- HBUINT16 unused; /* Set to 0. */
- HBUINT32 tableCount; /* The number of subtables included in the extended kerning
- * table. */
- SubTable firstSubTable; /* Subtables. */
-/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
-
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_KERX_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh
deleted file mode 100644
index f41ecc197fb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-morx-table.hh
+++ /dev/null
@@ -1,1210 +0,0 @@
-/*
- * 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_AAT_LAYOUT_MORX_TABLE_HH
-#define HB_AAT_LAYOUT_MORX_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-aat-layout-common.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-layout-gdef-table.hh"
-#include "hb-aat-map.hh"
-
-/*
- * morx -- Extended Glyph Metamorphosis
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html
- */
-#define HB_AAT_TAG_morx HB_TAG('m','o','r','x')
-#define HB_AAT_TAG_mort HB_TAG('m','o','r','t')
-
-
-namespace AAT {
-
-using namespace OT;
-
-template <typename Types>
-struct RearrangementSubtable
-{
- typedef typename Types::HBUINT HBUINT;
-
- typedef void EntryData;
-
- struct driver_context_t
- {
- static constexpr bool in_place = true;
- enum Flags
- {
- MarkFirst = 0x8000, /* If set, make the current glyph the first
- * glyph to be rearranged. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph
- * before going to the new state. This means
- * that the glyph index doesn't change, even
- * if the glyph at that index has changed. */
- MarkLast = 0x2000, /* If set, make the current glyph the last
- * glyph to be rearranged. */
- Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */
- Verb = 0x000F, /* The type of rearrangement specified. */
- };
-
- driver_context_t (const RearrangementSubtable *table HB_UNUSED) :
- ret (false),
- start (0), end (0) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
- const Entry<EntryData> &entry)
- {
- return (entry.flags & Verb) && start < end;
- }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
- unsigned int flags = entry.flags;
-
- if (flags & MarkFirst)
- start = buffer->idx;
-
- if (flags & MarkLast)
- end = hb_min (buffer->idx + 1, buffer->len);
-
- if ((flags & Verb) && start < end)
- {
- /* The following map has two nibbles, for start-side
- * and end-side. Values of 0,1,2 mean move that many
- * to the other side. Value of 3 means move 2 and
- * flip them. */
- const unsigned char map[16] =
- {
- 0x00, /* 0 no change */
- 0x10, /* 1 Ax => xA */
- 0x01, /* 2 xD => Dx */
- 0x11, /* 3 AxD => DxA */
- 0x20, /* 4 ABx => xAB */
- 0x30, /* 5 ABx => xBA */
- 0x02, /* 6 xCD => CDx */
- 0x03, /* 7 xCD => DCx */
- 0x12, /* 8 AxCD => CDxA */
- 0x13, /* 9 AxCD => DCxA */
- 0x21, /* 10 ABxD => DxAB */
- 0x31, /* 11 ABxD => DxBA */
- 0x22, /* 12 ABxCD => CDxAB */
- 0x32, /* 13 ABxCD => CDxBA */
- 0x23, /* 14 ABxCD => DCxAB */
- 0x33, /* 15 ABxCD => DCxBA */
- };
-
- unsigned int m = map[flags & Verb];
- unsigned int l = hb_min (2u, m >> 4);
- unsigned int r = hb_min (2u, m & 0x0F);
- bool reverse_l = 3 == (m >> 4);
- bool reverse_r = 3 == (m & 0x0F);
-
- if (end - start >= l + r && end-start <= HB_MAX_CONTEXT_LENGTH)
- {
- buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len));
- buffer->merge_clusters (start, end);
-
- hb_glyph_info_t *info = buffer->info;
- hb_glyph_info_t buf[4];
-
- hb_memcpy (buf, info + start, l * sizeof (buf[0]));
- hb_memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
-
- if (l != r)
- memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0]));
-
- hb_memcpy (info + start, buf + 2, r * sizeof (buf[0]));
- hb_memcpy (info + end - l, buf, l * sizeof (buf[0]));
- if (reverse_l)
- {
- buf[0] = info[end - 1];
- info[end - 1] = info[end - 2];
- info[end - 2] = buf[0];
- }
- if (reverse_r)
- {
- buf[0] = info[start];
- info[start] = info[start + 1];
- info[start + 1] = buf[0];
- }
- }
- }
- }
-
- public:
- bool ret;
- private:
- unsigned int start;
- unsigned int end;
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- driver_context_t dc (this);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
- driver.drive (&dc, c);
-
- return_trace (dc.ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (machine.sanitize (c));
- }
-
- protected:
- StateTable<Types, EntryData> machine;
- public:
- DEFINE_SIZE_STATIC (16);
-};
-
-template <typename Types>
-struct ContextualSubtable
-{
- typedef typename Types::HBUINT HBUINT;
-
- struct EntryData
- {
- HBUINT16 markIndex; /* Index of the substitution table for the
- * marked glyph (use 0xFFFF for none). */
- HBUINT16 currentIndex; /* Index of the substitution table for the
- * current glyph (use 0xFFFF for none). */
- public:
- DEFINE_SIZE_STATIC (4);
- };
-
- struct driver_context_t
- {
- static constexpr bool in_place = true;
- enum Flags
- {
- SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
- * going to the new state. */
- Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
- };
-
- driver_context_t (const ContextualSubtable *table_,
- hb_aat_apply_context_t *c_) :
- ret (false),
- c (c_),
- gdef (*c->gdef_table),
- mark_set (false),
- has_glyph_classes (gdef.has_glyph_classes ()),
- mark (0),
- table (table_),
- subs (table+table->substitutionTables) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
-
- if (buffer->idx == buffer->len && !mark_set)
- return false;
-
- return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
- }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
-
- /* Looks like CoreText applies neither mark nor current substitution for
- * end-of-text if mark was not explicitly set. */
- if (buffer->idx == buffer->len && !mark_set)
- return;
-
- const HBGlyphID16 *replacement;
-
- replacement = nullptr;
- if (Types::extended)
- {
- if (entry.data.markIndex != 0xFFFF)
- {
- const Lookup<HBGlyphID16> &lookup = subs[entry.data.markIndex];
- replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
- }
- }
- else
- {
- unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
- const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
- replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
- if (!replacement->sanitize (&c->sanitizer) || !*replacement)
- replacement = nullptr;
- }
- if (replacement)
- {
- buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len));
- buffer->info[mark].codepoint = *replacement;
- if (has_glyph_classes)
- _hb_glyph_info_set_glyph_props (&buffer->info[mark],
- gdef.get_glyph_props (*replacement));
- ret = true;
- }
-
- replacement = nullptr;
- unsigned int idx = hb_min (buffer->idx, buffer->len - 1);
- if (Types::extended)
- {
- if (entry.data.currentIndex != 0xFFFF)
- {
- const Lookup<HBGlyphID16> &lookup = subs[entry.data.currentIndex];
- replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
- }
- }
- else
- {
- unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
- const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
- replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
- if (!replacement->sanitize (&c->sanitizer) || !*replacement)
- replacement = nullptr;
- }
- if (replacement)
- {
- buffer->info[idx].codepoint = *replacement;
- if (has_glyph_classes)
- _hb_glyph_info_set_glyph_props (&buffer->info[idx],
- gdef.get_glyph_props (*replacement));
- ret = true;
- }
-
- if (entry.flags & SetMark)
- {
- mark_set = true;
- mark = buffer->idx;
- }
- }
-
- public:
- bool ret;
- private:
- hb_aat_apply_context_t *c;
- const OT::GDEF &gdef;
- bool mark_set;
- bool has_glyph_classes;
- unsigned int mark;
- const ContextualSubtable *table;
- const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false> &subs;
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- driver_context_t dc (this, c);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
- driver.drive (&dc, c);
-
- return_trace (dc.ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
-
- unsigned int num_entries = 0;
- if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false);
-
- if (!Types::extended)
- return_trace (substitutionTables.sanitize (c, this, 0));
-
- unsigned int num_lookups = 0;
-
- const Entry<EntryData> *entries = machine.get_entries ();
- for (unsigned int i = 0; i < num_entries; i++)
- {
- const EntryData &data = entries[i].data;
-
- if (data.markIndex != 0xFFFF)
- num_lookups = hb_max (num_lookups, 1u + data.markIndex);
- if (data.currentIndex != 0xFFFF)
- num_lookups = hb_max (num_lookups, 1u + data.currentIndex);
- }
-
- return_trace (substitutionTables.sanitize (c, this, num_lookups));
- }
-
- protected:
- StateTable<Types, EntryData>
- machine;
- NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false>, HBUINT>
- substitutionTables;
- public:
- DEFINE_SIZE_STATIC (20);
-};
-
-
-template <bool extended>
-struct LigatureEntry;
-
-template <>
-struct LigatureEntry<true>
-{
- enum Flags
- {
- SetComponent = 0x8000, /* Push this glyph onto the component stack for
- * eventual processing. */
- DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
- next iteration. */
- PerformAction = 0x2000, /* Use the ligActionIndex to process a ligature
- * group. */
- Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
- };
-
- struct EntryData
- {
- HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
- * for processing this group, if indicated
- * by the flags. */
- public:
- DEFINE_SIZE_STATIC (2);
- };
-
- static bool performAction (const Entry<EntryData> &entry)
- { return entry.flags & PerformAction; }
-
- static unsigned int ligActionIndex (const Entry<EntryData> &entry)
- { return entry.data.ligActionIndex; }
-};
-template <>
-struct LigatureEntry<false>
-{
- enum Flags
- {
- SetComponent = 0x8000, /* Push this glyph onto the component stack for
- * eventual processing. */
- DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
- next iteration. */
- Offset = 0x3FFF, /* Byte offset from beginning of subtable to the
- * ligature action list. This value must be a
- * multiple of 4. */
- };
-
- typedef void EntryData;
-
- static bool performAction (const Entry<EntryData> &entry)
- { return entry.flags & Offset; }
-
- static unsigned int ligActionIndex (const Entry<EntryData> &entry)
- { return entry.flags & Offset; }
-};
-
-
-template <typename Types>
-struct LigatureSubtable
-{
- typedef typename Types::HBUINT HBUINT;
-
- typedef LigatureEntry<Types::extended> LigatureEntryT;
- typedef typename LigatureEntryT::EntryData EntryData;
-
- struct driver_context_t
- {
- static constexpr bool in_place = false;
- enum
- {
- DontAdvance = LigatureEntryT::DontAdvance,
- };
- enum LigActionFlags
- {
- LigActionLast = 0x80000000, /* This is the last action in the list. This also
- * implies storage. */
- LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
- * in the ligature table in place of the marked
- * (i.e. currently-popped) glyph. */
- LigActionOffset = 0x3FFFFFFF, /* A 30-bit value which is sign-extended to 32-bits
- * and added to the glyph ID, resulting in an index
- * into the component table. */
- };
-
- driver_context_t (const LigatureSubtable *table_,
- hb_aat_apply_context_t *c_) :
- ret (false),
- c (c_),
- table (table_),
- ligAction (table+table->ligAction),
- component (table+table->component),
- ligature (table+table->ligature),
- match_length (0) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
- const Entry<EntryData> &entry)
- {
- return LigatureEntryT::performAction (entry);
- }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
-
- DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx);
- if (entry.flags & LigatureEntryT::SetComponent)
- {
- /* Never mark same index twice, in case DontAdvance was used... */
- if (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len)
- match_length--;
-
- match_positions[match_length++ % ARRAY_LENGTH (match_positions)] = buffer->out_len;
- DEBUG_MSG (APPLY, nullptr, "Set component at %u", buffer->out_len);
- }
-
- if (LigatureEntryT::performAction (entry))
- {
- DEBUG_MSG (APPLY, nullptr, "Perform action with %u", match_length);
- unsigned int end = buffer->out_len;
-
- if (unlikely (!match_length))
- return;
-
- if (buffer->idx >= buffer->len)
- return; /* TODO Work on previous instead? */
-
- unsigned int cursor = match_length;
-
- unsigned int action_idx = LigatureEntryT::ligActionIndex (entry);
- action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ);
- const HBUINT32 *actionData = &ligAction[action_idx];
-
- unsigned int ligature_idx = 0;
- unsigned int action;
- do
- {
- if (unlikely (!cursor))
- {
- /* Stack underflow. Clear the stack. */
- DEBUG_MSG (APPLY, nullptr, "Stack underflow");
- match_length = 0;
- break;
- }
-
- DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
- if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return;
-
- if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
- action = *actionData;
-
- uint32_t uoffset = action & LigActionOffset;
- if (uoffset & 0x20000000)
- uoffset |= 0xC0000000; /* Sign-extend. */
- int32_t offset = (int32_t) uoffset;
- unsigned int component_idx = buffer->cur().codepoint + offset;
- component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ);
- const HBUINT16 &componentData = component[component_idx];
- if (unlikely (!componentData.sanitize (&c->sanitizer))) break;
- ligature_idx += componentData;
-
- DEBUG_MSG (APPLY, nullptr, "Action store %d last %d",
- bool (action & LigActionStore),
- bool (action & LigActionLast));
- if (action & (LigActionStore | LigActionLast))
- {
- ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
- const HBGlyphID16 &ligatureData = ligature[ligature_idx];
- if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
- hb_codepoint_t lig = ligatureData;
-
- DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
- if (unlikely (!buffer->replace_glyph (lig))) return;
-
- unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u;
- /* Now go and delete all subsequent components. */
- while (match_length - 1u > cursor)
- {
- DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
- if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return;
- if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return;
- }
-
- if (unlikely (!buffer->move_to (lig_end))) return;
- buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len);
- }
-
- actionData++;
- }
- while (!(action & LigActionLast));
- if (unlikely (!buffer->move_to (end))) return;
- }
- }
-
- public:
- bool ret;
- private:
- hb_aat_apply_context_t *c;
- const LigatureSubtable *table;
- const UnsizedArrayOf<HBUINT32> &ligAction;
- const UnsizedArrayOf<HBUINT16> &component;
- const UnsizedArrayOf<HBGlyphID16> &ligature;
- unsigned int match_length;
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- driver_context_t dc (this, c);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
- driver.drive (&dc, c);
-
- return_trace (dc.ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* The rest of array sanitizations are done at run-time. */
- return_trace (c->check_struct (this) && machine.sanitize (c) &&
- ligAction && component && ligature);
- }
-
- protected:
- StateTable<Types, EntryData>
- machine;
- NNOffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT>
- ligAction; /* Offset to the ligature action table. */
- NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
- component; /* Offset to the component table. */
- NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
- ligature; /* Offset to the actual ligature lists. */
- public:
- DEFINE_SIZE_STATIC (28);
-};
-
-template <typename Types>
-struct NoncontextualSubtable
-{
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- const OT::GDEF &gdef (*c->gdef_table);
- bool has_glyph_classes = gdef.has_glyph_classes ();
-
- bool ret = false;
- unsigned int num_glyphs = c->face->get_num_glyphs ();
-
- hb_glyph_info_t *info = c->buffer->info;
- unsigned int count = c->buffer->len;
- // If there's only one range, we already checked the flag.
- auto *last_range = c->range_flags && (c->range_flags->length > 1) ? &(*c->range_flags)[0] : nullptr;
- for (unsigned int i = 0; i < count; i++)
- {
- /* This block copied from StateTableDriver::drive. Keep in sync. */
- if (last_range)
- {
- auto *range = last_range;
- {
- unsigned cluster = info[i].cluster;
- while (cluster < range->cluster_first)
- range--;
- while (cluster > range->cluster_last)
- range++;
-
- last_range = range;
- }
- if (!(range->flags & c->subtable_flags))
- continue;
- }
-
- const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
- if (replacement)
- {
- info[i].codepoint = *replacement;
- if (has_glyph_classes)
- _hb_glyph_info_set_glyph_props (&info[i],
- gdef.get_glyph_props (*replacement));
- ret = true;
- }
- }
-
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (substitute.sanitize (c));
- }
-
- protected:
- Lookup<HBGlyphID16> substitute;
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-template <typename Types>
-struct InsertionSubtable
-{
- typedef typename Types::HBUINT HBUINT;
-
- struct EntryData
- {
- HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table.
- * The number of glyphs to be inserted is contained
- * in the currentInsertCount field in the flags.
- * A value of 0xFFFF indicates no insertion is to
- * be done. */
- HBUINT16 markedInsertIndex; /* Zero-based index into the insertion glyph table.
- * The number of glyphs to be inserted is contained
- * in the markedInsertCount field in the flags.
- * A value of 0xFFFF indicates no insertion is to
- * be done. */
- public:
- DEFINE_SIZE_STATIC (4);
- };
-
- struct driver_context_t
- {
- static constexpr bool in_place = false;
- enum Flags
- {
- SetMark = 0x8000, /* If set, mark the current glyph. */
- DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
- * going to the new state. This does not mean
- * that the glyph pointed to is the same one as
- * before. If you've made insertions immediately
- * downstream of the current glyph, the next glyph
- * processed would in fact be the first one
- * inserted. */
- CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero,
- * then the specified glyph list will be inserted
- * as a kashida-like insertion, either before or
- * after the current glyph (depending on the state
- * of the currentInsertBefore flag). If clear, and
- * the currentInsertList is nonzero, then the
- * specified glyph list will be inserted as a
- * split-vowel-like insertion, either before or
- * after the current glyph (depending on the state
- * of the currentInsertBefore flag). */
- MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero,
- * then the specified glyph list will be inserted
- * as a kashida-like insertion, either before or
- * after the marked glyph (depending on the state
- * of the markedInsertBefore flag). If clear, and
- * the markedInsertList is nonzero, then the
- * specified glyph list will be inserted as a
- * split-vowel-like insertion, either before or
- * after the marked glyph (depending on the state
- * of the markedInsertBefore flag). */
- CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made
- * to the left of the current glyph. If clear,
- * they're made to the right of the current glyph. */
- MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be
- * made to the left of the marked glyph. If clear,
- * they're made to the right of the marked glyph. */
- CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the
- * number of glyphs to insert at the current
- * position. Since zero means no insertions, the
- * largest number of insertions at any given
- * current location is 31 glyphs. */
- MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the
- * number of glyphs to insert at the marked
- * position. Since zero means no insertions, the
- * largest number of insertions at any given
- * marked location is 31 glyphs. */
- };
-
- driver_context_t (const InsertionSubtable *table,
- hb_aat_apply_context_t *c_) :
- ret (false),
- c (c_),
- mark (0),
- insertionAction (table+table->insertionAction) {}
-
- bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
- const Entry<EntryData> &entry)
- {
- return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) &&
- (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF);
- }
- void transition (StateTableDriver<Types, EntryData> *driver,
- const Entry<EntryData> &entry)
- {
- hb_buffer_t *buffer = driver->buffer;
- unsigned int flags = entry.flags;
-
- unsigned mark_loc = buffer->out_len;
-
- if (entry.data.markedInsertIndex != 0xFFFF)
- {
- unsigned int count = (flags & MarkedInsertCount);
- if (unlikely ((buffer->max_ops -= count) <= 0)) return;
- unsigned int start = entry.data.markedInsertIndex;
- const HBGlyphID16 *glyphs = &insertionAction[start];
- if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
-
- bool before = flags & MarkedInsertBefore;
-
- unsigned int end = buffer->out_len;
- if (unlikely (!buffer->move_to (mark))) return;
-
- if (buffer->idx < buffer->len && !before)
- if (unlikely (!buffer->copy_glyph ())) return;
- /* TODO We ignore KashidaLike setting. */
- if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
- if (buffer->idx < buffer->len && !before)
- buffer->skip_glyph ();
-
- if (unlikely (!buffer->move_to (end + count))) return;
-
- buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
- }
-
- if (flags & SetMark)
- mark = mark_loc;
-
- if (entry.data.currentInsertIndex != 0xFFFF)
- {
- unsigned int count = (flags & CurrentInsertCount) >> 5;
- if (unlikely ((buffer->max_ops -= count) <= 0)) return;
- unsigned int start = entry.data.currentInsertIndex;
- const HBGlyphID16 *glyphs = &insertionAction[start];
- if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
-
- bool before = flags & CurrentInsertBefore;
-
- unsigned int end = buffer->out_len;
-
- if (buffer->idx < buffer->len && !before)
- if (unlikely (!buffer->copy_glyph ())) return;
- /* TODO We ignore KashidaLike setting. */
- if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
- if (buffer->idx < buffer->len && !before)
- buffer->skip_glyph ();
-
- /* Humm. Not sure where to move to. There's this wording under
- * DontAdvance flag:
- *
- * "If set, don't update the glyph index before going to the new state.
- * This does not mean that the glyph pointed to is the same one as
- * before. If you've made insertions immediately downstream of the
- * current glyph, the next glyph processed would in fact be the first
- * one inserted."
- *
- * This suggests that if DontAdvance is NOT set, we should move to
- * end+count. If it *was*, then move to end, such that newly inserted
- * glyphs are now visible.
- *
- * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
- */
- if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return;
- }
- }
-
- public:
- bool ret;
- private:
- hb_aat_apply_context_t *c;
- unsigned int mark;
- const UnsizedArrayOf<HBGlyphID16> &insertionAction;
- };
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- driver_context_t dc (this, c);
-
- StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
- driver.drive (&dc, c);
-
- return_trace (dc.ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* The rest of array sanitizations are done at run-time. */
- return_trace (c->check_struct (this) && machine.sanitize (c) &&
- insertionAction);
- }
-
- protected:
- StateTable<Types, EntryData>
- machine;
- NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
- insertionAction; /* Byte offset from stateHeader to the start of
- * the insertion glyph table. */
- public:
- DEFINE_SIZE_STATIC (20);
-};
-
-
-struct Feature
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT16 featureType; /* The type of feature. */
- HBUINT16 featureSetting; /* The feature's setting (aka selector). */
- HBUINT32 enableFlags; /* Flags for the settings that this feature
- * and setting enables. */
- HBUINT32 disableFlags; /* Complement of flags for the settings that this
- * feature and setting disable. */
-
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-template <typename Types>
-struct ChainSubtable
-{
- typedef typename Types::HBUINT HBUINT;
-
- template <typename T>
- friend struct Chain;
-
- unsigned int get_size () const { return length; }
- unsigned int get_type () const { return coverage & 0xFF; }
- unsigned int get_coverage () const { return coverage >> (sizeof (HBUINT) * 8 - 8); }
-
- enum Coverage
- {
- Vertical = 0x80, /* If set, this subtable will only be applied
- * to vertical text. If clear, this subtable
- * will only be applied to horizontal text. */
- Backwards = 0x40, /* If set, this subtable will process glyphs
- * in descending order. If clear, it will
- * process the glyphs in ascending order. */
- AllDirections = 0x20, /* If set, this subtable will be applied to
- * both horizontal and vertical text (i.e.
- * the state of bit 0x80000000 is ignored). */
- Logical = 0x10, /* If set, this subtable will process glyphs
- * in logical order (or reverse logical order,
- * depending on the value of bit 0x80000000). */
- };
- enum Type
- {
- Rearrangement = 0,
- Contextual = 1,
- Ligature = 2,
- Noncontextual = 4,
- Insertion = 5
- };
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- unsigned int subtable_type = get_type ();
- TRACE_DISPATCH (this, subtable_type);
- switch (subtable_type) {
- case Rearrangement: return_trace (c->dispatch (u.rearrangement, std::forward<Ts> (ds)...));
- case Contextual: return_trace (c->dispatch (u.contextual, std::forward<Ts> (ds)...));
- case Ligature: return_trace (c->dispatch (u.ligature, std::forward<Ts> (ds)...));
- case Noncontextual: return_trace (c->dispatch (u.noncontextual, std::forward<Ts> (ds)...));
- case Insertion: return_trace (c->dispatch (u.insertion, std::forward<Ts> (ds)...));
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- hb_sanitize_with_object_t with (&c->sanitizer, this);
- return_trace (dispatch (c));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!length.sanitize (c) ||
- length <= min_size ||
- !c->check_range (this, length))
- return_trace (false);
-
- hb_sanitize_with_object_t with (c, this);
- return_trace (dispatch (c));
- }
-
- protected:
- HBUINT length; /* Total subtable length, including this header. */
- HBUINT coverage; /* Coverage flags and subtable type. */
- HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */
- union {
- RearrangementSubtable<Types> rearrangement;
- ContextualSubtable<Types> contextual;
- LigatureSubtable<Types> ligature;
- NoncontextualSubtable<Types> noncontextual;
- InsertionSubtable<Types> insertion;
- } u;
- public:
- DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4);
-};
-
-template <typename Types>
-struct Chain
-{
- typedef typename Types::HBUINT HBUINT;
-
- hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const
- {
- hb_mask_t flags = defaultFlags;
- {
- unsigned int count = featureCount;
- for (unsigned i = 0; i < count; i++)
- {
- const Feature &feature = featureZ[i];
- hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType;
- hb_aat_layout_feature_selector_t setting = (hb_aat_layout_feature_selector_t) (unsigned int) feature.featureSetting;
- retry:
- // Check whether this type/setting pair was requested in the map, and if so, apply its flags.
- // (The search here only looks at the type and setting fields of feature_info_t.)
- hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 };
- if (map->current_features.bsearch (info))
- {
- flags &= feature.disableFlags;
- flags |= feature.enableFlags;
- }
- else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS)
- {
- /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */
- type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE;
- setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS;
- goto retry;
- }
-#ifndef HB_NO_AAT
- else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting &&
- /* TODO: Rudimentary language matching. */
- hb_language_matches (map->face->table.ltag->get_language (setting - 1), map->props.language))
- {
- flags &= feature.disableFlags;
- flags |= feature.enableFlags;
- }
-#endif
- }
- }
- return flags;
- }
-
- void apply (hb_aat_apply_context_t *c) const
- {
- const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
- unsigned int count = subtableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- bool reverse;
-
- if (hb_none (hb_iter (c->range_flags) |
- hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); })))
- goto skip;
- c->subtable_flags = subtable->subFeatureFlags;
-
- if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
- HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
- bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical))
- goto skip;
-
- /* Buffer contents is always in logical direction. Determine if
- * we need to reverse before applying this subtable. We reverse
- * back after if we did reverse indeed.
- *
- * Quoting the spac:
- * """
- * Bits 28 and 30 of the coverage field control the order in which
- * glyphs are processed when the subtable is run by the layout engine.
- * Bit 28 is used to indicate if the glyph processing direction is
- * the same as logical order or layout order. Bit 30 is used to
- * indicate whether glyphs are processed forwards or backwards within
- * that order.
-
- Bit 30 Bit 28 Interpretation for Horizontal Text
- 0 0 The subtable is processed in layout order
- (the same order as the glyphs, which is
- always left-to-right).
- 1 0 The subtable is processed in reverse layout order
- (the order opposite that of the glyphs, which is
- always right-to-left).
- 0 1 The subtable is processed in logical order
- (the same order as the characters, which may be
- left-to-right or right-to-left).
- 1 1 The subtable is processed in reverse logical order
- (the order opposite that of the characters, which
- may be right-to-left or left-to-right).
- */
- reverse = subtable->get_coverage () & ChainSubtable<Types>::Logical ?
- bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) :
- bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) !=
- HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
-
- if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index))
- goto skip;
-
- if (reverse)
- c->buffer->reverse ();
-
- subtable->apply (c);
-
- if (reverse)
- c->buffer->reverse ();
-
- (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index);
-
- if (unlikely (!c->buffer->successful)) return;
-
- skip:
- subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
- c->set_lookup_index (c->lookup_index + 1);
- }
- }
-
- unsigned int get_size () const { return length; }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const
- {
- TRACE_SANITIZE (this);
- if (!length.sanitize (c) ||
- length < min_size ||
- !c->check_range (this, length))
- return_trace (false);
-
- if (!c->check_array (featureZ.arrayZ, featureCount))
- return_trace (false);
-
- const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
- unsigned int count = subtableCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if (!subtable->sanitize (c))
- return_trace (false);
- subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
- }
-
- return_trace (true);
- }
-
- protected:
- HBUINT32 defaultFlags; /* The default specification for subtables. */
- HBUINT32 length; /* Total byte count, including this header. */
- HBUINT featureCount; /* Number of feature subtable entries. */
- HBUINT subtableCount; /* The number of subtables in the chain. */
-
- UnsizedArrayOf<Feature> featureZ; /* Features. */
-/*ChainSubtable firstSubtable;*//* Subtables. */
-/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
-
- public:
- DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT));
-};
-
-
-/*
- * The 'mort'/'morx' Table
- */
-
-template <typename Types, hb_tag_t TAG>
-struct mortmorx
-{
- static constexpr hb_tag_t tableTag = TAG;
-
- bool has_data () const { return version != 0; }
-
- void compile_flags (const hb_aat_map_builder_t *mapper,
- hb_aat_map_t *map) const
- {
- const Chain<Types> *chain = &firstChain;
- unsigned int count = chainCount;
- if (unlikely (!map->chain_flags.resize (count)))
- return;
- for (unsigned int i = 0; i < count; i++)
- {
- map->chain_flags[i].push (hb_aat_map_t::range_flags_t {chain->compile_flags (mapper),
- mapper->range_first,
- mapper->range_last});
- chain = &StructAfter<Chain<Types>> (*chain);
- }
- }
-
- void apply (hb_aat_apply_context_t *c,
- const hb_aat_map_t &map) const
- {
- if (unlikely (!c->buffer->successful)) return;
-
- c->buffer->unsafe_to_concat ();
-
- c->set_lookup_index (0);
- const Chain<Types> *chain = &firstChain;
- unsigned int count = chainCount;
- for (unsigned int i = 0; i < count; i++)
- {
- c->range_flags = &map.chain_flags[i];
- chain->apply (c);
- if (unlikely (!c->buffer->successful)) return;
- chain = &StructAfter<Chain<Types>> (*chain);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!version.sanitize (c) || !version || !chainCount.sanitize (c))
- return_trace (false);
-
- const Chain<Types> *chain = &firstChain;
- unsigned int count = chainCount;
- for (unsigned int i = 0; i < count; i++)
- {
- if (!chain->sanitize (c, version))
- return_trace (false);
- chain = &StructAfter<Chain<Types>> (*chain);
- }
-
- return_trace (true);
- }
-
- protected:
- HBUINT16 version; /* Version number of the glyph metamorphosis table.
- * 1, 2, or 3. */
- HBUINT16 unused; /* Set to 0. */
- HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
- * table. */
- Chain<Types> firstChain; /* Chains. */
-
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-struct morx : mortmorx<ExtendedTypes, HB_AAT_TAG_morx> {};
-struct mort : mortmorx<ObsoleteTypes, HB_AAT_TAG_mort> {};
-
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_MORX_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh
deleted file mode 100644
index 51b650fc33c..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-opbd-table.hh
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LAYOUT_OPBD_TABLE_HH
-#define HB_AAT_LAYOUT_OPBD_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-#include "hb-open-type.hh"
-
-/*
- * opbd -- Optical Bounds
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
- */
-#define HB_AAT_TAG_opbd HB_TAG('o','p','b','d')
-
-
-namespace AAT {
-
-struct OpticalBounds
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- FWORD leftSide;
- FWORD topSide;
- FWORD rightSide;
- FWORD bottomSide;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct opbdFormat0
-{
- bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
- hb_glyph_extents_t *extents, const void *base) const
- {
- const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
- if (!bounds_offset) return false;
- const OpticalBounds &bounds = base+*bounds_offset;
-
- if (extents)
- *extents = {
- font->em_scale_x (bounds.leftSide),
- font->em_scale_y (bounds.topSide),
- font->em_scale_x (bounds.rightSide),
- font->em_scale_y (bounds.bottomSide)
- };
- return true;
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
- }
-
- protected:
- Lookup<Offset16To<OpticalBounds>>
- lookupTable; /* Lookup table associating glyphs with the four
- * int16 values for the left-side, top-side,
- * right-side, and bottom-side optical bounds. */
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct opbdFormat1
-{
- bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
- hb_glyph_extents_t *extents, const void *base) const
- {
- const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
- if (!bounds_offset) return false;
- const OpticalBounds &bounds = base+*bounds_offset;
-
- hb_position_t left = 0, top = 0, right = 0, bottom = 0, ignore;
- if (font->get_glyph_contour_point (glyph_id, bounds.leftSide, &left, &ignore) ||
- font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, &top) ||
- font->get_glyph_contour_point (glyph_id, bounds.rightSide, &right, &ignore) ||
- font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, &bottom))
- {
- if (extents)
- *extents = {left, top, right, bottom};
- return true;
- }
- return false;
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
- }
-
- protected:
- Lookup<Offset16To<OpticalBounds>>
- lookupTable; /* Lookup table associating glyphs with the four
- * int16 values for the left-side, top-side,
- * right-side, and bottom-side optical bounds. */
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct opbd
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd;
-
- bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
- hb_glyph_extents_t *extents) const
- {
- switch (format)
- {
- case 0: return u.format0.get_bounds (font, glyph_id, extents, this);
- case 1: return u.format1.get_bounds (font, glyph_id, extents, this);
- default:return false;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this) || version.major != 1))
- return_trace (false);
-
- switch (format)
- {
- case 0: return_trace (u.format0.sanitize (c, this));
- case 1: return_trace (u.format1.sanitize (c, this));
- default:return_trace (true);
- }
- }
-
- protected:
- FixedVersion<>version; /* Version number of the optical bounds
- * table (0x00010000 for the current version). */
- HBUINT16 format; /* Format of the optical bounds table.
- * Format 0 indicates distance and Format 1 indicates
- * control point. */
- union {
- opbdFormat0 format0;
- opbdFormat1 format1;
- } u;
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_OPBD_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh
deleted file mode 100644
index 2ba9355b06b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- * Copyright © 2018 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_AAT_LAYOUT_TRAK_TABLE_HH
-#define HB_AAT_LAYOUT_TRAK_TABLE_HH
-
-#include "hb-aat-layout-common.hh"
-#include "hb-ot-layout.hh"
-#include "hb-open-type.hh"
-
-/*
- * trak -- Tracking
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
- */
-#define HB_AAT_TAG_trak HB_TAG('t','r','a','k')
-
-
-namespace AAT {
-
-
-struct TrackTableEntry
-{
- friend struct TrackData;
-
- float get_track_value () const { return track.to_float (); }
-
- int get_value (const void *base, unsigned int index,
- unsigned int table_size) const
- { return (base+valuesZ).as_array (table_size)[index]; }
-
- public:
- bool sanitize (hb_sanitize_context_t *c, const void *base,
- unsigned int table_size) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (valuesZ.sanitize (c, base, table_size))));
- }
-
- protected:
- F16DOT16 track; /* Track value for this record. */
- NameID trackNameID; /* The 'name' table index for this track.
- * (a short word or phrase like "loose"
- * or "very tight") */
- NNOffset16To<UnsizedArrayOf<FWORD>>
- valuesZ; /* Offset from start of tracking table to
- * per-size tracking values for this track. */
-
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct TrackData
-{
- float interpolate_at (unsigned int idx,
- float target_size,
- const TrackTableEntry &trackTableEntry,
- const void *base) const
- {
- unsigned int sizes = nSizes;
- hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
-
- float s0 = size_table[idx].to_float ();
- float s1 = size_table[idx + 1].to_float ();
- float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0);
- return t * trackTableEntry.get_value (base, idx + 1, sizes) +
- (1.f - t) * trackTableEntry.get_value (base, idx, sizes);
- }
-
- int get_tracking (const void *base, float ptem) const
- {
- /*
- * Choose track.
- */
- const TrackTableEntry *trackTableEntry = nullptr;
- unsigned int count = nTracks;
- for (unsigned int i = 0; i < count; i++)
- {
- /* Note: Seems like the track entries are sorted by values. But the
- * spec doesn't explicitly say that. It just mentions it in the example. */
-
- /* For now we only seek for track entries with zero tracking value */
-
- if (trackTable[i].get_track_value () == 0.f)
- {
- trackTableEntry = &trackTable[i];
- break;
- }
- }
- if (!trackTableEntry) return 0.;
-
- /*
- * Choose size.
- */
- unsigned int sizes = nSizes;
- if (!sizes) return 0.;
- if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
-
- hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
- unsigned int size_index;
- for (size_index = 0; size_index < sizes - 1; size_index++)
- if (size_table[size_index].to_float () >= ptem)
- break;
-
- return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem,
- *trackTableEntry, base));
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- sizeTable.sanitize (c, base, nSizes) &&
- trackTable.sanitize (c, nTracks, base, nSizes)));
- }
-
- protected:
- HBUINT16 nTracks; /* Number of separate tracks included in this table. */
- HBUINT16 nSizes; /* Number of point sizes included in this table. */
- NNOffset32To<UnsizedArrayOf<F16DOT16>>
- sizeTable; /* Offset from start of the tracking table to
- * Array[nSizes] of size values.. */
- UnsizedArrayOf<TrackTableEntry>
- trackTable; /* Array[nTracks] of TrackTableEntry records. */
-
- public:
- DEFINE_SIZE_ARRAY (8, trackTable);
-};
-
-struct trak
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_trak;
-
- bool has_data () const { return version.to_int (); }
-
- bool apply (hb_aat_apply_context_t *c) const
- {
- TRACE_APPLY (this);
-
- hb_mask_t trak_mask = c->plan->trak_mask;
-
- const float ptem = c->font->ptem;
- if (unlikely (ptem <= 0.f))
- return_trace (false);
-
- hb_buffer_t *buffer = c->buffer;
- if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- {
- const TrackData &trackData = this+horizData;
- int tracking = trackData.get_tracking (this, ptem);
- hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2);
- hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
- foreach_grapheme (buffer, start, end)
- {
- if (!(buffer->info[start].mask & trak_mask)) continue;
- buffer->pos[start].x_advance += advance_to_add;
- buffer->pos[start].x_offset += offset_to_add;
- }
- }
- else
- {
- const TrackData &trackData = this+vertData;
- int tracking = trackData.get_tracking (this, ptem);
- hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2);
- hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
- foreach_grapheme (buffer, start, end)
- {
- if (!(buffer->info[start].mask & trak_mask)) continue;
- buffer->pos[start].y_advance += advance_to_add;
- buffer->pos[start].y_offset += offset_to_add;
- }
- }
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
-
- return_trace (likely (c->check_struct (this) &&
- version.major == 1 &&
- horizData.sanitize (c, this, this) &&
- vertData.sanitize (c, this, this)));
- }
-
- protected:
- FixedVersion<>version; /* Version of the tracking table
- * (0x00010000u for version 1.0). */
- HBUINT16 format; /* Format of the tracking table (set to 0). */
- Offset16To<TrackData>
- horizData; /* Offset from start of tracking table to TrackData
- * for horizontal text (or 0 if none). */
- Offset16To<TrackData>
- vertData; /* Offset from start of tracking table to TrackData
- * for vertical text (or 0 if none). */
- HBUINT16 reserved; /* Reserved. Set to 0. */
-
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LAYOUT_TRAK_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc
deleted file mode 100644
index c9147ff73b1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright © 2017 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.hh"
-
-#include "hb-aat-layout.hh"
-#include "hb-aat-layout-ankr-table.hh"
-#include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-aat-layout-feat-table.hh"
-#include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-aat-layout-kerx-table.hh"
-#include "hb-aat-layout-morx-table.hh"
-#include "hb-aat-layout-trak-table.hh"
-#include "hb-aat-ltag-table.hh"
-
-
-/*
- * hb_aat_apply_context_t
- */
-
-/* Note: This context is used for kerning, even without AAT, hence the condition. */
-#if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)
-
-AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
- hb_font_t *font_,
- hb_buffer_t *buffer_,
- hb_blob_t *blob) :
- plan (plan_),
- font (font_),
- face (font->face),
- buffer (buffer_),
- sanitizer (),
- ankr_table (&Null (AAT::ankr)),
- gdef_table (face->table.GDEF->table),
- lookup_index (0)
-{
- sanitizer.init (blob);
- sanitizer.set_num_glyphs (face->get_num_glyphs ());
- sanitizer.start_processing ();
- sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
-}
-
-AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
-{ sanitizer.end_processing (); }
-
-void
-AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
-{ ankr_table = ankr_table_; }
-
-#endif
-
-
-/**
- * SECTION:hb-aat-layout
- * @title: hb-aat-layout
- * @short_description: Apple Advanced Typography Layout
- * @include: hb-aat.h
- *
- * Functions for querying AAT Layout features in the font face.
- *
- * HarfBuzz supports all of the AAT tables used to implement shaping. Other
- * AAT tables and their associated features are not supported.
- **/
-
-
-#if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
-
-/* Mapping from OpenType feature tags to AAT feature names and selectors.
- *
- * Table data courtesy of Apple. Converted from mnemonics to integers
- * when moving to this file. */
-static const hb_aat_feature_mapping_t feature_mappings[] =
-{
- {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
- {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE},
- {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE},
- {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF},
- {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF},
- {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF},
- {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF},
- {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF},
- {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF},
- {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS},
- {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('h','i','s','t'), (hb_aat_layout_feature_type_t) 40, (hb_aat_layout_feature_selector_t) 0, (hb_aat_layout_feature_selector_t) 1},
- {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF},
- {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF},
- {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION},
- {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF},
- {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF},
- {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2},
- {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF},
- {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2},
- {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
- {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
- {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4},
- {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('r','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF},
- {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF},
- {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
- {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
- {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF},
- {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF},
- {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF},
- {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF},
- {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF},
- {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF},
- {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF},
- {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF},
- {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF},
- {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF},
- {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF},
- {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF},
- {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF},
- {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF},
- {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF},
- {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF},
- {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF},
- {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF},
- {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF},
- {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF},
- {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
- {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
- {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF},
- {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS},
- {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_selector_t) 4},
- {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_selector_t) 16},
- {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_selector_t) 14, (hb_aat_layout_feature_selector_t) 15},
- {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
- {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF},
- {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
- {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF},
- {HB_TAG ('v','r','t','r'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, (hb_aat_layout_feature_selector_t) 2, (hb_aat_layout_feature_selector_t) 3},
- {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
-};
-
-/**
- * hb_aat_layout_find_feature_mapping:
- * @tag: The requested #hb_tag_t feature tag
- *
- * Fetches the AAT feature-and-selector combination that corresponds
- * to a given OpenType feature tag.
- *
- * Return value: the AAT features and selectors corresponding to the
- * OpenType feature tag queried
- *
- **/
-const hb_aat_feature_mapping_t *
-hb_aat_layout_find_feature_mapping (hb_tag_t tag)
-{
- return hb_sorted_array (feature_mappings).bsearch (tag);
-}
-#endif
-
-
-#ifndef HB_NO_AAT
-
-/*
- * mort/morx/kerx/trak
- */
-
-
-void
-hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
- hb_aat_map_t *map)
-{
- const AAT::morx& morx = *mapper->face->table.morx;
- if (morx.has_data ())
- {
- morx.compile_flags (mapper, map);
- return;
- }
-
- const AAT::mort& mort = *mapper->face->table.mort;
- if (mort.has_data ())
- {
- mort.compile_flags (mapper, map);
- return;
- }
-}
-
-
-/**
- * hb_aat_layout_has_substitution:
- * @face: #hb_face_t to work upon
- *
- * Tests whether the specified face includes any substitutions in the
- * `morx` or `mort` tables.
- *
- * <note>Note: does not examine the `GSUB` table.</note>
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.3.0
- */
-hb_bool_t
-hb_aat_layout_has_substitution (hb_face_t *face)
-{
- return face->table.morx->has_data () ||
- face->table.mort->has_data ();
-}
-
-void
-hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned num_features)
-{
- hb_aat_map_builder_t builder (font->face, plan->props);
- for (unsigned i = 0; i < num_features; i++)
- builder.add_feature (features[i]);
- hb_aat_map_t map;
- builder.compile (map);
-
- hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
- const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
- if (morx.has_data ())
- {
- AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob);
- if (!buffer->message (font, "start table morx")) return;
- morx.apply (&c, map);
- (void) buffer->message (font, "end table morx");
- return;
- }
-
- hb_blob_t *mort_blob = font->face->table.mort.get_blob ();
- const AAT::mort& mort = *mort_blob->as<AAT::mort> ();
- if (mort.has_data ())
- {
- AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob);
- if (!buffer->message (font, "start table mort")) return;
- mort.apply (&c, map);
- (void) buffer->message (font, "end table mort");
- return;
- }
-}
-
-void
-hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
-{
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- hb_glyph_position_t *pos = buffer->pos;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH))
- pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
-}
-
-static bool
-is_deleted_glyph (const hb_glyph_info_t *info)
-{
- return info->codepoint == AAT::DELETED_GLYPH;
-}
-
-void
-hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
-{
- buffer->delete_glyphs_inplace (is_deleted_glyph);
-}
-
-/**
- * hb_aat_layout_has_positioning:
- * @face: #hb_face_t to work upon
- *
- * Tests whether the specified face includes any positioning information
- * in the `kerx` table.
- *
- * <note>Note: does not examine the `GPOS` table.</note>
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.3.0
- */
-hb_bool_t
-hb_aat_layout_has_positioning (hb_face_t *face)
-{
- return face->table.kerx->has_data ();
-}
-
-void
-hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
- const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
-
- AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob);
- if (!buffer->message (font, "start table kerx")) return;
- c.set_ankr_table (font->face->table.ankr.get ());
- kerx.apply (&c);
- (void) buffer->message (font, "end table kerx");
-}
-
-
-/**
- * hb_aat_layout_has_tracking:
- * @face:: #hb_face_t to work upon
- *
- * Tests whether the specified face includes any tracking information
- * in the `trak` table.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.3.0
- */
-hb_bool_t
-hb_aat_layout_has_tracking (hb_face_t *face)
-{
- return face->table.trak->has_data ();
-}
-
-void
-hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- const AAT::trak& trak = *font->face->table.trak;
-
- AAT::hb_aat_apply_context_t c (plan, font, buffer);
- trak.apply (&c);
-}
-
-/**
- * hb_aat_layout_get_feature_types:
- * @face: #hb_face_t to work upon
- * @start_offset: offset of the first feature type to retrieve
- * @feature_count: (inout) (optional): Input = the maximum number of feature types to return;
- * Output = the actual number of feature types returned (may be zero)
- * @features: (out caller-allocates) (array length=feature_count): Array of feature types found
- *
- * Fetches a list of the AAT feature types included in the specified face.
- *
- * Return value: Number of all available feature types.
- *
- * Since: 2.2.0
- */
-unsigned int
-hb_aat_layout_get_feature_types (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *feature_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */)
-{
- return face->table.feat->get_feature_types (start_offset, feature_count, features);
-}
-
-/**
- * hb_aat_layout_feature_type_get_name_id:
- * @face: #hb_face_t to work upon
- * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
- *
- * Fetches the name identifier of the specified feature type in the face's `name` table.
- *
- * Return value: Name identifier of the requested feature type
- *
- * Since: 2.2.0
- */
-hb_ot_name_id_t
-hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
- hb_aat_layout_feature_type_t feature_type)
-{
- return face->table.feat->get_feature_name_id (feature_type);
-}
-
-/**
- * hb_aat_layout_feature_type_get_selector_infos:
- * @face: #hb_face_t to work upon
- * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
- * @start_offset: offset of the first feature type to retrieve
- * @selector_count: (inout) (optional): Input = the maximum number of selectors to return;
- * Output = the actual number of selectors returned (may be zero)
- * @selectors: (out caller-allocates) (array length=selector_count) (optional):
- * A buffer pointer. The selectors available for the feature type queries.
- * @default_index: (out) (optional): The index of the feature's default selector, if any
- *
- * Fetches a list of the selectors available for the specified feature in the given face.
- *
- * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then
- * the feature type is non-exclusive. Otherwise, @default_index is the index of
- * the selector that is selected by default.
- *
- * Return value: Number of all available feature selectors
- *
- * Since: 2.2.0
- */
-unsigned int
-hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face,
- hb_aat_layout_feature_type_t feature_type,
- unsigned int start_offset,
- unsigned int *selector_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
- unsigned int *default_index /* OUT. May be NULL. */)
-{
- return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h
deleted file mode 100644
index 9af27400886..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.h
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#if !defined(HB_AAT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-aat.h> instead."
-#endif
-
-#ifndef HB_AAT_LAYOUT_H
-#define HB_AAT_LAYOUT_H
-
-#include "hb.h"
-
-#include "hb-ot.h"
-
-HB_BEGIN_DECLS
-
-/**
- * hb_aat_layout_feature_type_t:
- * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type
- * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING: [Number Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type6)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE: [Smart Swash](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type8)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE: [Diacritics](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type9)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION: [Vertical Position](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type10)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS: [Fractions](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type11)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: [Overlapping Characters](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type13)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: [Typographic Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type14)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS: [Mathematical Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type15)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE: [Ornament Sets](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type16)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES: [Character Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type17)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: [Design Complexity](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type18)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS: [Style Options](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type19)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE: [Character Shape](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type20)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE: [Number Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type21)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING: [Text Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type22)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION: [Transliteration](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type23)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE: [Annotation](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type24)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE: [Kana Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type25)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: [Ideographic Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type26)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: [Unicode Decomposition](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type27)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA: [Ruby Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type28)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: [CJK Symbol Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type29)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: [Ideographic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type30)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: [CJK Vertical Roman Placement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type31)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN: [Italic CJK Roman](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type32)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: [Case Sensitive Layout](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type33)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA: [Alternate Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type34)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES: [Stylistic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type35)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: [Contextual Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type36)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE: [Lower Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type37)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE: [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE: [Language Tag](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type39)
- * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: [CJK Roman Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type103)
- *
- * The possible feature types defined for AAT shaping, from Apple [Font Feature Registry](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html).
- *
- * Since: 2.2.0
- */
-typedef enum
-{
- HB_AAT_LAYOUT_FEATURE_TYPE_INVALID = 0xFFFF,
-
- HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0,
- HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1,
- HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2,
- HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3,
- HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4,
- HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5,
- HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6,
- HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8,
- HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9,
- HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10,
- HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11,
- HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13,
- HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14,
- HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15,
- HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16,
- HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17,
- HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18,
- HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19,
- HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20,
- HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21,
- HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22,
- HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23,
- HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24,
- HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25,
- HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26,
- HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27,
- HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28,
- HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29,
- HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30,
- HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31,
- HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32,
- HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33,
- HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34,
- HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35,
- HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36,
- HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37,
- HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38,
- HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
- HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
-
- /*< private >*/
- _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_aat_layout_feature_type_t;
-
-/**
- * hb_aat_layout_feature_selector_t:
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID: Initial, unset feature selector
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS: Deprecated
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
- * @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
- *
- * The selectors defined for specifying AAT feature settings.
- *
- * Since: 2.2.0
- */
-typedef enum
-{
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID = 0xFFFF,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON = 10,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON = 12,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF = 13,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON = 16,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF = 17,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON = 20,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF = 21,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS = 1, /* deprecated */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS = 3, /* deprecated */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS = 4, /* deprecated */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS = 3,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF = 9,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS = 4,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON = 10,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF = 11,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS = 6,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES = 0,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1 = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2 = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3 = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4 = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5 = 4,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS = 5,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS = 10,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS = 11,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS = 12,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS = 13,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT = 6,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF = 3,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON = 6,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON = 12,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON = 18,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON = 20,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF = 3,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS = 2,
-
- /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */
- HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
- HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
-
- /*< private >*/
- _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_aat_layout_feature_selector_t;
-
-HB_EXTERN unsigned int
-hb_aat_layout_get_feature_types (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *feature_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */);
-
-HB_EXTERN hb_ot_name_id_t
-hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
- hb_aat_layout_feature_type_t feature_type);
-
-/**
- * hb_aat_layout_feature_selector_info_t:
- * @name_id: The selector's name identifier
- * @enable: The value to turn the selector on
- * @disable: The value to turn the selector off
- *
- * Structure representing a setting for an #hb_aat_layout_feature_type_t.
- */
-typedef struct hb_aat_layout_feature_selector_info_t {
- hb_ot_name_id_t name_id;
- hb_aat_layout_feature_selector_t enable;
- hb_aat_layout_feature_selector_t disable;
- /*< private >*/
- unsigned int reserved;
-} hb_aat_layout_feature_selector_info_t;
-
-/**
- * HB_AAT_LAYOUT_NO_SELECTOR_INDEX
- *
- * Used when getting or setting AAT feature selectors. Indicates that
- * there is no selector index corresponding to the selector of interest.
- *
- */
-#define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu
-
-HB_EXTERN unsigned int
-hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face,
- hb_aat_layout_feature_type_t feature_type,
- unsigned int start_offset,
- unsigned int *selector_count, /* IN/OUT. May be NULL. */
- hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
- unsigned int *default_index /* OUT. May be NULL. */);
-
-
-/*
- * morx/mort
- */
-
-HB_EXTERN hb_bool_t
-hb_aat_layout_has_substitution (hb_face_t *face);
-
-
-/*
- * kerx
- */
-
-HB_EXTERN hb_bool_t
-hb_aat_layout_has_positioning (hb_face_t *face);
-
-
-/*
- * trak
- */
-
-HB_EXTERN hb_bool_t
-hb_aat_layout_has_tracking (hb_face_t *face);
-
-
-HB_END_DECLS
-
-#endif /* HB_AAT_LAYOUT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh
deleted file mode 100644
index 15c382aa92d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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_AAT_LAYOUT_HH
-#define HB_AAT_LAYOUT_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shape.hh"
-#include "hb-aat-ltag-table.hh"
-
-struct hb_aat_feature_mapping_t
-{
- hb_tag_t otFeatureTag;
- hb_aat_layout_feature_type_t aatFeatureType;
- hb_aat_layout_feature_selector_t selectorToEnable;
- hb_aat_layout_feature_selector_t selectorToDisable;
-
- int cmp (hb_tag_t key) const
- { return key < otFeatureTag ? -1 : key > otFeatureTag ? 1 : 0; }
-};
-
-HB_INTERNAL const hb_aat_feature_mapping_t *
-hb_aat_layout_find_feature_mapping (hb_tag_t tag);
-
-HB_INTERNAL void
-hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
- hb_aat_map_t *map);
-
-HB_INTERNAL void
-hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned num_features);
-
-HB_INTERNAL void
-hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer);
-
-HB_INTERNAL void
-hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer);
-
-HB_INTERNAL void
-hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-HB_INTERNAL void
-hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-#endif /* HB_AAT_LAYOUT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh
deleted file mode 100644
index 6d771e1513e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-ltag-table.hh
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_LTAG_TABLE_HH
-#define HB_AAT_LTAG_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * ltag -- Language Tag
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html
- */
-#define HB_AAT_TAG_ltag HB_TAG('l','t','a','g')
-
-
-namespace AAT {
-
-using namespace OT;
-
-
-struct FTStringRange
-{
- friend struct ltag;
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && (base+tag).sanitize (c, length));
- }
-
- protected:
- NNOffset16To<UnsizedArrayOf<HBUINT8>>
- tag; /* Offset from the start of the table to
- * the beginning of the string */
- HBUINT16 length; /* String length (in bytes) */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct ltag
-{
- static constexpr hb_tag_t tableTag = HB_AAT_TAG_ltag;
-
- hb_language_t get_language (unsigned int i) const
- {
- const FTStringRange &range = tagRanges[i];
- return hb_language_from_string ((const char *) (this+range.tag).arrayZ,
- range.length);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version >= 1 &&
- tagRanges.sanitize (c, this)));
- }
-
- protected:
- HBUINT32 version; /* Table version; currently 1 */
- HBUINT32 flags; /* Table flags; currently none defined */
- Array32Of<FTStringRange>
- tagRanges; /* Range for each tag's string */
- public:
- DEFINE_SIZE_ARRAY (12, tagRanges);
-};
-
-} /* namespace AAT */
-
-
-#endif /* HB_AAT_LTAG_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc
deleted file mode 100644
index 5bdb8004f2f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright © 2009,2010 Red Hat, Inc.
- * Copyright © 2010,2011,2013 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_AAT_SHAPE
-
-#include "hb-aat-map.hh"
-
-#include "hb-aat-layout.hh"
-#include "hb-aat-layout-feat-table.hh"
-
-
-void hb_aat_map_builder_t::add_feature (const hb_feature_t &feature)
-{
- if (!face->table.feat->has_data ()) return;
-
- if (feature.tag == HB_TAG ('a','a','l','t'))
- {
- if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES))
- return;
- feature_range_t *range = features.push();
- range->start = feature.start;
- range->end = feature.end;
- range->info.type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES;
- range->info.setting = (hb_aat_layout_feature_selector_t) feature.value;
- range->info.seq = features.length;
- range->info.is_exclusive = true;
- return;
- }
-
- const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (feature.tag);
- if (!mapping) return;
-
- const AAT::FeatureName* feature_name = &face->table.feat->get_feature (mapping->aatFeatureType);
- if (!feature_name->has_data ())
- {
- /* Special case: Chain::compile_flags will fall back to the deprecated version of
- * small-caps if necessary, so we need to check for that possibility.
- * https://github.com/harfbuzz/harfbuzz/issues/2307 */
- if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE &&
- mapping->selectorToEnable == HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS)
- {
- feature_name = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE);
- if (!feature_name->has_data ()) return;
- }
- else return;
- }
-
- feature_range_t *range = features.push();
- range->start = feature.start;
- range->end = feature.end;
- range->info.type = mapping->aatFeatureType;
- range->info.setting = feature.value ? mapping->selectorToEnable : mapping->selectorToDisable;
- range->info.seq = features.length;
- range->info.is_exclusive = feature_name->is_exclusive ();
-}
-
-void
-hb_aat_map_builder_t::compile (hb_aat_map_t &m)
-{
- /* Compute active features per range, and compile each. */
-
- /* Sort features by start/end events. */
- hb_vector_t<feature_event_t> feature_events;
- for (unsigned int i = 0; i < features.length; i++)
- {
- auto &feature = features[i];
-
- if (features[i].start == features[i].end)
- continue;
-
- feature_event_t *event;
-
- event = feature_events.push ();
- event->index = features[i].start;
- event->start = true;
- event->feature = feature.info;
-
- event = feature_events.push ();
- event->index = features[i].end;
- event->start = false;
- event->feature = feature.info;
- }
- feature_events.qsort ();
- /* Add a strategic final event. */
- {
- feature_info_t feature;
- feature.seq = features.length + 1;
-
- feature_event_t *event = feature_events.push ();
- event->index = -1; /* This value does magic. */
- event->start = false;
- event->feature = feature;
- }
-
- /* Scan events and save features for each range. */
- hb_sorted_vector_t<feature_info_t> active_features;
- unsigned int last_index = 0;
- for (unsigned int i = 0; i < feature_events.length; i++)
- {
- feature_event_t *event = &feature_events[i];
-
- if (event->index != last_index)
- {
- /* Save a snapshot of active features and the range. */
-
- /* Sort features and merge duplicates */
- current_features = active_features;
- range_first = last_index;
- range_last = event->index - 1;
- if (current_features.length)
- {
- current_features.qsort ();
- unsigned int j = 0;
- for (unsigned int i = 1; i < current_features.length; i++)
- if (current_features[i].type != current_features[j].type ||
- /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
- * respectively, so we mask out the low-order bit when checking for "duplicates"
- * (selectors referring to the same feature setting) here. */
- (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1))))
- current_features[++j] = current_features[i];
- current_features.shrink (j + 1);
- }
-
- hb_aat_layout_compile_map (this, &m);
-
- last_index = event->index;
- }
-
- if (event->start)
- {
- active_features.push (event->feature);
- } else {
- feature_info_t *feature = active_features.lsearch (event->feature);
- if (feature)
- active_features.remove_ordered (feature - active_features.arrayZ);
- }
- }
-
- for (auto &chain_flags : m.chain_flags)
- // With our above setup this value is one less than desired; adjust it.
- chain_flags.tail().cluster_last = HB_FEATURE_GLOBAL_END;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh
deleted file mode 100644
index cb22ffee42d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-map.hh
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright © 2018 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_AAT_MAP_HH
-#define HB_AAT_MAP_HH
-
-#include "hb.hh"
-
-
-struct hb_aat_map_t
-{
- friend struct hb_aat_map_builder_t;
-
- public:
- struct range_flags_t
- {
- hb_mask_t flags;
- unsigned cluster_first;
- unsigned cluster_last; // end - 1
- };
-
- public:
- hb_vector_t<hb_sorted_vector_t<range_flags_t>> chain_flags;
-};
-
-struct hb_aat_map_builder_t
-{
- public:
-
- HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_,
- const hb_segment_properties_t props_) :
- face (face_),
- props (props_) {}
-
- HB_INTERNAL void add_feature (const hb_feature_t &feature);
-
- HB_INTERNAL void compile (hb_aat_map_t &m);
-
- public:
- struct feature_info_t
- {
- hb_aat_layout_feature_type_t type;
- hb_aat_layout_feature_selector_t setting;
- bool is_exclusive;
- unsigned seq; /* For stable sorting only. */
-
- HB_INTERNAL 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;
- if (a->type != b->type) return (a->type < b->type ? -1 : 1);
- if (!a->is_exclusive &&
- (a->setting & ~1) != (b->setting & ~1)) return (a->setting < b->setting ? -1 : 1);
- return (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
- }
-
- /* compares type & setting only */
- int cmp (const feature_info_t& f) const
- {
- return (f.type != type) ? (f.type < type ? -1 : 1) :
- (f.setting != setting) ? (f.setting < setting ? -1 : 1) : 0;
- }
- };
-
- struct feature_range_t
- {
- feature_info_t info;
- unsigned start;
- unsigned end;
- };
-
- private:
- struct feature_event_t
- {
- unsigned int index;
- bool start;
- feature_info_t feature;
-
- HB_INTERNAL 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 :
- feature_info_t::cmp (&a->feature, &b->feature);
- }
- };
-
- public:
- hb_face_t *face;
- hb_segment_properties_t props;
-
- public:
- hb_sorted_vector_t<feature_range_t> features;
- hb_sorted_vector_t<feature_info_t> current_features;
- unsigned range_first = HB_FEATURE_GLOBAL_START;
- unsigned range_last = HB_FEATURE_GLOBAL_END;
-};
-
-
-#endif /* HB_AAT_MAP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat.h b/src/3rdparty/harfbuzz-ng/src/hb-aat.h
deleted file mode 100644
index c14313d1e2e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_AAT_H
-#define HB_AAT_H
-#define HB_AAT_H_IN
-
-#include "hb.h"
-
-#include "hb-aat-layout.h"
-
-HB_BEGIN_DECLS
-
-HB_END_DECLS
-
-#undef HB_AAT_H_IN
-#endif /* HB_AAT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh
deleted file mode 100644
index 13587eac017..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh
+++ /dev/null
@@ -1,1405 +0,0 @@
-/*
- * Copyright © 2017 Google, Inc.
- * Copyright © 2019 Facebook, 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
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_ALGS_HH
-#define HB_ALGS_HH
-
-#include "hb.hh"
-#include "hb-meta.hh"
-#include "hb-null.hh"
-#include "hb-number.hh"
-
-#include <algorithm>
-#include <initializer_list>
-#include <functional>
-#include <new>
-
-/*
- * Flags
- */
-
-/* Enable bitwise ops on enums marked as flags_t */
-/* To my surprise, looks like the function resolver is happy to silently cast
- * 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/harfbuzz/harfbuzz/pull/163
- */
-#ifdef _MSC_VER
-# pragma warning(disable:4200)
-# pragma warning(disable:4800)
-#endif
-#define HB_MARK_AS_FLAG_T(T) \
- extern "C++" { \
- static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
- static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
- static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
- static inline constexpr unsigned operator ~ (T r) { return (~(unsigned) r); } \
- static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
- static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
- static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
- } \
- static_assert (true, "")
-
-/* Useful for set-operations on small enums.
- * For example, for testing "x ∈ {x1, x2, x3}" use:
- * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
- */
-#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x)))
-#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0)
-#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x))
-#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x)))
-#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0)
-
-
-/*
- * Big-endian integers.
- */
-
-/* Endian swap, used in Windows related backends */
-static inline constexpr uint16_t hb_uint16_swap (uint16_t v)
-{ return (v >> 8) | (v << 8); }
-static inline constexpr uint32_t hb_uint32_swap (uint32_t v)
-{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
-
-template <typename Type, int Bytes = sizeof (Type)>
-struct BEInt;
-template <typename Type>
-struct BEInt<Type, 1>
-{
- public:
- BEInt () = default;
- constexpr BEInt (Type V) : v {uint8_t (V)} {}
- constexpr operator Type () const { return v; }
- private: uint8_t v;
-};
-template <typename Type>
-struct BEInt<Type, 2>
-{
- public:
- BEInt () = default;
- constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF),
- uint8_t ((V ) & 0xFF)} {}
-
- struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
- constexpr operator Type () const
- {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
- defined(__BYTE_ORDER) && \
- (__BYTE_ORDER == __BIG_ENDIAN || \
- (__BYTE_ORDER == __LITTLE_ENDIAN && \
- hb_has_builtin(__builtin_bswap16)))
- /* Spoon-feed the compiler a big-endian integer with alignment 1.
- * https://github.com/harfbuzz/harfbuzz/pull/1398 */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- return __builtin_bswap16 (((packed_uint16_t *) v)->v);
-#else /* __BYTE_ORDER == __BIG_ENDIAN */
- return ((packed_uint16_t *) v)->v;
-#endif
-#else
- return (v[0] << 8)
- + (v[1] );
-#endif
- }
- private: uint8_t v[2];
-};
-template <typename Type>
-struct BEInt<Type, 3>
-{
- static_assert (!std::is_signed<Type>::value, "");
- public:
- BEInt () = default;
- constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF),
- uint8_t ((V >> 8) & 0xFF),
- uint8_t ((V ) & 0xFF)} {}
-
- constexpr operator Type () const { return (v[0] << 16)
- + (v[1] << 8)
- + (v[2] ); }
- private: uint8_t v[3];
-};
-template <typename Type>
-struct BEInt<Type, 4>
-{
- public:
- BEInt () = default;
- constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF),
- uint8_t ((V >> 16) & 0xFF),
- uint8_t ((V >> 8) & 0xFF),
- uint8_t ((V ) & 0xFF)} {}
-
- struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
- constexpr operator Type () const {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
- defined(__BYTE_ORDER) && \
- (__BYTE_ORDER == __BIG_ENDIAN || \
- (__BYTE_ORDER == __LITTLE_ENDIAN && \
- hb_has_builtin(__builtin_bswap32)))
- /* Spoon-feed the compiler a big-endian integer with alignment 1.
- * https://github.com/harfbuzz/harfbuzz/pull/1398 */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- return __builtin_bswap32 (((packed_uint32_t *) v)->v);
-#else /* __BYTE_ORDER == __BIG_ENDIAN */
- return ((packed_uint32_t *) v)->v;
-#endif
-#else
- return (v[0] << 24)
- + (v[1] << 16)
- + (v[2] << 8)
- + (v[3] );
-#endif
- }
- private: uint8_t v[4];
-};
-
-/* Floats. */
-
-/* We want our rounding towards +infinity. */
-static inline float
-_hb_roundf (float x) { return floorf (x + .5f); }
-#define roundf(x) _hb_roundf(x)
-
-
-/* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits,
- * values will be truncated / overlap, and might not decode exactly. */
-#define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z))
-#define HB_CODEPOINT_DECODE3_1(v) ((hb_codepoint_t) ((v) >> 42))
-#define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
-#define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
-
-/* Custom encoding used by hb-ucd. */
-#define HB_CODEPOINT_ENCODE3_11_7_14(x,y,z) (((uint32_t) ((x) & 0x07FFu) << 21) | (((uint32_t) (y) & 0x007Fu) << 14) | (uint32_t) ((z) & 0x3FFFu))
-#define HB_CODEPOINT_DECODE3_11_7_14_1(v) ((hb_codepoint_t) ((v) >> 21))
-#define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
-#define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
-
-
-struct
-{
- /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
- template <typename T> constexpr auto
- operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) )
-}
-HB_FUNCOBJ (hb_identity);
-struct
-{
- /* Like identity(), but only retains lvalue-references. Rvalues are returned as rvalues. */
- template <typename T> constexpr T&
- operator () (T& v) const { return v; }
-
- template <typename T> constexpr hb_remove_reference<T>
- operator () (T&& v) const { return v; }
-}
-HB_FUNCOBJ (hb_lidentity);
-struct
-{
- /* Like identity(), but always returns rvalue. */
- template <typename T> constexpr hb_remove_reference<T>
- operator () (T&& v) const { return v; }
-}
-HB_FUNCOBJ (hb_ridentity);
-
-struct
-{
- template <typename T> constexpr bool
- operator () (T&& v) const { return bool (std::forward<T> (v)); }
-}
-HB_FUNCOBJ (hb_bool);
-
-struct
-{
- private:
-
- template <typename T> constexpr auto
- impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
-
- template <typename T> constexpr auto
- impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
-
- public:
-
- template <typename T> constexpr auto
- operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
-}
-HB_FUNCOBJ (hb_hash);
-
-
-struct
-{
- private:
-
- /* Pointer-to-member-function. */
- template <typename Appl, typename T, typename ...Ts> auto
- impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
- ((hb_deref (std::forward<T> (v)).*std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
-
- /* Pointer-to-member. */
- template <typename Appl, typename T> auto
- impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
- ((hb_deref (std::forward<T> (v))).*std::forward<Appl> (a))
-
- /* Operator(). */
- template <typename Appl, typename ...Ts> auto
- impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
- (hb_deref (std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
-
- public:
-
- template <typename Appl, typename ...Ts> auto
- operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
- (
- impl (std::forward<Appl> (a),
- hb_prioritize,
- std::forward<Ts> (ds)...)
- )
-}
-HB_FUNCOBJ (hb_invoke);
-
-template <unsigned Pos, typename Appl, typename V>
-struct hb_partial_t
-{
- hb_partial_t (Appl a, V v) : a (a), v (v) {}
-
- static_assert (Pos > 0, "");
-
- template <typename ...Ts,
- unsigned P = Pos,
- hb_enable_if (P == 1)> auto
- operator () (Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
- hb_declval (V),
- hb_declval (Ts)...))
- {
- return hb_invoke (std::forward<Appl> (a),
- std::forward<V> (v),
- std::forward<Ts> (ds)...);
- }
- template <typename T0, typename ...Ts,
- unsigned P = Pos,
- hb_enable_if (P == 2)> auto
- operator () (T0&& d0, Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
- hb_declval (T0),
- hb_declval (V),
- hb_declval (Ts)...))
- {
- return hb_invoke (std::forward<Appl> (a),
- std::forward<T0> (d0),
- std::forward<V> (v),
- std::forward<Ts> (ds)...);
- }
-
- private:
- hb_reference_wrapper<Appl> a;
- V v;
-};
-template <unsigned Pos=1, typename Appl, typename V>
-auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
-(( hb_partial_t<Pos, Appl, V> (a, v) ))
-
-/* The following, HB_PARTIALIZE, macro uses a particular corner-case
- * of C++11 that is not particularly well-supported by all compilers.
- * What's happening is that it's using "this" in a trailing return-type
- * via decltype(). Broken compilers deduce the type of "this" pointer
- * in that context differently from what it resolves to in the body
- * of the function.
- *
- * One probable cause of this is that at the time of trailing return
- * type declaration, "this" points to an incomplete type, whereas in
- * the function body the type is complete. That doesn't justify the
- * error in any way, but is probably what's happening.
- *
- * In the case of MSVC, we get around this by using C++14 "decltype(auto)"
- * which deduces the type from the actual return statement. For gcc 4.8
- * we use "+this" instead of "this" which produces an rvalue that seems
- * to be deduced as the same type with this particular compiler, and seem
- * to be fine as default code path as well.
- */
-#ifdef _MSC_VER
-/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \
-#define HB_PARTIALIZE(Pos) \
- template <typename _T> \
- decltype(auto) operator () (_T&& _v) const \
- { return hb_partial<Pos> (this, std::forward<_T> (_v)); } \
- static_assert (true, "")
-#else
-/* https://github.com/harfbuzz/harfbuzz/issues/1724 */
-#define HB_PARTIALIZE(Pos) \
- template <typename _T> \
- auto operator () (_T&& _v) const HB_AUTO_RETURN \
- (hb_partial<Pos> (+this, std::forward<_T> (_v))) \
- static_assert (true, "")
-#endif
-
-
-struct
-{
- private:
-
- template <typename Pred, typename Val> auto
- impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
- (
- hb_deref (std::forward<Pred> (p)).has (std::forward<Val> (v))
- )
-
- template <typename Pred, typename Val> auto
- impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
- (
- hb_invoke (std::forward<Pred> (p),
- std::forward<Val> (v))
- )
-
- public:
-
- template <typename Pred, typename Val> auto
- operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
- impl (std::forward<Pred> (p),
- std::forward<Val> (v),
- hb_prioritize)
- )
-}
-HB_FUNCOBJ (hb_has);
-
-struct
-{
- private:
-
- template <typename Pred, typename Val> auto
- impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
- (
- hb_has (std::forward<Pred> (p),
- std::forward<Val> (v))
- )
-
- template <typename Pred, typename Val> auto
- impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
- (
- std::forward<Pred> (p) == std::forward<Val> (v)
- )
-
- public:
-
- template <typename Pred, typename Val> auto
- operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
- impl (std::forward<Pred> (p),
- std::forward<Val> (v),
- hb_prioritize)
- )
-}
-HB_FUNCOBJ (hb_match);
-
-struct
-{
- private:
-
- template <typename Proj, typename Val> auto
- impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
- (
- hb_deref (std::forward<Proj> (f)).get (std::forward<Val> (v))
- )
-
- template <typename Proj, typename Val> auto
- impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
- (
- hb_invoke (std::forward<Proj> (f),
- std::forward<Val> (v))
- )
-
- template <typename Proj, typename Val> auto
- impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
- (
- std::forward<Proj> (f)[std::forward<Val> (v)]
- )
-
- public:
-
- template <typename Proj, typename Val> auto
- operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
- (
- impl (std::forward<Proj> (f),
- std::forward<Val> (v),
- hb_prioritize)
- )
-}
-HB_FUNCOBJ (hb_get);
-
-struct
-{
- private:
-
- template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<3>) const HB_AUTO_RETURN
- (
- std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
- )
-
- template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
- (
- std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
- )
-
- template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
- (
- std::forward<T1> (v1) == std::forward<T2> (v2)
- )
-
- template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
- (
- std::forward<T2> (v2) == std::forward<T1> (v1)
- )
-
- public:
-
- template <typename T1, typename T2> auto
- operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN
- (
- impl (std::forward<T1> (v1),
- std::forward<T2> (v2),
- hb_prioritize)
- )
-}
-HB_FUNCOBJ (hb_equal);
-
-struct
-{
- template <typename T> void
- operator () (T& a, T& b) const
- {
- using std::swap; // allow ADL
- swap (a, b);
- }
-}
-HB_FUNCOBJ (hb_swap);
-
-
-template <typename T1, typename T2>
-struct hb_pair_t
-{
- typedef T1 first_t;
- typedef T2 second_t;
- typedef hb_pair_t<T1, T2> pair_t;
-
- template <typename U1 = T1, typename U2 = T2,
- hb_enable_if (std::is_default_constructible<U1>::value &&
- std::is_default_constructible<U2>::value)>
- hb_pair_t () : first (), second () {}
- hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {}
-
- template <typename Q1, typename Q2,
- hb_enable_if (hb_is_convertible (T1, Q1) &&
- hb_is_convertible (T2, Q2))>
- operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
-
- hb_pair_t<T1, T2> reverse () const
- { return hb_pair_t<T1, T2> (second, first); }
-
- bool operator == (const pair_t& o) const { return first == o.first && second == o.second; }
- bool operator != (const pair_t& o) const { return !(*this == o); }
- bool operator < (const pair_t& o) const { return first < o.first || (first == o.first && second < o.second); }
- bool operator >= (const pair_t& o) const { return !(*this < o); }
- bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
- bool operator <= (const pair_t& o) const { return !(*this > o); }
-
- static int cmp (const void *pa, const void *pb)
- {
- pair_t *a = (pair_t *) pa;
- pair_t *b = (pair_t *) pb;
-
- if (a->first < b->first) return -1;
- if (a->first > b->first) return +1;
- if (a->second < b->second) return -1;
- if (a->second > b->second) return +1;
- return 0;
- }
-
- friend void swap (hb_pair_t& a, hb_pair_t& b)
- {
- hb_swap (a.first, b.first);
- hb_swap (a.second, b.second);
- }
-
-
- T1 first;
- T2 second;
-};
-template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
-hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
-
-struct
-{
- template <typename Pair> constexpr typename Pair::first_t
- operator () (const Pair& pair) const { return pair.first; }
-}
-HB_FUNCOBJ (hb_first);
-
-struct
-{
- template <typename Pair> constexpr typename Pair::second_t
- operator () (const Pair& pair) const { return pair.second; }
-}
-HB_FUNCOBJ (hb_second);
-
-/* Note. In min/max impl, we can use hb_type_identity<T> for second argument.
- * However, that would silently convert between different-signedness integers.
- * Instead we accept two different types, such that compiler can err if
- * comparing integers of different signedness. */
-struct
-{
- template <typename T, typename T2> constexpr auto
- operator () (T&& a, T2&& b) const HB_AUTO_RETURN
- (a <= b ? a : b)
-}
-HB_FUNCOBJ (hb_min);
-struct
-{
- template <typename T, typename T2> constexpr auto
- operator () (T&& a, T2&& b) const HB_AUTO_RETURN
- (a >= b ? a : b)
-}
-HB_FUNCOBJ (hb_max);
-struct
-{
- template <typename T, typename T2, typename T3> constexpr auto
- operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
- (hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max)))
-}
-HB_FUNCOBJ (hb_clamp);
-
-/*
- * Bithacks.
- */
-
-/* Return the number of 1 bits in v. */
-template <typename T>
-static inline unsigned int
-hb_popcount (T v)
-{
-#if hb_has_builtin(__builtin_popcount)
- if (sizeof (T) <= sizeof (unsigned int))
- return __builtin_popcount (v);
-#endif
-
-#if hb_has_builtin(__builtin_popcountl)
- if (sizeof (T) <= sizeof (unsigned long))
- return __builtin_popcountl (v);
-#endif
-
-#if hb_has_builtin(__builtin_popcountll)
- if (sizeof (T) <= sizeof (unsigned long long))
- return __builtin_popcountll (v);
-#endif
-
- if (sizeof (T) <= 4)
- {
- /* "HACKMEM 169" */
- uint32_t y;
- y = (v >> 1) &033333333333;
- y = v - y - ((y >>1) & 033333333333);
- return (((y + (y >> 3)) & 030707070707) % 077);
- }
-
- if (sizeof (T) == 8)
- {
- unsigned int shift = 32;
- return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
- }
-
- if (sizeof (T) == 16)
- {
- unsigned int shift = 64;
- return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
- }
-
- assert (0);
- return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of bits needed to store number */
-template <typename T>
-static inline unsigned int
-hb_bit_storage (T v)
-{
- if (unlikely (!v)) return 0;
-
-#if hb_has_builtin(__builtin_clz)
- if (sizeof (T) <= sizeof (unsigned int))
- return sizeof (unsigned int) * 8 - __builtin_clz (v);
-#endif
-
-#if hb_has_builtin(__builtin_clzl)
- if (sizeof (T) <= sizeof (unsigned long))
- return sizeof (unsigned long) * 8 - __builtin_clzl (v);
-#endif
-
-#if hb_has_builtin(__builtin_clzll)
- if (sizeof (T) <= sizeof (unsigned long long))
- return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
- if (sizeof (T) <= sizeof (unsigned int))
- {
- unsigned long where;
- _BitScanReverse (&where, v);
- return 1 + where;
- }
-# if defined(_WIN64)
- if (sizeof (T) <= 8)
- {
- unsigned long where;
- _BitScanReverse64 (&where, v);
- return 1 + where;
- }
-# endif
-#endif
-
- if (sizeof (T) <= 4)
- {
- /* "bithacks" */
- const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
- const unsigned int S[] = {1, 2, 4, 8, 16};
- unsigned int r = 0;
- for (int i = 4; i >= 0; i--)
- if (v & b[i])
- {
- v >>= S[i];
- r |= S[i];
- }
- return r + 1;
- }
- if (sizeof (T) <= 8)
- {
- /* "bithacks" */
- const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
- const unsigned int S[] = {1, 2, 4, 8, 16, 32};
- unsigned int r = 0;
- for (int i = 5; i >= 0; i--)
- if (v & b[i])
- {
- v >>= S[i];
- r |= S[i];
- }
- return r + 1;
- }
- if (sizeof (T) == 16)
- {
- unsigned int shift = 64;
- return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
- hb_bit_storage<uint64_t> ((uint64_t) v);
- }
-
- assert (0);
- return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of zero bits in the least significant side of v */
-template <typename T>
-static inline unsigned int
-hb_ctz (T v)
-{
- if (unlikely (!v)) return 8 * sizeof (T);
-
-#if hb_has_builtin(__builtin_ctz)
- if (sizeof (T) <= sizeof (unsigned int))
- return __builtin_ctz (v);
-#endif
-
-#if hb_has_builtin(__builtin_ctzl)
- if (sizeof (T) <= sizeof (unsigned long))
- return __builtin_ctzl (v);
-#endif
-
-#if hb_has_builtin(__builtin_ctzll)
- if (sizeof (T) <= sizeof (unsigned long long))
- return __builtin_ctzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
- if (sizeof (T) <= sizeof (unsigned int))
- {
- unsigned long where;
- _BitScanForward (&where, v);
- return where;
- }
-# if defined(_WIN64)
- if (sizeof (T) <= 8)
- {
- unsigned long where;
- _BitScanForward64 (&where, v);
- return where;
- }
-# endif
-#endif
-
- if (sizeof (T) <= 4)
- {
- /* "bithacks" */
- unsigned int c = 32;
- v &= - (int32_t) v;
- if (v) c--;
- if (v & 0x0000FFFF) c -= 16;
- if (v & 0x00FF00FF) c -= 8;
- if (v & 0x0F0F0F0F) c -= 4;
- if (v & 0x33333333) c -= 2;
- if (v & 0x55555555) c -= 1;
- return c;
- }
- if (sizeof (T) <= 8)
- {
- /* "bithacks" */
- unsigned int c = 64;
- v &= - (int64_t) (v);
- if (v) c--;
- if (v & 0x00000000FFFFFFFFULL) c -= 32;
- if (v & 0x0000FFFF0000FFFFULL) c -= 16;
- if (v & 0x00FF00FF00FF00FFULL) c -= 8;
- if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
- if (v & 0x3333333333333333ULL) c -= 2;
- if (v & 0x5555555555555555ULL) c -= 1;
- return c;
- }
- if (sizeof (T) == 16)
- {
- unsigned int shift = 64;
- return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
- hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
- }
-
- assert (0);
- return 0; /* Shut up stupid compiler. */
-}
-
-
-/*
- * Tiny stuff.
- */
-
-/* ASCII tag/character handling */
-static inline bool ISALPHA (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
-static inline bool ISALNUM (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
-static inline bool ISSPACE (unsigned char c)
-{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
-static inline unsigned char TOUPPER (unsigned char c)
-{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
-static inline unsigned char TOLOWER (unsigned char c)
-{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
-static inline bool ISHEX (unsigned char c)
-{ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }
-static inline unsigned char TOHEX (uint8_t c)
-{ return (c & 0xF) <= 9 ? (c & 0xF) + '0' : (c & 0xF) + 'a' - 10; }
-static inline uint8_t FROMHEX (unsigned char c)
-{ return (c >= '0' && c <= '9') ? c - '0' : TOLOWER (c) - 'a' + 10; }
-
-static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
-{ return (a + (b - 1)) / b; }
-
-
-#undef ARRAY_LENGTH
-template <typename Type, unsigned int n>
-static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
-/* A const version, but does not detect erratically being called on pointers. */
-#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
-
-
-static inline void *
-hb_memcpy (void *__restrict dst, const void *__restrict src, size_t len)
-{
- /* It's illegal to pass 0 as size to memcpy. */
- if (unlikely (!len)) return dst;
- return memcpy (dst, src, len);
-}
-
-static inline int
-hb_memcmp (const void *a, const void *b, unsigned int len)
-{
- /* It's illegal to pass NULL to memcmp(), even if len is zero.
- * So, wrap it.
- * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
- if (unlikely (!len)) return 0;
- return memcmp (a, b, len);
-}
-
-static inline void *
-hb_memset (void *s, int c, unsigned int n)
-{
- /* It's illegal to pass NULL to memset(), even if n is zero. */
- if (unlikely (!n)) return 0;
- return memset (s, c, n);
-}
-
-static inline unsigned int
-hb_ceil_to_4 (unsigned int v)
-{
- return ((v - 1) | 3) + 1;
-}
-
-template <typename T> static inline bool
-hb_in_range (T u, T lo, T hi)
-{
- static_assert (!std::is_signed<T>::value, "");
-
- /* The casts below are important as if T is smaller than int,
- * the subtract results will become a signed int! */
- return (T)(u - lo) <= (T)(hi - lo);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1)
-{
- return hb_in_range (u, lo1, hi1);
-}
-template <typename T, typename ...Ts> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
-{
- return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...);
-}
-
-
-/*
- * Overflow checking.
- */
-
-static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
-{
-#if hb_has_builtin(__builtin_mul_overflow)
- unsigned stack_result;
- if (!result)
- result = &stack_result;
- return __builtin_mul_overflow (count, size, result);
-#endif
-
- if (result)
- *result = count * size;
- return (size > 0) && (count >= ((unsigned int) -1) / size);
-}
-
-
-/*
- * Sort and search.
- */
-
-template <typename K, typename V, typename ...Ts>
-static int
-_hb_cmp_method (const void *pkey, const void *pval, Ts... ds)
-{
- const K& key = * (const K*) pkey;
- const V& val = * (const V*) pval;
-
- return val.cmp (key, ds...);
-}
-
-template <typename V, typename K, typename ...Ts>
-static inline bool
-hb_bsearch_impl (unsigned *pos, /* Out */
- const K& key,
- V* base, size_t nmemb, size_t stride,
- int (*compar)(const void *_key, const void *_item, Ts... _ds),
- Ts... ds)
-{
- /* This is our *only* bsearch implementation. */
-
- int min = 0, max = (int) nmemb - 1;
- while (min <= max)
- {
- int mid = ((unsigned int) min + (unsigned int) max) / 2;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- V* p = (V*) (((const char *) base) + (mid * stride));
-#pragma GCC diagnostic pop
- int c = compar ((const void *) std::addressof (key), (const void *) p, ds...);
- if (c < 0)
- max = mid - 1;
- else if (c > 0)
- min = mid + 1;
- else
- {
- *pos = mid;
- return true;
- }
- }
- *pos = min;
- return false;
-}
-
-template <typename V, typename K>
-static inline V*
-hb_bsearch (const K& key, V* base,
- size_t nmemb, size_t stride = sizeof (V),
- int (*compar)(const void *_key, const void *_item) = _hb_cmp_method<K, V>)
-{
- unsigned pos;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar) ?
- (V*) (((const char *) base) + (pos * stride)) : nullptr;
-#pragma GCC diagnostic pop
-}
-template <typename V, typename K, typename ...Ts>
-static inline V*
-hb_bsearch (const K& key, V* base,
- size_t nmemb, size_t stride,
- int (*compar)(const void *_key, const void *_item, Ts... _ds),
- Ts... ds)
-{
- unsigned pos;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar, ds...) ?
- (V*) (((const char *) base) + (pos * stride)) : nullptr;
-#pragma GCC diagnostic pop
-}
-
-
-/* From https://github.com/noporpoise/sort_r
- Feb 5, 2019 (c8c65c1e)
- Modified to support optional argument using templates */
-
-/* Isaac Turner 29 April 2014 Public Domain */
-
-/*
-hb_qsort 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 (optional) is a pointer to be passed to the comparison function
-
-void hb_qsort(void *base, size_t nel, size_t width,
- int (*compar)(const void *_a, const void *_b, [void *_arg]),
- [void *arg]);
-*/
-
-#define SORT_R_SWAP(a,b,tmp) ((void) ((tmp) = (a)), (void) ((a) = (b)), (b) = (tmp))
-
-/* swap a and b */
-/* a and b must not be equal! */
-static inline void sort_r_swap(char *__restrict a, char *__restrict b,
- size_t w)
-{
- char tmp, *end = a+w;
- for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }
-}
-
-/* swap a, b iff a>b */
-/* a and b must not be equal! */
-/* __restrict is same as restrict but better support on old machines */
-template <typename ...Ts>
-static inline int sort_r_cmpswap(char *__restrict a,
- char *__restrict b, size_t w,
- int (*compar)(const void *_a,
- const void *_b,
- Ts... _ds),
- Ts... ds)
-{
- if(compar(a, b, ds...) > 0) {
- sort_r_swap(a, b, w);
- return 1;
- }
- return 0;
-}
-
-/*
-Swap consecutive blocks of bytes of size na and nb starting at memory addr ptr,
-with the smallest swap so that the blocks are in the opposite order. Blocks may
-be internally re-ordered e.g.
- 12345ab -> ab34512
- 123abc -> abc123
- 12abcde -> deabc12
-*/
-static inline void sort_r_swap_blocks(char *ptr, size_t na, size_t nb)
-{
- if(na > 0 && nb > 0) {
- if(na > nb) { sort_r_swap(ptr, ptr+na, nb); }
- else { sort_r_swap(ptr, ptr+nb, na); }
- }
-}
-
-/* Implement recursive quicksort ourselves */
-/* Note: quicksort is not stable, equivalent values may be swapped */
-template <typename ...Ts>
-static inline void sort_r_simple(void *base, size_t nel, size_t w,
- int (*compar)(const void *_a,
- const void *_b,
- Ts... _ds),
- Ts... ds)
-{
- char *b = (char *)base, *end = b + nel*w;
-
- /* for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
- printf("\n"); */
-
- if(nel < 10) {
- /* 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,ds...); pj -= w) {}
- }
- }
- else
- {
- /* nel > 9; Quicksort */
-
- int cmp;
- char *pl, *ple, *pr, *pre, *pivot;
- char *last = b+w*(nel-1), *tmp;
-
- /*
- Use median of second, middle and second-last items as pivot.
- First and last may have been swapped with pivot and therefore be extreme
- */
- char *l[3];
- l[0] = b + w;
- l[1] = b+w*(nel/2);
- l[2] = last - w;
-
- /* printf("pivots: %i, %i, %i\n", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */
-
- if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
- if(compar(l[1],l[2],ds...) > 0) {
- SORT_R_SWAP(l[1], l[2], tmp);
- if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
- }
-
- /* swap mid value (l[1]), and last element to put pivot as last element */
- if(l[1] != last) { sort_r_swap(l[1], last, w); }
-
- /*
- pl is the next item on the left to be compared to the pivot
- pr is the last item on the right that was compared to the pivot
- ple is the left position to put the next item that equals the pivot
- ple is the last right position where we put an item that equals the pivot
- v- end (beyond the array)
- EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE.
- ^- b ^- ple ^- pl ^- pr ^- pre ^- last (where the pivot is)
- Pivot comparison key:
- E = equal, L = less than, u = unknown, G = greater than, E = equal
- */
- pivot = last;
- ple = pl = b;
- pre = pr = last;
-
- /*
- Strategy:
- Loop into the list from the left and right at the same time to find:
- - an item on the left that is greater than the pivot
- - an item on the right that is less than the pivot
- Once found, they are swapped and the loop continues.
- Meanwhile items that are equal to the pivot are moved to the edges of the
- array.
- */
- while(pl < pr) {
- /* Move left hand items which are equal to the pivot to the far left.
- break when we find an item that is greater than the pivot */
- for(; pl < pr; pl += w) {
- cmp = compar(pl, pivot, ds...);
- if(cmp > 0) { break; }
- else if(cmp == 0) {
- if(ple < pl) { sort_r_swap(ple, pl, w); }
- ple += w;
- }
- }
- /* break if last batch of left hand items were equal to pivot */
- if(pl >= pr) { break; }
- /* Move right hand items which are equal to the pivot to the far right.
- break when we find an item that is less than the pivot */
- for(; pl < pr; ) {
- pr -= w; /* Move right pointer onto an unprocessed item */
- cmp = compar(pr, pivot, ds...);
- if(cmp == 0) {
- pre -= w;
- if(pr < pre) { sort_r_swap(pr, pre, w); }
- }
- else if(cmp < 0) {
- if(pl < pr) { sort_r_swap(pl, pr, w); }
- pl += w;
- break;
- }
- }
- }
-
- pl = pr; /* pr may have gone below pl */
-
- /*
- Now we need to go from: EEELLLGGGGEEEE
- to: LLLEEEEEEEGGGG
- Pivot comparison key:
- E = equal, L = less than, u = unknown, G = greater than, E = equal
- */
- sort_r_swap_blocks(b, ple-b, pl-ple);
- sort_r_swap_blocks(pr, pre-pr, end-pre);
-
- /*for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
- printf("\n");*/
-
- sort_r_simple(b, (pl-ple)/w, w, compar, ds...);
- sort_r_simple(end-(pre-pr), (pre-pr)/w, w, compar, ds...);
- }
-}
-
-static inline void
-hb_qsort (void *base, size_t nel, size_t width,
- int (*compar)(const void *_a, const void *_b))
-{
-#if defined(__OPTIMIZE_SIZE__) && !defined(HB_USE_INTERNAL_QSORT)
- qsort (base, nel, width, compar);
-#else
- sort_r_simple (base, nel, width, compar);
-#endif
-}
-
-static inline void
-hb_qsort (void *base, size_t nel, size_t width,
- int (*compar)(const void *_a, const void *_b, void *_arg),
- void *arg)
-{
-#ifdef HAVE_GNU_QSORT_R
- qsort_r (base, nel, width, compar, arg);
-#else
- sort_r_simple (base, nel, width, compar, arg);
-#endif
-}
-
-
-template <typename T, typename T2, typename T3 = int> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr)
-{
- static_assert (hb_is_trivially_copy_assignable (T), "");
- static_assert (hb_is_trivially_copy_assignable (T3), "");
-
- for (unsigned int i = 1; i < len; i++)
- {
- unsigned int j = i;
- while (j && compar (&array[j - 1], &array[i]) > 0)
- j--;
- if (i == j)
- continue;
- /* Move item i to occupy place for item j, shift what's in between. */
- {
- T t = array[i];
- memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
- array[j] = t;
- }
- if (array2)
- {
- T3 t = array2[i];
- memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T3));
- array2[j] = t;
- }
- }
-}
-
-static inline hb_bool_t
-hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
-{
- unsigned int v;
- const char *p = s;
- const char *end = p + len;
- if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
- return false;
-
- *out = v;
- return true;
-}
-
-
-/* Operators. */
-
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
-}
-HB_FUNCOBJ (hb_bitwise_and);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
-}
-HB_FUNCOBJ (hb_bitwise_or);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
-}
-HB_FUNCOBJ (hb_bitwise_xor);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & b)
-}
-HB_FUNCOBJ (hb_bitwise_lt);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
-}
-HB_FUNCOBJ (hb_bitwise_gt); // aka sub
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a | b)
-}
-HB_FUNCOBJ (hb_bitwise_le);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T> constexpr auto
- operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | ~b)
-}
-HB_FUNCOBJ (hb_bitwise_ge);
-struct
-{
- template <typename T> constexpr auto
- operator () (const T &a) const HB_AUTO_RETURN (~a)
-}
-HB_FUNCOBJ (hb_bitwise_neg);
-
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
-}
-HB_FUNCOBJ (hb_add);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
-}
-HB_FUNCOBJ (hb_sub);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (b - a)
-}
-HB_FUNCOBJ (hb_rsub);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
-}
-HB_FUNCOBJ (hb_mul);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
-}
-HB_FUNCOBJ (hb_div);
-struct
-{ HB_PARTIALIZE(2);
- template <typename T, typename T2> constexpr auto
- operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
-}
-HB_FUNCOBJ (hb_mod);
-struct
-{
- template <typename T> constexpr auto
- operator () (const T &a) const HB_AUTO_RETURN (+a)
-}
-HB_FUNCOBJ (hb_pos);
-struct
-{
- template <typename T> constexpr auto
- operator () (const T &a) const HB_AUTO_RETURN (-a)
-}
-HB_FUNCOBJ (hb_neg);
-struct
-{
- template <typename T> constexpr auto
- operator () (T &a) const HB_AUTO_RETURN (++a)
-}
-HB_FUNCOBJ (hb_inc);
-struct
-{
- template <typename T> constexpr auto
- operator () (T &a) const HB_AUTO_RETURN (--a)
-}
-HB_FUNCOBJ (hb_dec);
-
-
-/* Adapted from kurbo implementation with extra parameters added,
- * and finding for a particular range instead of 0.
- *
- * For documentation and implementation see:
- *
- * [ITP method]: https://en.wikipedia.org/wiki/ITP_Method
- * [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality]: https://dl.acm.org/doi/10.1145/3423597
- * https://docs.rs/kurbo/0.8.1/kurbo/common/fn.solve_itp.html
- * https://github.com/linebender/kurbo/blob/fd839c25ea0c98576c7ce5789305822675a89938/src/common.rs#L162-L248
- */
-template <typename func_t>
-double solve_itp (func_t f,
- double a, double b,
- double epsilon,
- double min_y, double max_y,
- double &ya, double &yb, double &y)
-{
- unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0));
- const unsigned n0 = 1; // Hardwired
- const double k1 = 0.2 / (b - a); // Hardwired.
- unsigned nmax = n0 + n1_2;
- double scaled_epsilon = epsilon * double (1llu << nmax);
- double _2_epsilon = 2.0 * epsilon;
- while (b - a > _2_epsilon)
- {
- double x1_2 = 0.5 * (a + b);
- double r = scaled_epsilon - 0.5 * (b - a);
- double xf = (yb * a - ya * b) / (yb - ya);
- double sigma = x1_2 - xf;
- double b_a = b - a;
- // This has k2 = 2 hardwired for efficiency.
- double b_a_k2 = b_a * b_a;
- double delta = k1 * b_a_k2;
- int sigma_sign = sigma >= 0 ? +1 : -1;
- double xt = delta <= fabs (x1_2 - xf) ? xf + delta * sigma_sign : x1_2;
- double xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign;
- double yitp = f (xitp);
- if (yitp > max_y)
- {
- b = xitp;
- yb = yitp;
- }
- else if (yitp < min_y)
- {
- a = xitp;
- ya = yitp;
- }
- else
- {
- y = yitp;
- return xitp;
- }
- scaled_epsilon *= 0.5;
- }
- return 0.5 * (a + b);
-}
-
-
-#endif /* HB_ALGS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-array.hh
deleted file mode 100644
index e82c081535e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-array.hh
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright © 2018 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_ARRAY_HH
-#define HB_ARRAY_HH
-
-#include "hb.hh"
-#include "hb-algs.hh"
-#include "hb-iter.hh"
-#include "hb-null.hh"
-
-
-template <typename Type>
-struct hb_sorted_array_t;
-
-enum hb_not_found_t
-{
- HB_NOT_FOUND_DONT_STORE,
- HB_NOT_FOUND_STORE,
- HB_NOT_FOUND_STORE_CLOSEST,
-};
-
-
-template <typename Type>
-struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
-{
- /*
- * Constructors.
- */
- hb_array_t () = default;
- hb_array_t (const hb_array_t&) = default;
- ~hb_array_t () = default;
- hb_array_t& operator= (const hb_array_t&) = default;
- hb_array_t& operator= (hb_array_t&&) = default;
-
- constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
- template <unsigned int length_>
- constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
-
- template <typename U,
- hb_enable_if (hb_is_cr_convertible(U, Type))>
- constexpr hb_array_t (const hb_array_t<U> &o) :
- hb_iter_with_fallback_t<hb_array_t, Type&> (),
- arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
- template <typename U,
- hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_array_t& operator = (const hb_array_t<U> &o)
- { arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
-
- /*
- * Iterator implementation.
- */
- typedef Type& __item_t__;
- static constexpr bool is_random_access_iterator = true;
- Type& __item_at__ (unsigned i) const
- {
- if (unlikely (i >= length)) return CrapOrNull (Type);
- return arrayZ[i];
- }
- void __forward__ (unsigned n)
- {
- if (unlikely (n > length))
- n = length;
- length -= n;
- backwards_length += n;
- arrayZ += n;
- }
- void __rewind__ (unsigned n)
- {
- if (unlikely (n > backwards_length))
- n = backwards_length;
- length += n;
- backwards_length -= n;
- arrayZ -= n;
- }
- unsigned __len__ () const { return length; }
- /* Ouch. The operator== compares the contents of the array. For range-based for loops,
- * it's best if we can just compare arrayZ, though comparing contents is still fast,
- * but also would require that Type has operator==. As such, we optimize this operator
- * for range-based for loop and just compare arrayZ and length.
- *
- * The above comment is outdated now because we implemented separate begin/end to
- * objects that were using hb_array_t for range-based loop before. */
- bool operator != (const hb_array_t& o) const
- { return this->arrayZ != o.arrayZ || this->length != o.length; }
-
- /* Faster range-based for loop without bounds-check. */
- Type *begin () const { return arrayZ; }
- Type *end () const { return arrayZ + length; }
-
-
- /* Extra operators.
- */
- Type * operator & () const { return arrayZ; }
- operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
- template <typename T> operator T * () const { return arrayZ; }
-
- HB_INTERNAL bool operator == (const hb_array_t &o) const;
-
- uint32_t hash () const
- {
- uint32_t current = 0;
- for (auto &v : *this)
- current = current * 31 + hb_hash (v);
- return current;
- }
-
- /*
- * Compare, Sort, and Search.
- */
-
- /* Note: our compare is NOT lexicographic; it also does NOT call Type::cmp. */
- int cmp (const hb_array_t &a) const
- {
- if (length != a.length)
- return (int) a.length - (int) length;
- return hb_memcmp (a.arrayZ, arrayZ, get_size ());
- }
- HB_INTERNAL static int cmp (const void *pa, const void *pb)
- {
- hb_array_t *a = (hb_array_t *) pa;
- hb_array_t *b = (hb_array_t *) pb;
- return b->cmp (*a);
- }
-
- template <typename T>
- Type *lsearch (const T &x, Type *not_found = nullptr)
- {
- unsigned i;
- return lfind (x, &i) ? &this->arrayZ[i] : not_found;
- }
- template <typename T>
- const Type *lsearch (const T &x, const Type *not_found = nullptr) const
- {
- unsigned i;
- return lfind (x, &i) ? &this->arrayZ[i] : not_found;
- }
- template <typename T>
- bool lfind (const T &x, unsigned *pos = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- {
- for (unsigned i = 0; i < length; ++i)
- if (hb_equal (x, this->arrayZ[i]))
- {
- if (pos)
- *pos = i;
- return true;
- }
-
- if (pos)
- {
- switch (not_found)
- {
- case HB_NOT_FOUND_DONT_STORE:
- break;
-
- case HB_NOT_FOUND_STORE:
- *pos = to_store;
- break;
-
- case HB_NOT_FOUND_STORE_CLOSEST:
- *pos = length;
- break;
- }
- }
- return false;
- }
-
- hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
- {
- //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
- if (likely (length))
- hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
- return hb_sorted_array_t<Type> (*this);
- }
- hb_sorted_array_t<Type> qsort ()
- {
- //static_assert (hb_enable_if (hb_is_trivially_copy_assignable(Type)), "");
- if (likely (length))
- hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
- return hb_sorted_array_t<Type> (*this);
- }
-
- /*
- * Other methods.
- */
-
- unsigned int get_size () const { return length * this->get_item_size (); }
-
- /*
- * Reverse the order of items in this array in the range [start, end).
- */
- void reverse (unsigned start = 0, unsigned end = -1)
- {
- start = hb_min (start, length);
- end = hb_min (end, length);
-
- if (end < start + 2)
- return;
-
- for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--)
- hb_swap (arrayZ[rhs], arrayZ[lhs]);
- }
-
- hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
- {
- if (!start_offset && !seg_count)
- return *this;
-
- unsigned int count = length;
- if (unlikely (start_offset > count))
- count = 0;
- else
- count -= start_offset;
- if (seg_count)
- count = *seg_count = hb_min (count, *seg_count);
- return hb_array_t (arrayZ + start_offset, count);
- }
- hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
- { return sub_array (start_offset, &seg_count); }
-
- hb_array_t truncate (unsigned length) const { return sub_array (0, length); }
-
- template <typename T,
- unsigned P = sizeof (Type),
- hb_enable_if (P == 1)>
- const T *as () const
- { return length < hb_min_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); }
-
- template <typename T,
- unsigned P = sizeof (Type),
- hb_enable_if (P == 1)>
- bool check_range (const T *p, unsigned int size = T::static_size) const
- {
- return arrayZ <= ((const char *) p)
- && ((const char *) p) <= arrayZ + length
- && (unsigned int) (arrayZ + length - (const char *) p) >= size;
- }
-
- /* Only call if you allocated the underlying array using hb_malloc() or similar. */
- void fini ()
- { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
-
- template <typename hb_serialize_context_t,
- typename U = Type,
- hb_enable_if (!(sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>)))>
- hb_array_t copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto* out = c->start_embed (arrayZ);
- if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
- for (unsigned i = 0; i < length; i++)
- out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
- return_trace (hb_array_t (out, length));
- }
-
- template <typename hb_serialize_context_t,
- typename U = Type,
- hb_enable_if (sizeof (U) < sizeof (long long) && hb_is_trivially_copy_assignable(hb_decay<Type>))>
- hb_array_t copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto* out = c->start_embed (arrayZ);
- if (unlikely (!c->extend_size (out, get_size (), false))) return_trace (hb_array_t ());
- hb_memcpy (out, arrayZ, get_size ());
- return_trace (hb_array_t (out, length));
- }
-
- template <typename hb_sanitize_context_t>
- bool sanitize (hb_sanitize_context_t *c) const
- { return c->check_array (arrayZ, length); }
-
- /*
- * Members
- */
-
- public:
- Type *arrayZ = nullptr;
- unsigned int length = 0;
- unsigned int backwards_length = 0;
-};
-template <typename T> inline hb_array_t<T>
-hb_array ()
-{ return hb_array_t<T> (); }
-template <typename T> inline hb_array_t<T>
-hb_array (T *array, unsigned int length)
-{ return hb_array_t<T> (array, length); }
-template <typename T, unsigned int length_> inline hb_array_t<T>
-hb_array (T (&array_)[length_])
-{ return hb_array_t<T> (array_); }
-
-template <typename Type>
-struct hb_sorted_array_t :
- hb_array_t<Type>,
- hb_iter_t<hb_sorted_array_t<Type>, Type&>
-{
- typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t;
- HB_ITER_USING (iter_base_t);
- static constexpr bool is_random_access_iterator = true;
- static constexpr bool is_sorted_iterator = true;
-
- hb_sorted_array_t () = default;
- hb_sorted_array_t (const hb_sorted_array_t&) = default;
- ~hb_sorted_array_t () = default;
- hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default;
- hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default;
-
- constexpr hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
- template <unsigned int length_>
- constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
-
- template <typename U,
- hb_enable_if (hb_is_cr_convertible(U, Type))>
- constexpr hb_sorted_array_t (const hb_array_t<U> &o) :
- hb_array_t<Type> (o),
- hb_iter_t<hb_sorted_array_t, Type&> () {}
- template <typename U,
- hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_sorted_array_t& operator = (const hb_array_t<U> &o)
- { hb_array_t<Type> (*this) = o; return *this; }
-
- /* Iterator implementation. */
-
- /* See comment in hb_array_of::operator != */
- bool operator != (const hb_sorted_array_t& o) const
- { return this->arrayZ != o.arrayZ || this->length != o.length; }
-
- /* Faster range-based for loop without bounds-check. */
- Type *begin () const { return this->arrayZ; }
- Type *end () const { return this->arrayZ + this->length; }
-
-
- hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
- { return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
- hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
- { return sub_array (start_offset, &seg_count); }
-
- hb_sorted_array_t truncate (unsigned length) const { return sub_array (0, length); }
-
- template <typename T>
- Type *bsearch (const T &x, Type *not_found = nullptr)
- {
- unsigned int i;
- return bfind (x, &i) ? &this->arrayZ[i] : not_found;
- }
- template <typename T>
- const Type *bsearch (const T &x, const Type *not_found = nullptr) const
- {
- unsigned int i;
- return bfind (x, &i) ? &this->arrayZ[i] : not_found;
- }
- template <typename T>
- bool bfind (const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- {
- unsigned pos;
-
- if (bsearch_impl (x, &pos))
- {
- if (i)
- *i = pos;
- return true;
- }
-
- if (i)
- {
- switch (not_found)
- {
- case HB_NOT_FOUND_DONT_STORE:
- break;
-
- case HB_NOT_FOUND_STORE:
- *i = to_store;
- break;
-
- case HB_NOT_FOUND_STORE_CLOSEST:
- *i = pos;
- break;
- }
- }
- return false;
- }
- template <typename T, typename ...Ts>
- bool bsearch_impl (const T &x, unsigned *pos, Ts... ds) const
- {
- return hb_bsearch_impl (pos,
- x,
- this->arrayZ,
- this->length,
- sizeof (Type),
- _hb_cmp_method<T, Type, Ts...>,
- std::forward<Ts> (ds)...);
- }
-};
-template <typename T> inline hb_sorted_array_t<T>
-hb_sorted_array (T *array, unsigned int length)
-{ return hb_sorted_array_t<T> (array, length); }
-template <typename T, unsigned int length_> inline hb_sorted_array_t<T>
-hb_sorted_array (T (&array_)[length_])
-{ return hb_sorted_array_t<T> (array_); }
-
-template <typename T>
-inline bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
-{
- if (o.length != this->length) return false;
- for (unsigned int i = 0; i < this->length; i++) {
- if (this->arrayZ[i] != o.arrayZ[i]) return false;
- }
- return true;
-}
-template <>
-inline bool hb_array_t<const char>::operator == (const hb_array_t<const char> &o) const
-{
- if (o.length != this->length) return false;
- return 0 == hb_memcmp (arrayZ, o.arrayZ, length);
-}
-template <>
-inline bool hb_array_t<const unsigned char>::operator == (const hb_array_t<const unsigned char> &o) const
-{
- if (o.length != this->length) return false;
- return 0 == hb_memcmp (arrayZ, o.arrayZ, length);
-}
-
-
-/* Specialize hash() for byte arrays. */
-
-template <>
-inline uint32_t hb_array_t<const char>::hash () const
-{
- uint32_t current = 0;
- unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
- ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
- struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
- for (; i + 4 <= this->length; i += 4)
- current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
- for (; i < this->length; i++)
- current = current * 31 + hb_hash (this->arrayZ[i]);
- return current;
-}
-
-template <>
-inline uint32_t hb_array_t<const unsigned char>::hash () const
-{
- uint32_t current = 0;
- unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
- ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
- struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
- for (; i + 4 <= this->length; i += 4)
- current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
- for (; i < this->length; i++)
- current = current * 31 + hb_hash (this->arrayZ[i]);
- return current;
-}
-
-
-typedef hb_array_t<const char> hb_bytes_t;
-typedef hb_array_t<const unsigned char> hb_ubytes_t;
-
-
-
-#endif /* HB_ARRAY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
new file mode 100644
index 00000000000..93438401400
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Contributor(s):
+ * Chris Wilson <[email protected]>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ATOMIC_PRIVATE_HH
+#define HB_ATOMIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* atomic_int */
+
+/* We need external help for these */
+
+#if defined(hb_atomic_int_impl_add) \
+ && defined(hb_atomic_ptr_impl_get) \
+ && defined(hb_atomic_ptr_impl_cmpexch)
+
+/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
+
+
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#include <windows.h>
+
+/* MinGW has a convoluted history of supporting MemoryBarrier
+ * properly. As such, define a function to wrap the whole
+ * thing. */
+static inline void _HBMemoryBarrier (void) {
+#if !defined(MemoryBarrier)
+ long dummy = 0;
+ InterlockedExchange (&dummy, 1);
+#else
+ MemoryBarrier ();
+#endif
+}
+
+typedef LONG hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
+
+#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
+
+
+#elif !defined(HB_NO_MT) && defined(__APPLE__)
+
+#include <libkern/OSAtomic.h>
+#ifdef __MAC_OS_X_MIN_REQUIRED
+#include <AvailabilityMacros.h>
+#elif defined(__IPHONE_OS_MIN_REQUIRED)
+#include <Availability.h>
+#endif
+
+
+typedef int32_t hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
+
+#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P))
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
+#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) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P))
+#else
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P))
+#endif
+#endif
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+
+typedef int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
+
+#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
+
+#include <atomic.h>
+#include <mbarrier.h>
+
+typedef unsigned int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
+
+
+#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
+
+#include <builtins.h>
+
+
+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) {
+ __sync();
+ int result = __compare_and_swaplp (P, &O, N);
+ __sync();
+ return result;
+}
+
+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_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))
+
+#elif !defined(HB_NO_MT)
+
+#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
+
+typedef volatile int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
+
+
+#endif
+
+
+#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)}
+
+struct hb_atomic_int_t
+{
+ hb_atomic_int_impl_t v;
+
+ inline void set_unsafe (int v_) { v = v_; }
+ inline int get_unsafe (void) const { return v; }
+ inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); }
+ inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); }
+};
+
+
+#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
+#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
+
+
+#endif /* HB_ATOMIC_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh
deleted file mode 100644
index a6283de1408..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright © 2007 Chris Wilson
- * Copyright © 2009,2010 Red Hat, Inc.
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Contributor(s):
- * Chris Wilson <[email protected]>
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_ATOMIC_HH
-#define HB_ATOMIC_HH
-
-#include "hb.hh"
-#include "hb-meta.hh"
-
-
-/*
- * Atomic integers and pointers.
- */
-
-
-/* We need external help for these */
-
-#if defined(hb_atomic_int_impl_add) \
- && defined(hb_atomic_ptr_impl_get) \
- && defined(hb_atomic_ptr_impl_cmpexch)
-
-/* Defined externally, i.e. in config.h. */
-
-
-#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
-
-/* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */
-
-#define _hb_memory_barrier() __sync_synchronize ()
-
-#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
-#define hb_atomic_int_impl_set_relaxed(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
-#define hb_atomic_int_impl_set(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELEASE)
-#define hb_atomic_int_impl_get_relaxed(AI) __atomic_load_n ((AI), __ATOMIC_RELAXED)
-#define hb_atomic_int_impl_get(AI) __atomic_load_n ((AI), __ATOMIC_ACQUIRE)
-
-#define hb_atomic_ptr_impl_set_relaxed(P, V) __atomic_store_n ((P), (V), __ATOMIC_RELAXED)
-#define hb_atomic_ptr_impl_get_relaxed(P) __atomic_load_n ((P), __ATOMIC_RELAXED)
-#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_ACQUIRE)
-static inline bool
-_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
-{
- const void *O = O_; // Need lvalue
- return __atomic_compare_exchange_n ((void **) P, (void **) &O, (void *) N, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
-}
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
-
-
-#elif !defined(HB_NO_MT)
-
-/* C++11 atomics. */
-
-#include <atomic>
-
-#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel)
-#define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire)
-#define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release)
-
-#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
-#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_relaxed))
-#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_release))
-#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_relaxed))
-#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_acquire))
-
-#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
-#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast<std::atomic<void*> const *> (P)->load (std::memory_order_relaxed))
-#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
-static inline bool
-_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
-{
- const void *O = O_; // Need lvalue
- return reinterpret_cast<std::atomic<const void*> *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed);
-}
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
-
-
-#else /* defined(HB_NO_MT) */
-
-#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
-#define _hb_memory_barrier() do {} while (0)
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
-
-#endif
-
-
-/* This should never be disabled, even under HB_NO_MT.
- * except that MSVC gives me an internal compiler error, so disabled there.
- *
- * https://github.com/harfbuzz/harfbuzz/pull/4119
- */
-#ifndef _hb_compiler_memory_r_barrier
-#if defined(__ATOMIC_ACQUIRE) // gcc-like
-#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory")
-#elif !defined(_MSC_VER)
-#include <atomic>
-#define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire)
-#else
-#define _hb_compiler_memory_r_barrier() do {} while (0)
-#endif
-#endif
-
-
-
-#ifndef _hb_memory_r_barrier
-#define _hb_memory_r_barrier() _hb_memory_barrier ()
-#endif
-#ifndef _hb_memory_w_barrier
-#define _hb_memory_w_barrier() _hb_memory_barrier ()
-#endif
-#ifndef hb_atomic_int_impl_set_relaxed
-#define hb_atomic_int_impl_set_relaxed(AI, V) (*(AI) = (V))
-#endif
-#ifndef hb_atomic_int_impl_get_relaxed
-#define hb_atomic_int_impl_get_relaxed(AI) (*(AI))
-#endif
-
-#ifndef hb_atomic_ptr_impl_set_relaxed
-#define hb_atomic_ptr_impl_set_relaxed(P, V) (*(P) = (V))
-#endif
-#ifndef hb_atomic_ptr_impl_get_relaxed
-#define hb_atomic_ptr_impl_get_relaxed(P) (*(P))
-#endif
-#ifndef hb_atomic_int_impl_set
-inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; }
-inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; }
-#endif
-#ifndef hb_atomic_int_impl_get
-inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; }
-inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; }
-#endif
-#ifndef hb_atomic_ptr_impl_get
-inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; }
-#endif
-
-
-struct hb_atomic_short_t
-{
- hb_atomic_short_t () = default;
- constexpr hb_atomic_short_t (short v) : v (v) {}
-
- hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; }
- operator short () const { return get_relaxed (); }
-
- void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
- void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); }
- short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
- short get_acquire () const { return hb_atomic_int_impl_get (&v); }
- short inc () { return hb_atomic_int_impl_add (&v, 1); }
- short dec () { return hb_atomic_int_impl_add (&v, -1); }
-
- short v = 0;
-};
-
-struct hb_atomic_int_t
-{
- hb_atomic_int_t () = default;
- constexpr hb_atomic_int_t (int v) : v (v) {}
-
- hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; }
- operator int () const { return get_relaxed (); }
-
- void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
- void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); }
- int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
- int get_acquire () const { return hb_atomic_int_impl_get (&v); }
- int inc () { return hb_atomic_int_impl_add (&v, 1); }
- int dec () { return hb_atomic_int_impl_add (&v, -1); }
-
- int v = 0;
-};
-
-template <typename P>
-struct hb_atomic_ptr_t
-{
- typedef hb_remove_pointer<P> T;
-
- hb_atomic_ptr_t () = default;
- constexpr hb_atomic_ptr_t (T* v) : v (v) {}
-
- void init (T* v_ = nullptr) { set_relaxed (v_); }
- void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
- T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); }
- T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); }
- bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); }
-
- T * operator -> () const { return get_acquire (); }
- template <typename C> operator C * () const { return get_acquire (); }
-
- T *v = nullptr;
-};
-
-
-#endif /* HB_ATOMIC_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh b/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh
deleted file mode 100644
index 9edefd97106..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-bimap.hh
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright © 2019 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_BIMAP_HH
-#define HB_BIMAP_HH
-
-#include "hb.hh"
-#include "hb-map.hh"
-
-/* Bi-directional map */
-struct hb_bimap_t
-{
- void reset ()
- {
- forw_map.reset ();
- back_map.reset ();
- }
-
- void resize (unsigned pop)
- {
- forw_map.resize (pop);
- back_map.resize (pop);
- }
-
- bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
-
- void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
- {
- if (in_error ()) return;
- if (unlikely (lhs == HB_MAP_VALUE_INVALID)) return;
- if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; }
-
- forw_map.set (lhs, rhs);
- if (unlikely (in_error ())) return;
-
- back_map.set (rhs, lhs);
- if (unlikely (in_error ())) forw_map.del (lhs);
- }
-
- hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
- hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
-
- hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
- bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
-
-
- void del (hb_codepoint_t lhs)
- {
- back_map.del (get (lhs));
- forw_map.del (lhs);
- }
-
- void clear ()
- {
- forw_map.clear ();
- back_map.clear ();
- }
-
- bool is_empty () const { return forw_map.is_empty (); }
-
- unsigned int get_population () const { return forw_map.get_population (); }
-
-
- protected:
- hb_map_t forw_map;
- hb_map_t back_map;
-
- public:
- auto keys () const HB_AUTO_RETURN (+ forw_map.keys())
- auto values () const HB_AUTO_RETURN (+ forw_map.values())
- auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
-};
-
-/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
-struct hb_inc_bimap_t : hb_bimap_t
-{
- /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
- * Return the rhs value as the result.
- */
- hb_codepoint_t add (hb_codepoint_t lhs)
- {
- hb_codepoint_t rhs = forw_map[lhs];
- if (rhs == HB_MAP_VALUE_INVALID)
- {
- rhs = next_value++;
- set (lhs, rhs);
- }
- return rhs;
- }
-
- hb_codepoint_t skip ()
- { return next_value++; }
-
- hb_codepoint_t skip (unsigned count)
- { return next_value += count; }
-
- hb_codepoint_t get_next_value () const
- { return next_value; }
-
- void add_set (const hb_set_t *set)
- {
- hb_codepoint_t i = HB_SET_VALUE_INVALID;
- while (hb_set_next (set, &i)) add (i);
- }
-
- /* Create an identity map. */
- bool identity (unsigned int size)
- {
- clear ();
- for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
- return !in_error ();
- }
-
- protected:
- static int cmp_id (const void* a, const void* b)
- { return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
-
- public:
- /* Optional: after finished adding all mappings in a random order,
- * reassign rhs to lhs so that they are in the same order. */
- void sort ()
- {
- hb_codepoint_t count = get_population ();
- hb_vector_t <hb_codepoint_t> work;
- work.resize (count);
-
- for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
- work[rhs] = back_map[rhs];
-
- work.qsort (cmp_id);
-
- clear ();
- for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
- set (work[rhs], rhs);
- }
-
- protected:
- unsigned int next_value = 0;
-};
-
-#endif /* HB_BIMAP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh
deleted file mode 100644
index 9b027ac5905..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright © 2012,2017 Google, Inc.
- * Copyright © 2021 Behdad Esfahbod
- *
- * 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_BIT_PAGE_HH
-#define HB_BIT_PAGE_HH
-
-#include "hb.hh"
-
-
-/* Compiler-assisted vectorization. */
-
-/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * basically a fixed-size bitset. We can't use the compiler type because hb_vector_t cannot
- * guarantee alignment requirements. */
-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]; }
-
- void init0 ()
- {
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- v[i] = 0;
- }
- void init1 ()
- {
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- v[i] = (elt_t) -1;
- }
-
- template <typename Op>
- hb_vector_size_t process (const Op& op) const
- {
- hb_vector_size_t r;
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- r.v[i] = op (v[i]);
- return r;
- }
- template <typename Op>
- hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
- {
- hb_vector_size_t r;
- for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
- r.v[i] = op (v[i], o.v[i]);
- return r;
- }
- hb_vector_size_t operator | (const hb_vector_size_t &o) const
- { return process (hb_bitwise_or, o); }
- hb_vector_size_t operator & (const hb_vector_size_t &o) const
- { return process (hb_bitwise_and, o); }
- hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
- { return process (hb_bitwise_xor, o); }
- hb_vector_size_t operator ~ () const
- { return process (hb_bitwise_neg); }
-
- hb_array_t<const elt_t> iter () const
- { return hb_array (v); }
-
- private:
- static_assert (0 == byte_size % sizeof (elt_t), "");
- elt_t v[byte_size / sizeof (elt_t)];
-};
-
-
-struct hb_bit_page_t
-{
- void init0 () { v.init0 (); }
- void init1 () { v.init1 (); }
-
- static inline constexpr unsigned len ()
- { return ARRAY_LENGTH_CONST (v); }
-
- bool is_empty () const
- {
- return
- + hb_iter (v)
- | hb_none
- ;
- }
- uint32_t hash () const
- {
- return
- + hb_iter (v)
- | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u)
- ;
- }
-
- void add (hb_codepoint_t g) { elt (g) |= mask (g); }
- void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
- void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
- bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
-
- 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++;
-
- hb_memset (la, 0xff, (char *) lb - (char *) la);
-
- *lb |= ((mask (b) << 1) - 1);
- }
- }
- void del_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++;
-
- hb_memset (la, 0, (char *) lb - (char *) la);
-
- *lb &= ~((mask (b) << 1) - 1);
- }
- }
- void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
- { if (v) add_range (a, b); else del_range (a, b); }
-
-
- // Writes out page values to the array p. Returns the number of values
- // written. At most size codepoints will be written.
- unsigned int write (uint32_t base,
- unsigned int start_value,
- hb_codepoint_t *p,
- unsigned int size) const
- {
- unsigned int start_v = start_value / ELT_BITS;
- unsigned int start_bit = start_value & ELT_MASK;
- unsigned int count = 0;
- for (unsigned i = start_v; i < len () && count < size; i++)
- {
- elt_t bits = v[i];
- uint32_t v_base = base | (i * ELT_BITS);
- for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
- {
- if ((elt_t(1) << j) & bits) {
- *p++ = v_base | j;
- count++;
- }
- }
- start_bit = 0;
- }
- return count;
- }
-
- // Writes out the values NOT in this page to the array p. Returns the
- // number of values written. At most size codepoints will be written.
- // Returns the number of codepoints written. next_value holds the next value
- // that should be written (if not present in this page). This is used to fill
- // any missing value gaps between this page and the previous page, if any.
- // next_value is updated to one more than the last value present in this page.
- unsigned int write_inverted (uint32_t base,
- unsigned int start_value,
- hb_codepoint_t *p,
- unsigned int size,
- hb_codepoint_t *next_value) const
- {
- unsigned int start_v = start_value / ELT_BITS;
- unsigned int start_bit = start_value & ELT_MASK;
- unsigned int count = 0;
- for (unsigned i = start_v; i < len () && count < size; i++)
- {
- elt_t bits = v[i];
- uint32_t v_offset = i * ELT_BITS;
- for (unsigned int j = start_bit; j < ELT_BITS && count < size; j++)
- {
- if ((elt_t(1) << j) & bits)
- {
- hb_codepoint_t value = base | v_offset | j;
- // Emit all the missing values from next_value up to value - 1.
- for (hb_codepoint_t k = *next_value; k < value && count < size; k++)
- {
- *p++ = k;
- count++;
- }
- // Skip over this value;
- *next_value = value + 1;
- }
- }
- start_bit = 0;
- }
- return count;
- }
-
- bool is_equal (const hb_bit_page_t &other) const
- {
- for (unsigned i = 0; i < len (); i++)
- if (v[i] != other.v[i])
- return false;
- return true;
- }
- bool is_subset (const hb_bit_page_t &larger_page) const
- {
- for (unsigned i = 0; i < len (); i++)
- if (~larger_page.v[i] & v[i])
- return false;
- return true;
- }
-
- unsigned int get_population () const
- {
- return
- + hb_iter (v)
- | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
- ;
- }
-
- 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;
-
- const elt_t vv = v[i] & ~((elt_t (1) << j) - 1);
- for (const elt_t *p = &vv; i < len (); p = &v[++i])
- if (*p)
- {
- *codepoint = i * ELT_BITS + elt_get_min (*p);
- return true;
- }
-
- *codepoint = INVALID;
- return false;
- }
- bool previous (hb_codepoint_t *codepoint) const
- {
- unsigned int m = (*codepoint - 1) & MASK;
- if (m == MASK)
- {
- *codepoint = INVALID;
- return false;
- }
- unsigned int i = m / ELT_BITS;
- unsigned int j = m & ELT_MASK;
-
- /* Fancy mask to avoid shifting by elt_t bitsize, which is undefined. */
- const elt_t mask = j < 8 * sizeof (elt_t) - 1 ?
- ((elt_t (1) << (j + 1)) - 1) :
- (elt_t) -1;
- const elt_t vv = v[i] & mask;
- const elt_t *p = &vv;
- while (true)
- {
- if (*p)
- {
- *codepoint = i * ELT_BITS + elt_get_max (*p);
- return true;
- }
- if ((int) i <= 0) break;
- p = &v[--i];
- }
-
- *codepoint = INVALID;
- return false;
- }
- hb_codepoint_t get_min () const
- {
- for (unsigned int i = 0; i < len (); i++)
- if (v[i])
- return i * ELT_BITS + elt_get_min (v[i]);
- return INVALID;
- }
- hb_codepoint_t get_max () const
- {
- for (int i = len () - 1; i >= 0; i--)
- if (v[i])
- return i * ELT_BITS + elt_get_max (v[i]);
- return 0;
- }
-
- static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
-
- typedef unsigned long long elt_t;
- static constexpr unsigned PAGE_BITS_LOG_2 = 9; // 512 bits
- static constexpr unsigned PAGE_BITS = 1 << PAGE_BITS_LOG_2;
- static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, "");
- static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
- static constexpr unsigned PAGE_BITMASK = PAGE_BITS - 1;
-
- static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); }
- static unsigned int elt_get_max (const elt_t &elt) { return hb_bit_storage (elt) - 1; }
-
- typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
-
- static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8;
- static constexpr unsigned ELT_MASK = ELT_BITS - 1;
-
- static constexpr unsigned BITS = sizeof (vector_t) * 8;
- static constexpr unsigned MASK = BITS - 1;
- static_assert ((unsigned) PAGE_BITS == (unsigned) BITS, "");
-
- elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; }
- const elt_t& elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
- static constexpr elt_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); }
-
- vector_t v;
-};
-static_assert (hb_bit_page_t::PAGE_BITS == sizeof (hb_bit_page_t) * 8, "");
-
-
-#endif /* HB_BIT_PAGE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh
deleted file mode 100644
index 1eb1b1c2092..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set-invertible.hh
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright © 2012,2017 Google, Inc.
- * Copyright © 2021 Behdad Esfahbod
- *
- * 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_BIT_SET_INVERTIBLE_HH
-#define HB_BIT_SET_INVERTIBLE_HH
-
-#include "hb.hh"
-#include "hb-bit-set.hh"
-
-
-struct hb_bit_set_invertible_t
-{
- hb_bit_set_t s;
- bool inverted = false;
-
- hb_bit_set_invertible_t () = default;
- hb_bit_set_invertible_t (const hb_bit_set_invertible_t& o) = default;
- hb_bit_set_invertible_t (hb_bit_set_invertible_t&& other) : hb_bit_set_invertible_t () { hb_swap (*this, other); }
- hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default;
- hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& other) { hb_swap (*this, other); return *this; }
- friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b)
- {
- if (likely (!a.s.successful || !b.s.successful))
- return;
- hb_swap (a.inverted, b.inverted);
- hb_swap (a.s, b.s);
- }
-
- void init () { s.init (); inverted = false; }
- void fini () { s.fini (); }
- void err () { s.err (); }
- bool in_error () const { return s.in_error (); }
- explicit operator bool () const { return !is_empty (); }
-
- void alloc (unsigned sz) { s.alloc (sz); }
- void reset ()
- {
- s.reset ();
- inverted = false;
- }
- void clear ()
- {
- s.clear ();
- if (likely (s.successful))
- inverted = false;
- }
- void invert ()
- {
- if (likely (s.successful))
- inverted = !inverted;
- }
-
- bool is_inverted () const
- {
- return inverted;
- }
-
- bool is_empty () const
- {
- hb_codepoint_t v = INVALID;
- next (&v);
- return v == INVALID;
- }
- uint32_t hash () const { return s.hash () ^ (uint32_t) inverted; }
-
- hb_codepoint_t get_min () const
- {
- hb_codepoint_t v = INVALID;
- next (&v);
- return v;
- }
- hb_codepoint_t get_max () const
- {
- hb_codepoint_t v = INVALID;
- previous (&v);
- return v;
- }
- unsigned int get_population () const
- { return inverted ? INVALID - s.get_population () : s.get_population (); }
-
-
- void add (hb_codepoint_t g) { unlikely (inverted) ? s.del (g) : s.add (g); }
- bool add_range (hb_codepoint_t a, hb_codepoint_t b)
- { return unlikely (inverted) ? ((void) s.del_range (a, b), true) : s.add_range (a, b); }
-
- template <typename T>
- void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { inverted ? s.del_array (array, count, stride) : s.add_array (array, count, stride); }
- template <typename T>
- void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename T>
- bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { return inverted ? s.del_sorted_array (array, count, stride) : s.add_sorted_array (array, count, stride); }
- template <typename T>
- bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
-
- void del (hb_codepoint_t g) { unlikely (inverted) ? s.add (g) : s.del (g); }
- void del_range (hb_codepoint_t a, hb_codepoint_t b)
- { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); }
-
- bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; }
-
- /* Has interface. */
- bool operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k]; }
- /* Predicate. */
- bool operator () (hb_codepoint_t k) const { return has (k); }
-
- /* Sink interface. */
- hb_bit_set_invertible_t& operator << (hb_codepoint_t v)
- { add (v); return *this; }
- hb_bit_set_invertible_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
- { add_range (range.first, range.second); return *this; }
-
- bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
- {
- hb_codepoint_t c = first - 1;
- return next (&c) && c <= last;
- }
-
- void set (const hb_bit_set_invertible_t &other)
- {
- s.set (other.s);
- if (likely (s.successful))
- inverted = other.inverted;
- }
-
- bool is_equal (const hb_bit_set_invertible_t &other) const
- {
- if (likely (inverted == other.inverted))
- return s.is_equal (other.s);
- else
- {
- /* TODO Add iter_ranges() and use here. */
- auto it1 = iter ();
- auto it2 = other.iter ();
- return hb_all (+ hb_zip (it1, it2)
- | hb_map ([](hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return _.first == _.second; }));
- }
- }
-
- bool is_subset (const hb_bit_set_invertible_t &larger_set) const
- {
- if (unlikely (inverted != larger_set.inverted))
- return hb_all (hb_iter (s) | hb_map (larger_set.s));
- else
- return unlikely (inverted) ? larger_set.s.is_subset (s) : s.is_subset (larger_set.s);
- }
-
- protected:
- template <typename Op>
- void process (const Op& op, const hb_bit_set_invertible_t &other)
- { s.process (op, other.s); }
- public:
- void union_ (const hb_bit_set_invertible_t &other)
- {
- if (likely (inverted == other.inverted))
- {
- if (unlikely (inverted))
- process (hb_bitwise_and, other);
- else
- process (hb_bitwise_or, other); /* Main branch. */
- }
- else
- {
- if (unlikely (inverted))
- process (hb_bitwise_gt, other);
- else
- process (hb_bitwise_lt, other);
- }
- if (likely (s.successful))
- inverted = inverted || other.inverted;
- }
- void intersect (const hb_bit_set_invertible_t &other)
- {
- if (likely (inverted == other.inverted))
- {
- if (unlikely (inverted))
- process (hb_bitwise_or, other);
- else
- process (hb_bitwise_and, other); /* Main branch. */
- }
- else
- {
- if (unlikely (inverted))
- process (hb_bitwise_lt, other);
- else
- process (hb_bitwise_gt, other);
- }
- if (likely (s.successful))
- inverted = inverted && other.inverted;
- }
- void subtract (const hb_bit_set_invertible_t &other)
- {
- if (likely (inverted == other.inverted))
- {
- if (unlikely (inverted))
- process (hb_bitwise_lt, other);
- else
- process (hb_bitwise_gt, other); /* Main branch. */
- }
- else
- {
- if (unlikely (inverted))
- process (hb_bitwise_or, other);
- else
- process (hb_bitwise_and, other);
- }
- if (likely (s.successful))
- inverted = inverted && !other.inverted;
- }
- void symmetric_difference (const hb_bit_set_invertible_t &other)
- {
- process (hb_bitwise_xor, other);
- if (likely (s.successful))
- inverted = inverted ^ other.inverted;
- }
-
- bool next (hb_codepoint_t *codepoint) const
- {
- if (likely (!inverted))
- return s.next (codepoint);
-
- auto old = *codepoint;
- if (unlikely (old + 1 == INVALID))
- {
- *codepoint = INVALID;
- return false;
- }
-
- auto v = old;
- s.next (&v);
- if (old + 1 < v)
- {
- *codepoint = old + 1;
- return true;
- }
-
- v = old;
- s.next_range (&old, &v);
-
- *codepoint = v + 1;
- return *codepoint != INVALID;
- }
- bool previous (hb_codepoint_t *codepoint) const
- {
- if (likely (!inverted))
- return s.previous (codepoint);
-
- auto old = *codepoint;
- if (unlikely (old - 1 == INVALID))
- {
- *codepoint = INVALID;
- return false;
- }
-
- auto v = old;
- s.previous (&v);
-
- if (old - 1 > v || v == INVALID)
- {
- *codepoint = old - 1;
- return true;
- }
-
- v = old;
- s.previous_range (&v, &old);
-
- *codepoint = v - 1;
- return *codepoint != INVALID;
- }
- bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- {
- if (likely (!inverted))
- return s.next_range (first, last);
-
- if (!next (last))
- {
- *last = *first = INVALID;
- return false;
- }
-
- *first = *last;
- s.next (last);
- --*last;
- return true;
- }
- bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- {
- if (likely (!inverted))
- return s.previous_range (first, last);
-
- if (!previous (first))
- {
- *last = *first = INVALID;
- return false;
- }
-
- *last = *first;
- s.previous (first);
- ++*first;
- return true;
- }
-
- unsigned int next_many (hb_codepoint_t codepoint,
- hb_codepoint_t *out,
- unsigned int size) const
- {
- return inverted ? s.next_many_inverted (codepoint, out, size)
- : s.next_many (codepoint, out, size);
- }
-
- static constexpr hb_codepoint_t INVALID = hb_bit_set_t::INVALID;
-
- /*
- * Iterator implementation.
- */
- struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
- {
- static constexpr bool is_sorted_iterator = true;
- iter_t (const hb_bit_set_invertible_t &s_ = Null (hb_bit_set_invertible_t),
- bool init = true) : s (&s_), v (INVALID), l(0)
- {
- if (init)
- {
- l = s->get_population () + 1;
- __next__ ();
- }
- }
-
- typedef hb_codepoint_t __item_t__;
- hb_codepoint_t __item__ () const { return v; }
- bool __more__ () const { return v != INVALID; }
- void __next__ () { s->next (&v); if (l) l--; }
- void __prev__ () { s->previous (&v); }
- unsigned __len__ () const { return l; }
- iter_t end () const { return iter_t (*s, false); }
- bool operator != (const iter_t& o) const
- { return s != o.s || v != o.v; }
-
- protected:
- const hb_bit_set_invertible_t *s;
- hb_codepoint_t v;
- unsigned l;
- };
- iter_t iter () const { return iter_t (*this); }
- operator iter_t () const { return iter (); }
-};
-
-
-#endif /* HB_BIT_SET_INVERTIBLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh
deleted file mode 100644
index c30b2af7b0d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * Copyright © 2012,2017 Google, Inc.
- * Copyright © 2021 Behdad Esfahbod
- *
- * 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_BIT_SET_HH
-#define HB_BIT_SET_HH
-
-#include "hb.hh"
-#include "hb-bit-page.hh"
-#include "hb-machinery.hh"
-
-
-struct hb_bit_set_t
-{
- hb_bit_set_t () = default;
- ~hb_bit_set_t () = default;
-
- hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); }
- hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); }
- hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; }
- hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; }
- friend void swap (hb_bit_set_t &a, hb_bit_set_t &b)
- {
- if (likely (!a.successful || !b.successful))
- return;
- hb_swap (a.population, b.population);
- hb_swap (a.last_page_lookup, b.last_page_lookup);
- hb_swap (a.page_map, b.page_map);
- hb_swap (a.pages, b.pages);
- }
-
- void init ()
- {
- successful = true;
- population = 0;
- last_page_lookup = 0;
- page_map.init ();
- pages.init ();
- }
- void fini ()
- {
- page_map.fini ();
- pages.fini ();
- }
-
- using page_t = hb_bit_page_t;
- struct page_map_t
- {
- int cmp (const page_map_t &o) const { return cmp (o.major); }
- int cmp (uint32_t o_major) const { return (int) o_major - (int) major; }
-
- uint32_t major;
- uint32_t index;
- };
-
- bool successful = true; /* Allocations successful */
- mutable unsigned int population = 0;
- mutable hb_atomic_int_t last_page_lookup = 0;
- hb_sorted_vector_t<page_map_t> page_map;
- hb_vector_t<page_t> pages;
-
- void err () { if (successful) successful = false; } /* TODO Remove */
- bool in_error () const { return !successful; }
-
- bool resize (unsigned int count, bool clear = true, bool exact_size = false)
- {
- if (unlikely (!successful)) return false;
-
- if (pages.length == 0 && count == 1)
- exact_size = true; // Most sets are small and local
-
- if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size)))
- {
- pages.resize (page_map.length, clear, exact_size);
- successful = false;
- return false;
- }
- return true;
- }
-
- void alloc (unsigned sz)
- {
- sz >>= (page_t::PAGE_BITS_LOG_2 - 1);
- pages.alloc (sz);
- page_map.alloc (sz);
- }
-
- void reset ()
- {
- successful = true;
- clear ();
- }
-
- void clear ()
- {
- resize (0);
- if (likely (successful))
- population = 0;
- }
- bool is_empty () const
- {
- unsigned int count = pages.length;
- for (unsigned int i = 0; i < count; i++)
- if (!pages[i].is_empty ())
- return false;
- return true;
- }
- explicit operator bool () const { return !is_empty (); }
-
- uint32_t hash () const
- {
- uint32_t h = 0;
- for (auto &map : page_map)
- h = h * 31 + hb_hash (map.major) + hb_hash (pages[map.index]);
- return h;
- }
-
- private:
- void dirty () { population = UINT_MAX; }
- public:
-
- void add (hb_codepoint_t g)
- {
- if (unlikely (!successful)) return;
- if (unlikely (g == INVALID)) return;
- dirty ();
- page_t *page = page_for (g, true); if (unlikely (!page)) return;
- page->add (g);
- }
- bool add_range (hb_codepoint_t a, hb_codepoint_t b)
- {
- if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
- if (unlikely (a > b || a == INVALID || b == INVALID)) return false;
- dirty ();
- unsigned int ma = get_major (a);
- unsigned int mb = get_major (b);
- if (ma == mb)
- {
- page_t *page = page_for (a, true); if (unlikely (!page)) return false;
- page->add_range (a, b);
- }
- else
- {
- page_t *page = page_for (a, true); 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 (major_start (m), true); if (unlikely (!page)) return false;
- page->init1 ();
- }
-
- page = page_for (b, true); if (unlikely (!page)) return false;
- page->add_range (major_start (mb), b);
- }
- return true;
- }
-
- template <typename T>
- void set_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
- {
- if (unlikely (!successful)) return;
- if (!count) return;
- dirty ();
- hb_codepoint_t g = *array;
- while (count)
- {
- unsigned int m = get_major (g);
- page_t *page = page_for (g, v); if (unlikely (v && !page)) return;
- unsigned int start = major_start (m);
- unsigned int end = major_start (m + 1);
- do
- {
- if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
- page->set (g, v);
-
- array = &StructAtOffsetUnaligned<T> (array, stride);
- count--;
- }
- while (count && (g = *array, start <= g && g < end));
- }
- }
-
- template <typename T>
- void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { set_array (true, array, count, stride); }
- template <typename T>
- void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
-
- template <typename T>
- void del_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { set_array (false, array, count, stride); }
- template <typename T>
- void del_array (const hb_array_t<const T>& arr) { del_array (&arr, arr.len ()); }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename T>
- bool set_sorted_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
- {
- if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
- if (unlikely (!count)) return true;
- dirty ();
- hb_codepoint_t g = *array;
- hb_codepoint_t last_g = g;
- while (count)
- {
- unsigned int m = get_major (g);
- page_t *page = page_for (g, v); if (unlikely (v && !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;
-
- if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
- page->add (g);
-
- array = &StructAtOffsetUnaligned<T> (array, stride);
- count--;
- }
- while (count && (g = *array, g < end));
- }
- return true;
- }
-
- template <typename T>
- bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { return set_sorted_array (true, array, count, stride); }
- template <typename T>
- bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
-
- template <typename T>
- bool del_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { return set_sorted_array (false, array, count, stride); }
- template <typename T>
- bool del_sorted_array (const hb_sorted_array_t<const T>& arr) { return del_sorted_array (&arr, arr.len ()); }
-
- void del (hb_codepoint_t g)
- {
- if (unlikely (!successful)) return;
- page_t *page = page_for (g);
- if (!page)
- return;
- dirty ();
- page->del (g);
- }
-
- private:
- void del_pages (int ds, int de)
- {
- if (ds <= de)
- {
- // Pre-allocate the workspace that compact() will need so we can bail on allocation failure
- // before attempting to rewrite the page map.
- hb_vector_t<unsigned> compact_workspace;
- if (unlikely (!allocate_compact_workspace (compact_workspace))) return;
-
- unsigned int write_index = 0;
- for (unsigned int i = 0; i < page_map.length; i++)
- {
- int m = (int) page_map[i].major;
- if (m < ds || de < m)
- page_map[write_index++] = page_map[i];
- }
- compact (compact_workspace, write_index);
- resize (write_index);
- }
- }
-
-
- public:
- void del_range (hb_codepoint_t a, hb_codepoint_t b)
- {
- if (unlikely (!successful)) return;
- if (unlikely (a > b || a == INVALID)) return;
- dirty ();
- unsigned int ma = get_major (a);
- unsigned int mb = get_major (b);
- /* Delete pages from ds through de if ds <= de. */
- int ds = (a == major_start (ma))? (int) ma: (int) (ma + 1);
- int de = (b + 1 == major_start (mb + 1))? (int) mb: ((int) mb - 1);
- if (ds > de || (int) ma < ds)
- {
- page_t *page = page_for (a);
- if (page)
- {
- if (ma == mb)
- page->del_range (a, b);
- else
- page->del_range (a, major_start (ma + 1) - 1);
- }
- }
- if (de < (int) mb && ma != mb)
- {
- page_t *page = page_for (b);
- if (page)
- page->del_range (major_start (mb), b);
- }
- del_pages (ds, de);
- }
-
- bool get (hb_codepoint_t g) const
- {
- const page_t *page = page_for (g);
- if (!page)
- return false;
- return page->get (g);
- }
-
- /* Has interface. */
- bool operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k]; }
- /* Predicate. */
- bool operator () (hb_codepoint_t k) const { return has (k); }
-
- /* Sink interface. */
- hb_bit_set_t& operator << (hb_codepoint_t v)
- { add (v); return *this; }
- hb_bit_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
- { add_range (range.first, range.second); return *this; }
-
- bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
- {
- hb_codepoint_t c = first - 1;
- return next (&c) && c <= last;
- }
- void set (const hb_bit_set_t &other, bool exact_size = false)
- {
- if (unlikely (!successful)) return;
- unsigned int count = other.pages.length;
- if (unlikely (!resize (count, false, exact_size)))
- return;
- population = other.population;
-
- page_map = other.page_map;
- pages = other.pages;
- }
-
- bool is_equal (const hb_bit_set_t &other) const
- {
- if (has_population () && other.has_population () &&
- population != other.population)
- return false;
-
- unsigned int na = pages.length;
- unsigned int nb = other.pages.length;
-
- 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;
- }
-
- bool is_subset (const hb_bit_set_t &larger_set) const
- {
- if (has_population () && larger_set.has_population () &&
- population > larger_set.population)
- return false;
-
- uint32_t spi = 0;
- for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++)
- {
- uint32_t spm = page_map[spi].major;
- uint32_t lpm = larger_set.page_map[lpi].major;
- auto sp = page_at (spi);
- auto lp = larger_set.page_at (lpi);
-
- if (spm < lpm && !sp.is_empty ())
- return false;
-
- if (lpm < spm)
- continue;
-
- if (!sp.is_subset (lp))
- return false;
-
- spi++;
- }
-
- while (spi < page_map.length)
- if (!page_at (spi++).is_empty ())
- return false;
-
- return true;
- }
-
- private:
- bool allocate_compact_workspace (hb_vector_t<unsigned>& workspace)
- {
- if (unlikely (!workspace.resize_exact (pages.length)))
- {
- successful = false;
- return false;
- }
-
- return true;
- }
-
- /*
- * workspace should be a pre-sized vector allocated to hold at exactly pages.length
- * elements.
- */
- void compact (hb_vector_t<unsigned>& workspace,
- unsigned int length)
- {
- assert(workspace.length == pages.length);
- hb_vector_t<unsigned>& old_index_to_page_map_index = workspace;
-
- hb_fill (old_index_to_page_map_index.writer(), 0xFFFFFFFF);
- for (unsigned i = 0; i < length; i++)
- old_index_to_page_map_index[page_map[i].index] = i;
-
- compact_pages (old_index_to_page_map_index);
- }
- void compact_pages (const hb_vector_t<unsigned>& old_index_to_page_map_index)
- {
- unsigned int write_index = 0;
- for (unsigned int i = 0; i < pages.length; i++)
- {
- if (old_index_to_page_map_index[i] == 0xFFFFFFFF) continue;
-
- if (write_index < i)
- pages[write_index] = pages[i];
-
- page_map[old_index_to_page_map_index[i]].index = write_index;
- write_index++;
- }
- }
- public:
-
- void process_ (hb_bit_page_t::vector_t (*op) (const hb_bit_page_t::vector_t &, const hb_bit_page_t::vector_t &),
- bool passthru_left, bool passthru_right,
- const hb_bit_set_t &other)
- {
- if (unlikely (!successful)) return;
-
- dirty ();
-
- unsigned int na = pages.length;
- unsigned int nb = other.pages.length;
- unsigned int next_page = na;
-
- unsigned int count = 0, newCount = 0;
- unsigned int a = 0, b = 0;
- unsigned int write_index = 0;
-
- // Pre-allocate the workspace that compact() will need so we can bail on allocation failure
- // before attempting to rewrite the page map.
- hb_vector_t<unsigned> compact_workspace;
- if (!passthru_left && unlikely (!allocate_compact_workspace (compact_workspace))) return;
-
- for (; a < na && b < nb; )
- {
- if (page_map[a].major == other.page_map[b].major)
- {
- if (!passthru_left)
- {
- // Move page_map entries that we're keeping from the left side set
- // to the front of the page_map vector. This isn't necessary if
- // passthru_left is set since no left side pages will be removed
- // in that case.
- if (write_index < a)
- page_map[write_index] = page_map[a];
- write_index++;
- }
-
- count++;
- a++;
- b++;
- }
- else if (page_map[a].major < other.page_map[b].major)
- {
- if (passthru_left)
- count++;
- a++;
- }
- else
- {
- if (passthru_right)
- count++;
- b++;
- }
- }
- if (passthru_left)
- count += na - a;
- if (passthru_right)
- count += nb - b;
-
- if (!passthru_left)
- {
- na = write_index;
- next_page = write_index;
- compact (compact_workspace, write_index);
- }
-
- if (unlikely (!resize (count)))
- return;
-
- newCount = count;
-
- /* Process in-place backward. */
- a = na;
- b = nb;
- for (; a && b; )
- {
- if (page_map.arrayZ[a - 1].major == other.page_map.arrayZ[b - 1].major)
- {
- a--;
- b--;
- count--;
- page_map.arrayZ[count] = page_map.arrayZ[a];
- page_at (count).v = op (page_at (a).v, other.page_at (b).v);
- }
- else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
- {
- a--;
- if (passthru_left)
- {
- count--;
- page_map.arrayZ[count] = page_map.arrayZ[a];
- }
- }
- else
- {
- b--;
- if (passthru_right)
- {
- count--;
- page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
- page_map.arrayZ[count].index = next_page++;
- page_at (count).v = other.page_at (b).v;
- }
- }
- }
- if (passthru_left)
- while (a)
- {
- a--;
- count--;
- page_map.arrayZ[count] = page_map.arrayZ[a];
- }
- if (passthru_right)
- while (b)
- {
- b--;
- count--;
- page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
- page_map.arrayZ[count].index = next_page++;
- page_at (count).v = other.page_at (b).v;
- }
- assert (!count);
- resize (newCount);
- }
- template <typename Op>
- static hb_bit_page_t::vector_t
- op_ (const hb_bit_page_t::vector_t &a, const hb_bit_page_t::vector_t &b)
- { return Op{} (a, b); }
- template <typename Op>
- void process (const Op& op, const hb_bit_set_t &other)
- {
- process_ (op_<Op>, op (1, 0), op (0, 1), other);
- }
-
- void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); }
- void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); }
- void subtract (const hb_bit_set_t &other) { process (hb_bitwise_gt, other); }
- void symmetric_difference (const hb_bit_set_t &other) { process (hb_bitwise_xor, other); }
-
- bool next (hb_codepoint_t *codepoint) const
- {
- if (unlikely (*codepoint == INVALID)) {
- *codepoint = get_min ();
- return *codepoint != INVALID;
- }
-
- const auto* page_map_array = page_map.arrayZ;
- unsigned int major = get_major (*codepoint);
- unsigned int i = last_page_lookup;
-
- if (unlikely (i >= page_map.length || page_map_array[i].major != major))
- {
- page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST);
- if (i >= page_map.length) {
- *codepoint = INVALID;
- return false;
- }
- }
-
- const auto* pages_array = pages.arrayZ;
- const page_map_t &current = page_map_array[i];
- if (likely (current.major == major))
- {
- if (pages_array[current.index].next (codepoint))
- {
- *codepoint += current.major * page_t::PAGE_BITS;
- last_page_lookup = i;
- return true;
- }
- i++;
- }
-
- for (; i < page_map.length; i++)
- {
- const page_map_t &current = page_map_array[i];
- hb_codepoint_t m = pages_array[current.index].get_min ();
- if (m != INVALID)
- {
- *codepoint = current.major * page_t::PAGE_BITS + m;
- last_page_lookup = i;
- return true;
- }
- }
- last_page_lookup = 0;
- *codepoint = INVALID;
- return false;
- }
- bool previous (hb_codepoint_t *codepoint) const
- {
- if (unlikely (*codepoint == INVALID)) {
- *codepoint = get_max ();
- return *codepoint != INVALID;
- }
-
- page_map_t map = {get_major (*codepoint), 0};
- unsigned int i;
- page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST);
- if (i < page_map.length && page_map.arrayZ[i].major == map.major)
- {
- if (pages[page_map.arrayZ[i].index].previous (codepoint))
- {
- *codepoint += page_map.arrayZ[i].major * page_t::PAGE_BITS;
- return true;
- }
- }
- i--;
- for (; (int) i >= 0; i--)
- {
- hb_codepoint_t m = pages.arrayZ[page_map.arrayZ[i].index].get_max ();
- if (m != INVALID)
- {
- *codepoint = page_map.arrayZ[i].major * page_t::PAGE_BITS + m;
- return true;
- }
- }
- *codepoint = INVALID;
- return false;
- }
- bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- {
- hb_codepoint_t i;
-
- i = *last;
- if (!next (&i))
- {
- *last = *first = INVALID;
- return false;
- }
-
- /* TODO Speed up. */
- *last = *first = i;
- while (next (&i) && i == *last + 1)
- (*last)++;
-
- return true;
- }
- bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- {
- hb_codepoint_t i;
-
- i = *first;
- if (!previous (&i))
- {
- *last = *first = INVALID;
- return false;
- }
-
- /* TODO Speed up. */
- *last = *first = i;
- while (previous (&i) && i == *first - 1)
- (*first)--;
-
- return true;
- }
-
- unsigned int next_many (hb_codepoint_t codepoint,
- hb_codepoint_t *out,
- unsigned int size) const
- {
- // By default, start at the first bit of the first page of values.
- unsigned int start_page = 0;
- unsigned int start_page_value = 0;
- if (unlikely (codepoint != INVALID))
- {
- const auto* page_map_array = page_map.arrayZ;
- unsigned int major = get_major (codepoint);
- unsigned int i = last_page_lookup;
- if (unlikely (i >= page_map.length || page_map_array[i].major != major))
- {
- page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST);
- if (i >= page_map.length)
- return 0; // codepoint is greater than our max element.
- }
- start_page = i;
- start_page_value = page_remainder (codepoint + 1);
- if (unlikely (start_page_value == 0))
- {
- // The export-after value was last in the page. Start on next page.
- start_page++;
- start_page_value = 0;
- }
- }
-
- unsigned int initial_size = size;
- for (unsigned int i = start_page; i < page_map.length && size; i++)
- {
- uint32_t base = major_start (page_map[i].major);
- unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size);
- out += n;
- size -= n;
- start_page_value = 0;
- }
- return initial_size - size;
- }
-
- unsigned int next_many_inverted (hb_codepoint_t codepoint,
- hb_codepoint_t *out,
- unsigned int size) const
- {
- unsigned int initial_size = size;
- // By default, start at the first bit of the first page of values.
- unsigned int start_page = 0;
- unsigned int start_page_value = 0;
- if (unlikely (codepoint != INVALID))
- {
- const auto* page_map_array = page_map.arrayZ;
- unsigned int major = get_major (codepoint);
- unsigned int i = last_page_lookup;
- if (unlikely (i >= page_map.length || page_map_array[i].major != major))
- {
- page_map.bfind(major, &i, HB_NOT_FOUND_STORE_CLOSEST);
- if (unlikely (i >= page_map.length))
- {
- // codepoint is greater than our max element.
- while (++codepoint != INVALID && size)
- {
- *out++ = codepoint;
- size--;
- }
- return initial_size - size;
- }
- }
- start_page = i;
- start_page_value = page_remainder (codepoint + 1);
- if (unlikely (start_page_value == 0))
- {
- // The export-after value was last in the page. Start on next page.
- start_page++;
- start_page_value = 0;
- }
- }
-
- hb_codepoint_t next_value = codepoint + 1;
- for (unsigned int i=start_page; i<page_map.length && size; i++)
- {
- uint32_t base = major_start (page_map[i].major);
- unsigned int n = pages[page_map[i].index].write_inverted (base, start_page_value, out, size, &next_value);
- out += n;
- size -= n;
- start_page_value = 0;
- }
- while (next_value < HB_SET_VALUE_INVALID && size) {
- *out++ = next_value++;
- size--;
- }
- return initial_size - size;
- }
-
- bool has_population () const { return population != UINT_MAX; }
- unsigned int get_population () const
- {
- if (has_population ())
- return population;
-
- unsigned int pop = 0;
- unsigned int count = pages.length;
- for (unsigned int i = 0; i < count; i++)
- pop += pages[i].get_population ();
-
- population = pop;
- return pop;
- }
- hb_codepoint_t get_min () const
- {
- unsigned count = pages.length;
- for (unsigned i = 0; i < count; i++)
- {
- const auto& map = page_map[i];
- const auto& page = pages[map.index];
-
- if (!page.is_empty ())
- return map.major * page_t::PAGE_BITS + page.get_min ();
- }
- return INVALID;
- }
- hb_codepoint_t get_max () const
- {
- unsigned count = pages.length;
- for (signed i = count - 1; i >= 0; i--)
- {
- const auto& map = page_map[(unsigned) i];
- const auto& page = pages[map.index];
-
- if (!page.is_empty ())
- return map.major * page_t::PAGE_BITS + page.get_max ();
- }
- return INVALID;
- }
-
- static constexpr hb_codepoint_t INVALID = page_t::INVALID;
-
- /*
- * Iterator implementation.
- */
- struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
- {
- static constexpr bool is_sorted_iterator = true;
- iter_t (const hb_bit_set_t &s_ = Null (hb_bit_set_t),
- bool init = true) : s (&s_), v (INVALID), l(0)
- {
- if (init)
- {
- l = s->get_population () + 1;
- __next__ ();
- }
- }
-
- typedef hb_codepoint_t __item_t__;
- hb_codepoint_t __item__ () const { return v; }
- bool __more__ () const { return v != INVALID; }
- void __next__ () { s->next (&v); if (l) l--; }
- void __prev__ () { s->previous (&v); }
- unsigned __len__ () const { return l; }
- iter_t end () const { return iter_t (*s, false); }
- bool operator != (const iter_t& o) const
- { return s != o.s || v != o.v; }
-
- protected:
- const hb_bit_set_t *s;
- hb_codepoint_t v;
- unsigned l;
- };
- iter_t iter () const { return iter_t (*this); }
- operator iter_t () const { return iter (); }
-
- protected:
-
- page_t *page_for (hb_codepoint_t g, bool insert = false)
- {
- unsigned major = get_major (g);
-
- /* The extra page_map length is necessary; can't just rely on vector here,
- * since the next check would be tricked because a null page also has
- * major==0, which we can't distinguish from an actualy major==0 page... */
- unsigned i = last_page_lookup;
- if (likely (i < page_map.length))
- {
- auto &cached_page = page_map.arrayZ[i];
- if (cached_page.major == major)
- return &pages.arrayZ[cached_page.index];
- }
-
- page_map_t map = {major, pages.length};
- if (!page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST))
- {
- if (!insert)
- return nullptr;
-
- if (unlikely (!resize (pages.length + 1)))
- return nullptr;
-
- pages.arrayZ[map.index].init0 ();
- memmove (page_map.arrayZ + i + 1,
- page_map.arrayZ + i,
- (page_map.length - 1 - i) * page_map.item_size);
- page_map[i] = map;
- }
-
- last_page_lookup = i;
- return &pages.arrayZ[page_map.arrayZ[i].index];
- }
- const page_t *page_for (hb_codepoint_t g) const
- {
- unsigned major = get_major (g);
-
- /* The extra page_map length is necessary; can't just rely on vector here,
- * since the next check would be tricked because a null page also has
- * major==0, which we can't distinguish from an actualy major==0 page... */
- unsigned i = last_page_lookup;
- if (likely (i < page_map.length))
- {
- auto &cached_page = page_map.arrayZ[i];
- if (cached_page.major == major)
- return &pages.arrayZ[cached_page.index];
- }
-
- page_map_t key = {major};
- if (!page_map.bfind (key, &i))
- return nullptr;
-
- last_page_lookup = i;
- return &pages.arrayZ[page_map[i].index];
- }
- page_t &page_at (unsigned int i)
- {
- assert (i < page_map.length);
- return pages.arrayZ[page_map.arrayZ[i].index];
- }
- const page_t &page_at (unsigned int i) const
- {
- assert (i < page_map.length);
- return pages.arrayZ[page_map.arrayZ[i].index];
- }
- unsigned int get_major (hb_codepoint_t g) const { return g >> page_t::PAGE_BITS_LOG_2; }
- unsigned int page_remainder (hb_codepoint_t g) const { return g & page_t::PAGE_BITMASK; }
- hb_codepoint_t major_start (unsigned int major) const { return major << page_t::PAGE_BITS_LOG_2; }
-};
-
-
-#endif /* HB_BIT_SET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
index 265effba037..59c83336374 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
@@ -1,6 +1,5 @@
/*
* Copyright © 2009 Red Hat, Inc.
- * Copyright © 2018 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -25,8 +24,15 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-#include "hb-blob.hh"
+/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199309L
+#endif
+
+#include "hb-private.hh"
+#include "hb-debug.hh"
+
+#include "hb-object-private.hh"
#ifdef HAVE_SYS_MMAN_H
#ifdef HAVE_UNISTD_H
@@ -35,19 +41,36 @@
#include <sys/mman.h>
#endif /* HAVE_SYS_MMAN_H */
+#include <stdio.h>
+#include <errno.h>
+
+
+struct hb_blob_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ bool immutable;
+
+ const char *data;
+ unsigned int length;
+ hb_memory_mode_t mode;
+
+ void *user_data;
+ hb_destroy_func_t destroy;
+};
-/**
- * SECTION: hb-blob
- * @title: hb-blob
- * @short_description: Binary data containers
- * @include: hb.h
- *
- * Blobs wrap a chunk of binary data to handle lifecycle management of data
- * while it is passed between client and HarfBuzz. Blobs are primarily used
- * to create font faces, but also to access font face tables, as well as
- * pass around other binary data.
- **/
+static bool _try_writable (hb_blob_t *blob);
+
+static void
+_hb_blob_destroy_user_data (hb_blob_t *blob)
+{
+ if (blob->destroy) {
+ blob->destroy (blob->user_data);
+ blob->user_data = nullptr;
+ blob->destroy = nullptr;
+ }
+}
/**
* hb_blob_create: (skip)
@@ -55,7 +78,7 @@
* @length: Length of @data in bytes.
* @mode: Memory mode for @data.
* @user_data: Data parameter to pass to @destroy.
- * @destroy: (nullable): Callback to call when @data is not needed anymore.
+ * @destroy: Callback to call when @data is not needed anymore.
*
* Creates a new "blob" object wrapping @data. The @mode parameter is used
* to negotiate ownership and lifecycle of @data.
@@ -72,52 +95,14 @@ hb_blob_create (const char *data,
void *user_data,
hb_destroy_func_t destroy)
{
- if (!length)
- {
- if (destroy)
- destroy (user_data);
- return hb_blob_get_empty ();
- }
-
- hb_blob_t *blob = hb_blob_create_or_fail (data, length, mode,
- user_data, destroy);
- return likely (blob) ? blob : hb_blob_get_empty ();
-}
-
-/**
- * hb_blob_create_or_fail: (skip)
- * @data: Pointer to blob data.
- * @length: Length of @data in bytes.
- * @mode: Memory mode for @data.
- * @user_data: Data parameter to pass to @destroy.
- * @destroy: (nullable): Callback to call when @data is not needed anymore.
- *
- * Creates a new "blob" object wrapping @data. The @mode parameter is used
- * to negotiate ownership and lifecycle of @data.
- *
- * Note that this function returns a freshly-allocated empty blob even if @length
- * is zero. This is in contrast to hb_blob_create(), which returns the singleton
- * empty blob (as returned by hb_blob_get_empty()) if @length is zero.
- *
- * Return value: New blob, or `NULL` if failed. Destroy with hb_blob_destroy().
- *
- * Since: 2.8.2
- **/
-hb_blob_t *
-hb_blob_create_or_fail (const char *data,
- unsigned int length,
- hb_memory_mode_t mode,
- void *user_data,
- hb_destroy_func_t destroy)
-{
hb_blob_t *blob;
- if (length >= 1u << 31 ||
- !(blob = hb_object_create<hb_blob_t> ()))
- {
+ if (!length ||
+ length >= 1u << 31 ||
+ !(blob = hb_object_create<hb_blob_t> ())) {
if (destroy)
destroy (user_data);
- return nullptr;
+ return hb_blob_get_empty ();
}
blob->data = data;
@@ -129,10 +114,9 @@ hb_blob_create_or_fail (const char *data,
if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
blob->mode = HB_MEMORY_MODE_READONLY;
- if (!blob->try_make_writable ())
- {
+ if (!_try_writable (blob)) {
hb_blob_destroy (blob);
- return nullptr;
+ return hb_blob_get_empty ();
}
}
@@ -152,7 +136,7 @@ _hb_blob_destroy (void *data)
* @length: Length of sub-blob.
*
* Returns a blob that represents a range of bytes in @parent. The new
- * blob is always created with #HB_MEMORY_MODE_READONLY, meaning that it
+ * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
* will never modify data in the parent blob. The parent data is not
* expected to be modified, and will result in undefined behavior if it
* is.
@@ -172,13 +156,13 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
{
hb_blob_t *blob;
- if (!length || !parent || offset >= parent->length)
+ if (!length || offset >= parent->length)
return hb_blob_get_empty ();
hb_blob_make_immutable (parent);
blob = hb_blob_create (parent->data + offset,
- hb_min (length, parent->length - offset),
+ MIN (length, parent->length - offset),
HB_MEMORY_MODE_READONLY,
hb_blob_reference (parent),
_hb_blob_destroy);
@@ -187,45 +171,33 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
}
/**
- * hb_blob_copy_writable_or_fail:
- * @blob: A blob.
- *
- * Makes a writable copy of @blob.
- *
- * Return value: The new blob, or nullptr if allocation failed
- *
- * Since: 1.8.0
- **/
-hb_blob_t *
-hb_blob_copy_writable_or_fail (hb_blob_t *blob)
-{
- blob = hb_blob_create (blob->data,
- blob->length,
- HB_MEMORY_MODE_DUPLICATE,
- nullptr,
- nullptr);
-
- if (unlikely (blob == hb_blob_get_empty ()))
- blob = nullptr;
-
- return blob;
-}
-
-/**
* hb_blob_get_empty:
*
* Returns the singleton empty blob.
*
* See TODO:link object types for more information.
*
- * Return value: (transfer full): The empty blob.
+ * Return value: (transfer full): the empty blob.
*
* Since: 0.9.2
**/
hb_blob_t *
-hb_blob_get_empty ()
+hb_blob_get_empty (void)
{
- return const_cast<hb_blob_t *> (&Null (hb_blob_t));
+ static const hb_blob_t _hb_blob_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ nullptr, /* data */
+ 0, /* length */
+ HB_MEMORY_MODE_READONLY, /* mode */
+
+ nullptr, /* user_data */
+ nullptr /* destroy */
+ };
+
+ return const_cast<hb_blob_t *> (&_hb_blob_nil);
}
/**
@@ -250,7 +222,7 @@ hb_blob_reference (hb_blob_t *blob)
* hb_blob_destroy: (skip)
* @blob: a blob.
*
- * Decreases the reference count on @blob, and if it reaches zero, destroys
+ * Descreases the reference count on @blob, and if it reaches zero, destroys
* @blob, freeing all memory, possibly calling the destroy-callback the blob
* was created for if it has not been called already.
*
@@ -263,20 +235,20 @@ hb_blob_destroy (hb_blob_t *blob)
{
if (!hb_object_destroy (blob)) return;
- hb_free (blob);
+ _hb_blob_destroy_user_data (blob);
+
+ free (blob);
}
/**
* hb_blob_set_user_data: (skip)
- * @blob: An #hb_blob_t
- * @key: The user-data key to set
- * @data: A pointer to the user data to set
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the specified blob.
+ * @blob: a blob.
+ * @key: key for data to set.
+ * @data: data to set.
+ * @destroy: callback to call when @data is not needed anymore.
+ * @replace: whether to replace an existing data with the same key.
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -292,18 +264,17 @@ hb_blob_set_user_data (hb_blob_t *blob,
/**
* hb_blob_get_user_data: (skip)
- * @blob: a blob
- * @key: The user-data key to query
+ * @blob: a blob.
+ * @key: key for data to get.
*
- * Fetches the user data associated with the specified key,
- * attached to the specified font-functions structure.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_blob_get_user_data (const hb_blob_t *blob,
+hb_blob_get_user_data (hb_blob_t *blob,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (blob, key);
@@ -312,35 +283,35 @@ hb_blob_get_user_data (const hb_blob_t *blob,
/**
* hb_blob_make_immutable:
- * @blob: a blob
+ * @blob: a blob.
*
- * Makes a blob immutable.
+ *
*
* Since: 0.9.2
**/
void
hb_blob_make_immutable (hb_blob_t *blob)
{
- if (hb_object_is_immutable (blob))
+ if (hb_object_is_inert (blob))
return;
- hb_object_make_immutable (blob);
+ blob->immutable = true;
}
/**
* hb_blob_is_immutable:
* @blob: a blob.
*
- * Tests whether a blob is immutable.
+ *
*
- * Return value: `true` if @blob is immutable, `false` otherwise
+ * Return value: TODO
*
* Since: 0.9.2
**/
hb_bool_t
hb_blob_is_immutable (hb_blob_t *blob)
{
- return hb_object_is_immutable (blob);
+ return blob->immutable;
}
@@ -348,9 +319,9 @@ hb_blob_is_immutable (hb_blob_t *blob)
* hb_blob_get_length:
* @blob: a blob.
*
- * Fetches the length of a blob's data.
+ *
*
- * Return value: the length of @blob data in bytes.
+ * Return value: the length of blob data in bytes.
*
* Since: 0.9.2
**/
@@ -363,11 +334,11 @@ hb_blob_get_length (hb_blob_t *blob)
/**
* hb_blob_get_data:
* @blob: a blob.
- * @length: (out): The length in bytes of the data retrieved
+ * @length: (out):
*
- * Fetches the data from a blob.
+ *
*
- * Returns: (nullable) (transfer none) (array length=length): the byte data of @blob.
+ * Returns: (transfer none) (array length=length):
*
* Since: 0.9.2
**/
@@ -392,27 +363,29 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
* fails.
*
* Returns: (transfer none) (array length=length): Writable blob data,
- * or `NULL` if failed.
+ * or %NULL if failed.
*
* Since: 0.9.2
**/
char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
{
- if (hb_object_is_immutable (blob) ||
- !blob->try_make_writable ())
- {
- if (length) *length = 0;
+ if (!_try_writable (blob)) {
+ if (length)
+ *length = 0;
+
return nullptr;
}
- if (length) *length = blob->length;
+ if (length)
+ *length = blob->length;
+
return const_cast<char *> (blob->data);
}
-bool
-hb_blob_t::try_make_writable_inplace_unix ()
+static hb_bool_t
+_try_make_writable_inplace_unix (hb_blob_t *blob)
{
#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
uintptr_t pagesize = -1, mask, length;
@@ -427,25 +400,25 @@ hb_blob_t::try_make_writable_inplace_unix ()
#endif
if ((uintptr_t) -1L == pagesize) {
- DEBUG_MSG_FUNC (BLOB, this, "failed to get pagesize: %s", strerror (errno));
+ DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
return false;
}
- DEBUG_MSG_FUNC (BLOB, this, "pagesize is %lu", (unsigned long) pagesize);
+ DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
mask = ~(pagesize-1);
- addr = (const char *) (((uintptr_t) this->data) & mask);
- length = (const char *) (((uintptr_t) this->data + this->length + pagesize-1) & mask) - addr;
- DEBUG_MSG_FUNC (BLOB, this,
+ addr = (const char *) (((uintptr_t) blob->data) & mask);
+ length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
+ DEBUG_MSG_FUNC (BLOB, blob,
"calling mprotect on [%p..%p] (%lu bytes)",
addr, addr+length, (unsigned long) length);
if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
- DEBUG_MSG_FUNC (BLOB, this, "mprotect failed: %s", strerror (errno));
+ DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
return false;
}
- this->mode = HB_MEMORY_MODE_WRITABLE;
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
- DEBUG_MSG_FUNC (BLOB, this,
+ DEBUG_MSG_FUNC (BLOB, blob,
"successfully made [%p..%p] (%lu bytes) writable\n",
addr, addr+length, (unsigned long) length);
return true;
@@ -454,322 +427,53 @@ hb_blob_t::try_make_writable_inplace_unix ()
#endif
}
-bool
-hb_blob_t::try_make_writable_inplace ()
+static bool
+_try_writable_inplace (hb_blob_t *blob)
{
- DEBUG_MSG_FUNC (BLOB, this, "making writable inplace\n");
+ DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
- if (this->try_make_writable_inplace_unix ())
+ if (_try_make_writable_inplace_unix (blob))
return true;
- DEBUG_MSG_FUNC (BLOB, this, "making writable -> FAILED\n");
+ DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
/* Failed to make writable inplace, mark that */
- this->mode = HB_MEMORY_MODE_READONLY;
+ blob->mode = HB_MEMORY_MODE_READONLY;
return false;
}
-bool
-hb_blob_t::try_make_writable ()
+static bool
+_try_writable (hb_blob_t *blob)
{
- if (unlikely (!length))
- mode = HB_MEMORY_MODE_WRITABLE;
+ if (blob->immutable)
+ return false;
- if (this->mode == HB_MEMORY_MODE_WRITABLE)
+ if (blob->mode == HB_MEMORY_MODE_WRITABLE)
return true;
- if (this->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && this->try_make_writable_inplace ())
+ if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
return true;
- if (this->mode == HB_MEMORY_MODE_WRITABLE)
+ if (blob->mode == HB_MEMORY_MODE_WRITABLE)
return true;
- DEBUG_MSG_FUNC (BLOB, this, "current data is -> %p\n", this->data);
+ DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
char *new_data;
- new_data = (char *) hb_malloc (this->length);
+ new_data = (char *) malloc (blob->length);
if (unlikely (!new_data))
return false;
- DEBUG_MSG_FUNC (BLOB, this, "dupped successfully -> %p\n", this->data);
+ DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
- hb_memcpy (new_data, this->data, this->length);
- this->destroy_user_data ();
- this->mode = HB_MEMORY_MODE_WRITABLE;
- this->data = new_data;
- this->user_data = new_data;
- this->destroy = hb_free;
+ memcpy (new_data, blob->data, blob->length);
+ _hb_blob_destroy_user_data (blob);
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
+ blob->data = new_data;
+ blob->user_data = new_data;
+ blob->destroy = free;
return true;
}
-
-/*
- * Mmap
- */
-
-#ifndef HB_NO_OPEN
-#ifdef HAVE_MMAP
-# if !defined(HB_NO_RESOURCE_FORK) && defined(__APPLE__)
-# include <sys/paths.h>
-# endif
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-#endif
-
-#ifdef _WIN32
-# include <windows.h>
-#else
-# ifndef O_BINARY
-# define O_BINARY 0
-# endif
-#endif
-
-#ifndef MAP_NORESERVE
-# define MAP_NORESERVE 0
-#endif
-
-struct hb_mapped_file_t
-{
- char *contents;
- unsigned long length;
-#ifdef _WIN32
- HANDLE mapping;
-#endif
-};
-
-#if (defined(HAVE_MMAP) || defined(_WIN32)) && !defined(HB_NO_MMAP)
-static void
-_hb_mapped_file_destroy (void *file_)
-{
- hb_mapped_file_t *file = (hb_mapped_file_t *) file_;
-#ifdef HAVE_MMAP
- munmap (file->contents, file->length);
-#elif defined(_WIN32)
- UnmapViewOfFile (file->contents);
- CloseHandle (file->mapping);
-#else
- assert (0); // If we don't have mmap we shouldn't reach here
-#endif
-
- hb_free (file);
-}
-#endif
-
-#ifdef _PATH_RSRCFORKSPEC
-static int
-_open_resource_fork (const char *file_name, hb_mapped_file_t *file)
-{
- size_t name_len = strlen (file_name);
- size_t len = name_len + sizeof (_PATH_RSRCFORKSPEC);
-
- char *rsrc_name = (char *) hb_malloc (len);
- if (unlikely (!rsrc_name)) return -1;
-
- strncpy (rsrc_name, file_name, name_len);
- strncpy (rsrc_name + name_len, _PATH_RSRCFORKSPEC,
- sizeof (_PATH_RSRCFORKSPEC));
-
- int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0);
- hb_free (rsrc_name);
-
- if (fd != -1)
- {
- struct stat st;
- if (fstat (fd, &st) != -1)
- file->length = (unsigned long) st.st_size;
- else
- {
- close (fd);
- fd = -1;
- }
- }
-
- return fd;
-}
-#endif
-
-/**
- * hb_blob_create_from_file:
- * @file_name: A font filename
- *
- * Creates a new blob containing the data from the
- * specified binary font file.
- *
- * Returns: An #hb_blob_t pointer with the content of the file,
- * or hb_blob_get_empty() if failed.
- *
- * Since: 1.7.7
- **/
-hb_blob_t *
-hb_blob_create_from_file (const char *file_name)
-{
- hb_blob_t *blob = hb_blob_create_from_file_or_fail (file_name);
- return likely (blob) ? blob : hb_blob_get_empty ();
-}
-
-/**
- * hb_blob_create_from_file_or_fail:
- * @file_name: A font filename
- *
- * Creates a new blob containing the data from the
- * specified binary font file.
- *
- * Returns: An #hb_blob_t pointer with the content of the file,
- * or `NULL` if failed.
- *
- * Since: 2.8.2
- **/
-hb_blob_t *
-hb_blob_create_from_file_or_fail (const char *file_name)
-{
- /* Adopted from glib's gmappedfile.c with Matthias Clasen and
- Allison Lortie permission but changed a lot to suit our need. */
-#if defined(HAVE_MMAP) && !defined(HB_NO_MMAP)
- hb_mapped_file_t *file = (hb_mapped_file_t *) hb_calloc (1, sizeof (hb_mapped_file_t));
- if (unlikely (!file)) return nullptr;
-
- int fd = open (file_name, O_RDONLY | O_BINARY, 0);
- if (unlikely (fd == -1)) goto fail_without_close;
-
- struct stat st;
- if (unlikely (fstat (fd, &st) == -1)) goto fail;
-
- file->length = (unsigned long) st.st_size;
-
-#ifdef _PATH_RSRCFORKSPEC
- if (unlikely (file->length == 0))
- {
- int rfd = _open_resource_fork (file_name, file);
- if (rfd != -1)
- {
- close (fd);
- fd = rfd;
- }
- }
-#endif
-
- file->contents = (char *) mmap (nullptr, file->length, PROT_READ,
- MAP_PRIVATE | MAP_NORESERVE, fd, 0);
-
- if (unlikely (file->contents == MAP_FAILED)) goto fail;
-
- close (fd);
-
- return hb_blob_create_or_fail (file->contents, file->length,
- HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file,
- (hb_destroy_func_t) _hb_mapped_file_destroy);
-
-fail:
- close (fd);
-fail_without_close:
- hb_free (file);
-
-#elif defined(_WIN32) && !defined(HB_NO_MMAP)
- hb_mapped_file_t *file = (hb_mapped_file_t *) hb_calloc (1, sizeof (hb_mapped_file_t));
- if (unlikely (!file)) return nullptr;
-
- HANDLE fd;
- unsigned int size = strlen (file_name) + 1;
- wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size);
- if (unlikely (!wchar_file_name)) goto fail_without_close;
- mbstowcs (wchar_file_name, file_name, size);
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
- {
- CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 };
- ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
- ceparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFFF;
- ceparams.dwFileFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0xFFF00000;
- ceparams.dwSecurityQosFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED & 0x000F0000;
- ceparams.lpSecurityAttributes = nullptr;
- ceparams.hTemplateFile = nullptr;
- fd = CreateFile2 (wchar_file_name, GENERIC_READ, FILE_SHARE_READ,
- OPEN_EXISTING, &ceparams);
- }
-#else
- fd = CreateFileW (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
- nullptr);
-#endif
- hb_free (wchar_file_name);
-
- if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
-
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
- {
- LARGE_INTEGER length;
- GetFileSizeEx (fd, &length);
- file->length = length.LowPart;
- file->mapping = CreateFileMappingFromApp (fd, nullptr, PAGE_READONLY, length.QuadPart, nullptr);
- }
-#else
- file->length = (unsigned long) GetFileSize (fd, nullptr);
- file->mapping = CreateFileMapping (fd, nullptr, PAGE_READONLY, 0, 0, nullptr);
-#endif
- if (unlikely (!file->mapping)) goto fail;
-
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
- file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0);
-#else
- file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0);
-#endif
- if (unlikely (!file->contents)) goto fail;
-
- CloseHandle (fd);
- return hb_blob_create_or_fail (file->contents, file->length,
- HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file,
- (hb_destroy_func_t) _hb_mapped_file_destroy);
-
-fail:
- CloseHandle (fd);
-fail_without_close:
- hb_free (file);
-
-#endif
-
- /* The following tries to read a file without knowing its size beforehand
- It's used as a fallback for systems without mmap or to read from pipes */
- unsigned long len = 0, allocated = BUFSIZ * 16;
- char *data = (char *) hb_malloc (allocated);
- if (unlikely (!data)) return nullptr;
-
- FILE *fp = fopen (file_name, "rb");
- if (unlikely (!fp)) goto fread_fail_without_close;
-
- while (!feof (fp))
- {
- if (allocated - len < BUFSIZ)
- {
- allocated *= 2;
- /* Don't allocate and go more than ~536MB, our mmap reader still
- can cover files like that but lets limit our fallback reader */
- if (unlikely (allocated > (2 << 28))) goto fread_fail;
- char *new_data = (char *) hb_realloc (data, allocated);
- if (unlikely (!new_data)) goto fread_fail;
- data = new_data;
- }
-
- unsigned long addition = fread (data + len, 1, allocated - len, fp);
-
- int err = ferror (fp);
-#ifdef EINTR // armcc doesn't have it
- if (unlikely (err == EINTR)) continue;
-#endif
- if (unlikely (err)) goto fread_fail;
-
- len += addition;
- }
- fclose (fp);
-
- return hb_blob_create_or_fail (data, len, HB_MEMORY_MODE_WRITABLE, data,
- (hb_destroy_func_t) hb_free);
-
-fread_fail:
- fclose (fp);
-fread_fail_without_close:
- hb_free (data);
- return nullptr;
-}
-#endif /* !HB_NO_OPEN */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.h b/src/3rdparty/harfbuzz-ng/src/hb-blob.h
index db50067e164..ef3fc98c05d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -36,36 +36,25 @@
HB_BEGIN_DECLS
-/**
- * hb_memory_mode_t:
- * @HB_MEMORY_MODE_DUPLICATE: HarfBuzz immediately makes a copy of the data.
- * @HB_MEMORY_MODE_READONLY: HarfBuzz client will never modify the data,
- * and HarfBuzz will never modify the data.
- * @HB_MEMORY_MODE_WRITABLE: HarfBuzz client made a copy of the data solely
- * for HarfBuzz, so HarfBuzz may modify the data.
- * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE: See above
- *
- * Data type holding the memory modes available to
- * client programs.
- *
- * Regarding these various memory-modes:
+/*
+ * Note re various memory-modes:
*
* - In no case shall the HarfBuzz client modify memory
* that is passed to HarfBuzz in a blob. If there is
- * any such possibility, @HB_MEMORY_MODE_DUPLICATE should be used
+ * any such possibility, MODE_DUPLICATE should be used
* such that HarfBuzz makes a copy immediately,
*
- * - Use @HB_MEMORY_MODE_READONLY otherwise, unless you really really
+ * - Use MODE_READONLY otherse, unless you really really
* really know what you are doing,
*
- * - @HB_MEMORY_MODE_WRITABLE is appropriate if you really made a
+ * - MODE_WRITABLE is appropriate if you really made a
* copy of data solely for the purpose of passing to
* HarfBuzz and doing that just once (no reuse!),
*
- * - If the font is mmap()ed, it's okay to use
- * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, however, using that mode
- * correctly is very tricky. Use @HB_MEMORY_MODE_READONLY instead.
- **/
+ * - If the font is mmap()ed, it's ok to use
+ * READONLY_MAY_MAKE_WRITABLE, however, using that mode
+ * correctly is very tricky. Use MODE_READONLY instead.
+ */
typedef enum {
HB_MEMORY_MODE_DUPLICATE,
HB_MEMORY_MODE_READONLY,
@@ -73,14 +62,6 @@ typedef enum {
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
} hb_memory_mode_t;
-/**
- * hb_blob_t:
- *
- * Data type for blobs. A blob wraps a chunk of binary
- * data and facilitates its lifecycle management between
- * a client program and HarfBuzz.
- *
- **/
typedef struct hb_blob_t hb_blob_t;
HB_EXTERN hb_blob_t *
@@ -90,19 +71,6 @@ hb_blob_create (const char *data,
void *user_data,
hb_destroy_func_t destroy);
-HB_EXTERN hb_blob_t *
-hb_blob_create_or_fail (const char *data,
- unsigned int length,
- hb_memory_mode_t mode,
- void *user_data,
- hb_destroy_func_t destroy);
-
-HB_EXTERN hb_blob_t *
-hb_blob_create_from_file (const char *file_name);
-
-HB_EXTERN hb_blob_t *
-hb_blob_create_from_file_or_fail (const char *file_name);
-
/* Always creates with MEMORY_MODE_READONLY.
* Even if the parent blob is writable, we don't
* want the user of the sub-blob to be able to
@@ -115,9 +83,6 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
unsigned int length);
HB_EXTERN hb_blob_t *
-hb_blob_copy_writable_or_fail (hb_blob_t *blob);
-
-HB_EXTERN hb_blob_t *
hb_blob_get_empty (void);
HB_EXTERN hb_blob_t *
@@ -135,7 +100,7 @@ hb_blob_set_user_data (hb_blob_t *blob,
HB_EXTERN void *
-hb_blob_get_user_data (const hb_blob_t *blob,
+hb_blob_get_user_data (hb_blob_t *blob,
hb_user_data_key_t *key);
@@ -155,6 +120,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
HB_EXTERN char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
+
HB_END_DECLS
#endif /* HB_BLOB_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.hh b/src/3rdparty/harfbuzz-ng/src/hb-blob.hh
deleted file mode 100644
index b1b3b94d3dd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2018 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_BLOB_HH
-#define HB_BLOB_HH
-
-#include "hb.hh"
-
-
-/*
- * hb_blob_t
- */
-
-struct hb_blob_t
-{
- ~hb_blob_t () { destroy_user_data (); }
-
- void destroy_user_data ()
- {
- if (destroy)
- {
- destroy (user_data);
- user_data = nullptr;
- destroy = nullptr;
- }
- }
-
- HB_INTERNAL bool try_make_writable ();
- HB_INTERNAL bool try_make_writable_inplace ();
- HB_INTERNAL bool try_make_writable_inplace_unix ();
-
- hb_bytes_t as_bytes () const { return hb_bytes_t (data, length); }
- template <typename Type>
- const Type* as () const { return as_bytes ().as<Type> (); }
-
- public:
- hb_object_header_t header;
-
- const char *data = nullptr;
- unsigned int length = 0;
- hb_memory_mode_t mode = (hb_memory_mode_t) 0;
-
- void *user_data = nullptr;
- hb_destroy_func_t destroy = nullptr;
-};
-
-
-/*
- * hb_blob_ptr_t
- */
-
-template <typename P>
-struct hb_blob_ptr_t
-{
- typedef hb_remove_pointer<P> T;
-
- hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
- hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }
- const T * operator -> () const { return get (); }
- const T & operator * () const { return *get (); }
- template <typename C> operator const C * () const { return get (); }
- operator const char * () const { return (const char *) get (); }
- const T * get () const { return b->as<T> (); }
- hb_blob_t * get_blob () const { return b.get_raw (); }
- unsigned int get_length () const { return b.get ()->length; }
- void destroy () { hb_blob_destroy (b.get_raw ()); b = nullptr; }
-
- private:
- hb_nonnull_ptr_t<hb_blob_t> b;
-};
-
-
-#endif /* HB_BLOB_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
index 004a9fb8b70..3f626bda40d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh
@@ -29,41 +29,35 @@
#ifndef HB_BUFFER_DESERIALIZE_JSON_HH
#define HB_BUFFER_DESERIALIZE_JSON_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#line 33 "hb-buffer-deserialize-json.hh"
+#line 36 "hb-buffer-deserialize-json.hh"
static const unsigned char _deserialize_json_trans_keys[] = {
- 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
- 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
- 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u,
- 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u,
- 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u,
- 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u,
- 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u,
- 9u, 123u, 0u, 0u, 0
+ 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
+ 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
+ 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
+ 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
+ 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
+ 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
};
static const char _deserialize_json_key_spans[] = {
- 0, 115, 26, 21, 2, 1, 50, 49,
- 10, 117, 117, 85, 117, 1, 50, 49,
- 10, 117, 117, 1, 1, 50, 49, 117,
- 117, 2, 1, 50, 49, 10, 117, 117,
- 1, 50, 49, 10, 117, 117, 1, 1,
- 50, 49, 117, 117, 1, 50, 49, 59,
- 117, 59, 117, 117, 1, 50, 49, 117,
- 115, 0
+ 0, 115, 26, 7, 2, 1, 50, 49,
+ 10, 117, 117, 117, 1, 50, 49, 10,
+ 117, 117, 1, 1, 50, 49, 117, 117,
+ 2, 1, 50, 49, 10, 117, 117, 1,
+ 50, 49, 10, 117, 117, 1, 50, 49,
+ 58, 89, 117, 117, 85, 115, 0
};
static const short _deserialize_json_index_offsets[] = {
- 0, 0, 116, 143, 165, 168, 170, 221,
- 271, 282, 400, 518, 604, 722, 724, 775,
- 825, 836, 954, 1072, 1074, 1076, 1127, 1177,
- 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648,
- 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118,
- 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560,
- 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137,
- 3255, 3371
+ 0, 0, 116, 143, 151, 154, 156, 207,
+ 257, 268, 386, 504, 622, 624, 675, 725,
+ 736, 854, 972, 974, 976, 1027, 1077, 1195,
+ 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
+ 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
+ 2119, 2178, 2268, 2386, 2504, 2590, 2706
};
static const char _deserialize_json_indicies[] = {
@@ -85,28 +79,29 @@ static const char _deserialize_json_indicies[] = {
3, 3, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 3, 1, 4, 1,
- 5, 1, 6, 7, 1, 8, 9, 1,
+ 5, 1, 6, 7, 1, 1, 8, 1,
+ 9, 10, 1, 11, 1, 11, 11, 11,
+ 11, 11, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 10, 1, 11, 12,
- 1, 13, 1, 13, 13, 13, 13, 13,
+ 1, 1, 1, 1, 11, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 13, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 12, 1,
+ 12, 12, 12, 12, 12, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 12,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 14, 1, 14, 14,
- 14, 14, 14, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 13, 1, 1, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 1, 16, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 1, 18, 18, 18,
+ 18, 18, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 14, 1, 1,
+ 1, 1, 1, 1, 18, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 15, 1, 1, 16, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 1,
- 18, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 1, 20, 20, 20, 20, 20,
+ 19, 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, 20, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 21, 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,
@@ -114,199 +109,100 @@ static const char _deserialize_json_indicies[] = {
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, 20, 1, 21, 21, 21, 21, 21,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 22,
- 1, 23, 23, 23, 23, 23, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 23, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 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, 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, 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,
- 1, 1, 1, 1, 1, 24, 1, 25,
- 25, 25, 25, 25, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 25, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 26, 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, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 27, 1, 20, 20, 20,
- 20, 20, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 20, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 21, 1, 1, 1, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 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, 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,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 22, 1, 28, 1, 28, 28, 28,
- 28, 28, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 28, 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, 29, 1,
- 29, 29, 29, 29, 29, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 29,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 30, 1, 1, 31,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 1, 33, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 1, 35, 35, 35,
- 35, 35, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 35, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 36, 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, 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, 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, 1, 1, 1, 1,
- 1, 37, 1, 35, 35, 35, 35, 35,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 35, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 36, 1,
- 1, 1, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 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, 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, 1, 1,
+ 1, 1, 21, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 3, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 37,
- 1, 38, 1, 39, 1, 39, 39, 39,
- 39, 39, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 39, 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, 40, 1,
- 40, 40, 40, 40, 40, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 40,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 41,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 1, 43, 43, 43, 43, 43, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 43, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 44, 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, 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,
+ 1, 1, 1, 1, 1, 1, 1, 22,
+ 1, 18, 18, 18, 18, 18, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 18, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 19, 1, 1, 1,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 45, 1,
- 43, 43, 43, 43, 43, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 43,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 44, 1, 1, 1, 46,
- 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 20, 1, 23,
+ 1, 23, 23, 23, 23, 23, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 23, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 45, 1, 47, 48,
- 1, 49, 1, 49, 49, 49, 49, 49,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 24, 1, 24, 24, 24, 24,
+ 24, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 49, 1, 1, 1, 1, 1,
+ 1, 1, 1, 24, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 25, 1, 1, 26, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 1, 28, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 1, 30, 30, 30, 30, 30, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 50, 1, 50, 50,
- 50, 50, 50, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 50, 1, 1,
+ 30, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 31, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 51, 1, 1, 52, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 1,
- 54, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 1, 56, 56, 56, 56, 56,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 56, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 57, 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,
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, 1, 1, 1, 1, 32, 1, 30,
+ 30, 30, 30, 30, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 30, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 31, 1, 1, 1, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 58,
- 1, 56, 56, 56, 56, 56, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 56, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 57, 1, 1, 1,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 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, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 32, 1, 33, 1, 34,
+ 1, 34, 34, 34, 34, 34, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 58, 1, 59,
- 1, 59, 59, 59, 59, 59, 1, 1,
+ 34, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 59, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 35, 1, 35, 35, 35, 35,
+ 35, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 35, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 60, 1, 60, 60, 60, 60,
- 60, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 36, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 1, 38, 38,
+ 38, 38, 38, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 60, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 38, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 61, 1, 1, 62, 63, 63, 63, 63,
- 63, 63, 63, 63, 63, 1, 64, 65,
- 65, 65, 65, 65, 65, 65, 65, 65,
- 1, 66, 66, 66, 66, 66, 1, 1,
+ 1, 39, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 66, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 67, 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, 1, 1,
@@ -314,92 +210,86 @@ static const char _deserialize_json_indicies[] = {
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, 1, 40, 1, 38, 38, 38, 38,
+ 38, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 38, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 39,
+ 1, 1, 1, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 68, 1, 66,
- 66, 66, 66, 66, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 66, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 67, 1, 1, 1, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65,
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, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 40, 1, 42, 43, 1, 44, 1, 44,
+ 44, 44, 44, 44, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 44, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 68, 1, 69, 1, 70,
- 1, 70, 70, 70, 70, 70, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 45, 1, 45, 45, 45, 45, 45, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 70, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 45, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 46, 1,
+ 1, 47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 1, 49, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 1, 51,
+ 51, 51, 51, 51, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 71, 1, 71, 71, 71, 71,
- 71, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 51, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 71, 1, 1, 1, 1,
+ 1, 1, 52, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 72, 73, 73, 73, 73,
- 73, 73, 73, 73, 73, 1, 74, 74,
- 74, 74, 74, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 74, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 75, 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, 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, 1, 1, 1, 1,
+ 1, 1, 1, 53, 1, 51, 51, 51,
+ 51, 51, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 51, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 52, 1, 1, 1, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 76, 1, 74, 74, 74, 74,
- 74, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 74, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 75,
- 1, 1, 1, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 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, 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, 1,
+ 1, 53, 1, 54, 1, 54, 54, 54,
+ 54, 54, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 54, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 76, 1, 78, 1, 78, 78, 78, 78,
- 78, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 78, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 55, 1,
+ 55, 55, 55, 55, 55, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 55,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 79, 1, 79,
- 79, 79, 79, 79, 1, 1, 1, 1,
+ 1, 1, 1, 1, 56, 1, 1, 57,
+ 58, 58, 58, 58, 58, 58, 58, 58,
+ 58, 1, 59, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 1, 61, 61, 61,
+ 61, 61, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 79, 1,
- 80, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 81, 82,
- 82, 82, 82, 82, 82, 82, 82, 82,
- 1, 84, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 85, 83, 86, 86, 86,
- 86, 86, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 61, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 86, 1, 1, 1,
+ 62, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 87, 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, 1, 1, 1, 1, 1, 1,
@@ -408,75 +298,96 @@ static const char _deserialize_json_indicies[] = {
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, 63, 1, 61, 61, 61, 61, 61,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 88, 1, 83, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 61, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 62, 1,
+ 1, 1, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 83, 1, 89,
- 89, 89, 89, 89, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 89, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 90, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 63,
+ 1, 64, 1, 64, 64, 64, 64, 64,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 64, 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, 65, 1, 65, 65,
+ 65, 65, 65, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 65, 1, 66,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 67, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 1,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 1, 1, 1, 1, 1, 1,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 69, 1, 70, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 71, 71,
+ 1, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 1, 1, 1, 1, 1,
+ 1, 1, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 1, 1, 1, 1,
+ 71, 1, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 1, 72, 72, 72,
+ 72, 72, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 72, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 73, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 91, 1, 89, 89, 89,
- 89, 89, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 89, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 90, 1, 1, 1, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 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, 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,
+ 1, 74, 1, 72, 72, 72, 72, 72,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 91, 1, 93, 1, 93, 93, 93,
- 93, 93, 1, 1, 1, 1, 1, 1,
+ 1, 1, 72, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 73, 1,
+ 1, 1, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 93, 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, 94, 1,
- 94, 94, 94, 94, 94, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 94,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 95,
- 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 1, 89, 89, 89, 89, 89, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 89, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 90, 1, 1,
- 1, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 74,
+ 1, 76, 76, 76, 76, 76, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
+ 76, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 77, 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, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 91, 1,
- 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 78, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 1, 0, 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,
@@ -488,53 +399,47 @@ static const char _deserialize_json_indicies[] = {
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, 1, 2, 1, 1, 0
+ 1, 2, 1, 1, 0
};
static const char _deserialize_json_trans_targs[] = {
- 1, 0, 2, 2, 3, 4, 19, 25,
- 38, 44, 52, 5, 13, 6, 7, 8,
- 9, 12, 9, 12, 10, 2, 11, 10,
- 11, 11, 56, 57, 14, 15, 16, 17,
- 18, 17, 18, 10, 2, 11, 20, 21,
- 22, 23, 24, 10, 2, 11, 24, 26,
- 32, 27, 28, 29, 30, 31, 30, 31,
- 10, 2, 11, 33, 34, 35, 36, 37,
- 36, 37, 10, 2, 11, 39, 40, 41,
- 42, 43, 10, 2, 11, 43, 45, 46,
- 47, 50, 51, 47, 48, 49, 10, 2,
- 11, 10, 2, 11, 51, 53, 54, 50,
- 55, 55
+ 1, 0, 2, 2, 3, 4, 18, 24,
+ 37, 5, 12, 6, 7, 8, 9, 11,
+ 9, 11, 10, 2, 44, 10, 44, 13,
+ 14, 15, 16, 17, 16, 17, 10, 2,
+ 44, 19, 20, 21, 22, 23, 10, 2,
+ 44, 23, 25, 31, 26, 27, 28, 29,
+ 30, 29, 30, 10, 2, 44, 32, 33,
+ 34, 35, 36, 35, 36, 10, 2, 44,
+ 38, 39, 40, 42, 43, 41, 10, 41,
+ 10, 2, 44, 43, 44, 45, 46
};
static const char _deserialize_json_trans_actions[] = {
0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2,
- 2, 2, 0, 0, 3, 3, 4, 0,
- 5, 0, 0, 0, 0, 0, 2, 2,
- 2, 0, 0, 6, 6, 7, 0, 0,
- 0, 2, 2, 8, 8, 9, 0, 0,
- 0, 0, 0, 2, 2, 2, 0, 0,
- 10, 10, 11, 0, 0, 2, 2, 2,
- 0, 0, 12, 12, 13, 0, 0, 0,
- 2, 2, 14, 14, 15, 0, 0, 0,
- 2, 16, 16, 0, 17, 0, 18, 18,
- 19, 20, 20, 21, 17, 0, 0, 22,
- 22, 23
+ 0, 0, 0, 0, 0, 2, 2, 2,
+ 0, 0, 3, 3, 4, 0, 5, 0,
+ 0, 2, 2, 2, 0, 0, 6, 6,
+ 7, 0, 0, 0, 2, 2, 8, 8,
+ 9, 0, 0, 0, 0, 0, 2, 2,
+ 2, 0, 0, 10, 10, 11, 0, 0,
+ 2, 2, 2, 0, 0, 12, 12, 13,
+ 0, 0, 0, 2, 2, 2, 14, 0,
+ 15, 15, 16, 0, 0, 0, 0
};
static const int deserialize_json_start = 1;
-static const int deserialize_json_first_final = 56;
+static const int deserialize_json_first_final = 44;
static const int deserialize_json_error = 0;
static const int deserialize_json_en_main = 1;
-#line 111 "hb-buffer-deserialize-json.rl"
+#line 97 "hb-buffer-deserialize-json.rl"
static hb_bool_t
-_hb_buffer_deserialize_json (hb_buffer_t *buffer,
+_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
const char *buf,
unsigned int buf_len,
const char **end_ptr,
@@ -543,24 +448,26 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer,
const char *p = buf, *pe = buf + buf_len;
/* Ensure we have positions. */
- (void) hb_buffer_get_glyph_positions (buffer, nullptr);
+ (void) hb_buffer_get_glyph_positions (buffer, NULL);
while (p < pe && ISSPACE (*p))
p++;
if (p < pe && *p == (buffer->len ? ',' : '['))
+ {
*end_ptr = ++p;
+ }
- const char *tok = nullptr;
+ const char *tok = NULL;
int cs;
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
-#line 552 "hb-buffer-deserialize-json.hh"
+#line 466 "hb-buffer-deserialize-json.hh"
{
cs = deserialize_json_start;
}
-#line 555 "hb-buffer-deserialize-json.hh"
+#line 471 "hb-buffer-deserialize-json.hh"
{
int _slen;
int _trans;
@@ -588,15 +495,15 @@ _resume:
case 1:
#line 38 "hb-buffer-deserialize-json.rl"
{
- hb_memset (&info, 0, sizeof (info));
- hb_memset (&pos , 0, sizeof (pos ));
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
}
break;
case 5:
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
@@ -608,171 +515,112 @@ _resume:
tok = p;
}
break;
- case 17:
+ case 14:
#line 55 "hb-buffer-deserialize-json.rl"
- { if (unlikely (!buffer->ensure_glyphs ())) return false; }
- break;
- case 23:
-#line 56 "hb-buffer-deserialize-json.rl"
- { if (unlikely (!buffer->ensure_unicode ())) return false; }
- break;
- case 18:
-#line 58 "hb-buffer-deserialize-json.rl"
{
- /* TODO Unescape \" and \\ if found. */
if (!hb_font_glyph_from_string (font,
- tok+1, p - tok - 2, /* Skip "" */
+ tok, p - tok,
&info.codepoint))
return false;
}
break;
- case 20:
-#line 66 "hb-buffer-deserialize-json.rl"
+ case 15:
+#line 62 "hb-buffer-deserialize-json.rl"
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
break;
case 8:
-#line 67 "hb-buffer-deserialize-json.rl"
+#line 63 "hb-buffer-deserialize-json.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
break;
case 10:
-#line 68 "hb-buffer-deserialize-json.rl"
+#line 64 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
break;
case 12:
-#line 69 "hb-buffer-deserialize-json.rl"
+#line 65 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
break;
case 3:
-#line 70 "hb-buffer-deserialize-json.rl"
+#line 66 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
break;
case 6:
-#line 71 "hb-buffer-deserialize-json.rl"
+#line 67 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
break;
- case 14:
-#line 72 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
- break;
case 16:
-#line 51 "hb-buffer-deserialize-json.rl"
- {
- tok = p;
-}
-#line 55 "hb-buffer-deserialize-json.rl"
- { if (unlikely (!buffer->ensure_glyphs ())) return false; }
- break;
- case 22:
-#line 51 "hb-buffer-deserialize-json.rl"
- {
- tok = p;
-}
-#line 56 "hb-buffer-deserialize-json.rl"
- { if (unlikely (!buffer->ensure_unicode ())) return false; }
- break;
- case 19:
-#line 58 "hb-buffer-deserialize-json.rl"
- {
- /* TODO Unescape \" and \\ if found. */
- if (!hb_font_glyph_from_string (font,
- tok+1, p - tok - 2, /* Skip "" */
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 21:
-#line 66 "hb-buffer-deserialize-json.rl"
+#line 62 "hb-buffer-deserialize-json.rl"
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 9:
-#line 67 "hb-buffer-deserialize-json.rl"
+#line 63 "hb-buffer-deserialize-json.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 11:
-#line 68 "hb-buffer-deserialize-json.rl"
+#line 64 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 13:
-#line 69 "hb-buffer-deserialize-json.rl"
+#line 65 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 4:
-#line 70 "hb-buffer-deserialize-json.rl"
+#line 66 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 7:
-#line 71 "hb-buffer-deserialize-json.rl"
+#line 67 "hb-buffer-deserialize-json.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
#line 43 "hb-buffer-deserialize-json.rl"
{
buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 15:
-#line 72 "hb-buffer-deserialize-json.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 43 "hb-buffer-deserialize-json.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
-#line 733 "hb-buffer-deserialize-json.hh"
+#line 624 "hb-buffer-deserialize-json.hh"
}
_again:
@@ -784,7 +632,7 @@ _again:
_out: {}
}
-#line 137 "hb-buffer-deserialize-json.rl"
+#line 125 "hb-buffer-deserialize-json.rl"
*end_ptr = p;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh
deleted file mode 100644
index 5fe75659b49..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh
+++ /dev/null
@@ -1,692 +0,0 @@
-
-#line 1 "hb-buffer-deserialize-text-glyphs.rl"
-/*
- * Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
-#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
-
-#include "hb.hh"
-
-
-#line 33 "hb-buffer-deserialize-text-glyphs.hh"
-static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
- 0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
- 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u,
- 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
- 9u, 124u, 9u, 124u, 9u, 124u, 0
-};
-
-static const char _deserialize_text_glyphs_key_spans[] = {
- 0, 10, 13, 10, 13, 10, 10, 13,
- 10, 1, 13, 10, 14, 82, 116, 116,
- 116, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 116
-};
-
-static const short _deserialize_text_glyphs_index_offsets[] = {
- 0, 0, 11, 25, 36, 50, 61, 72,
- 86, 97, 99, 113, 124, 139, 222, 339,
- 456, 573, 690, 807, 924, 1041, 1158, 1275,
- 1392, 1509, 1626
-};
-
-static const char _deserialize_text_glyphs_indicies[] = {
- 0, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 1, 3, 1, 1, 4,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 1, 6, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 1, 8, 1, 1,
- 9, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 1, 11, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 1, 13, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 1, 15, 1, 1, 16, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 1, 18,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 1, 20, 1, 21, 1, 1, 22,
- 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 1, 24, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 1, 20, 1, 1,
- 1, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 1, 26, 26, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 26, 1,
- 1, 26, 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, 1, 1, 26, 26, 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,
- 1, 1, 1, 1, 1, 26, 1, 28,
- 28, 28, 28, 28, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 28, 27,
- 27, 29, 27, 27, 27, 27, 27, 27,
- 27, 30, 1, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 31, 27, 27, 32, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 33, 1, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 28, 27, 34, 34, 34, 34,
- 34, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 34, 26, 26, 35, 26,
- 26, 26, 26, 26, 26, 26, 36, 1,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 37, 26, 26, 38, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 39,
- 1, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 40,
- 26, 41, 41, 41, 41, 41, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 41, 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, 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, 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, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 42, 1, 43, 43,
- 43, 43, 43, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 43, 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, 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,
- 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, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 44, 1, 41, 41, 41, 41, 41,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 41, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 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, 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, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 42, 1,
- 46, 46, 46, 46, 46, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 46,
- 1, 1, 47, 1, 1, 1, 1, 1,
- 1, 1, 1, 48, 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, 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, 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, 1,
- 1, 1, 1, 49, 1, 50, 50, 50,
- 50, 50, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 50, 1, 1, 51,
- 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, 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, 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, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 52, 1, 50, 50, 50, 50, 50, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 50, 1, 1, 51, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 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, 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, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 52, 1, 46,
- 46, 46, 46, 46, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 46, 1,
- 1, 47, 1, 1, 1, 1, 1, 1,
- 1, 1, 48, 1, 1, 1, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7,
- 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, 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, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 49, 1, 53, 53, 53, 53,
- 53, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 53, 1, 1, 54, 1,
- 1, 1, 1, 1, 1, 1, 55, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 56, 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, 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, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 57,
- 1, 58, 58, 58, 58, 58, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 58, 1, 1, 59, 1, 1, 1, 1,
- 1, 1, 1, 60, 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, 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, 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, 1,
- 1, 1, 1, 1, 61, 1, 58, 58,
- 58, 58, 58, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 58, 1, 1,
- 59, 1, 1, 1, 1, 1, 1, 1,
- 60, 1, 1, 1, 1, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 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,
- 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, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 61, 1, 53, 53, 53, 53, 53,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 53, 1, 1, 54, 1, 1,
- 1, 1, 1, 1, 1, 55, 1, 1,
- 1, 1, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 62, 1, 1, 1, 1,
- 1, 1, 56, 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, 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, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 57, 1,
- 0
-};
-
-static const char _deserialize_text_glyphs_trans_targs[] = {
- 16, 0, 18, 3, 19, 22, 19, 22,
- 5, 20, 21, 20, 21, 23, 26, 8,
- 9, 12, 9, 12, 10, 11, 24, 25,
- 24, 25, 15, 15, 14, 1, 2, 6,
- 7, 13, 15, 1, 2, 6, 7, 13,
- 14, 17, 14, 17, 14, 18, 17, 1,
- 4, 14, 17, 1, 14, 17, 1, 2,
- 7, 14, 17, 1, 2, 14, 26
-};
-
-static const char _deserialize_text_glyphs_trans_actions[] = {
- 1, 0, 1, 1, 1, 1, 0, 0,
- 1, 1, 1, 0, 0, 1, 1, 1,
- 1, 1, 0, 0, 2, 1, 1, 1,
- 0, 0, 0, 4, 3, 5, 5, 5,
- 5, 4, 6, 7, 7, 7, 7, 0,
- 6, 8, 8, 0, 0, 0, 9, 10,
- 10, 9, 11, 12, 11, 13, 14, 14,
- 14, 13, 15, 16, 16, 15, 0
-};
-
-static const char _deserialize_text_glyphs_eof_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 3, 6,
- 8, 0, 8, 9, 11, 11, 9, 13,
- 15, 15, 13
-};
-
-static const int deserialize_text_glyphs_start = 14;
-static const int deserialize_text_glyphs_first_final = 14;
-static const int deserialize_text_glyphs_error = 0;
-
-static const int deserialize_text_glyphs_en_main = 14;
-
-
-#line 98 "hb-buffer-deserialize-text-glyphs.rl"
-
-
-static hb_bool_t
-_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
- const char *buf,
- unsigned int buf_len,
- const char **end_ptr,
- hb_font_t *font)
-{
- const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
-
- /* Ensure we have positions. */
- (void) hb_buffer_get_glyph_positions (buffer, nullptr);
-
- while (p < pe && ISSPACE (*p))
- p++;
- if (p < pe && *p == (buffer->len ? '|' : '['))
- *end_ptr = ++p;
-
- const char *end = strchr ((char *) p, ']');
- if (end)
- pe = eof = end;
- else
- {
- end = strrchr ((char *) p, '|');
- if (end)
- pe = eof = end;
- else
- pe = eof = p;
- }
-
- const char *tok = nullptr;
- int cs;
- hb_glyph_info_t info = {0};
- hb_glyph_position_t pos = {0};
-
-#line 346 "hb-buffer-deserialize-text-glyphs.hh"
- {
- cs = deserialize_text_glyphs_start;
- }
-
-#line 349 "hb-buffer-deserialize-text-glyphs.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
-_resume:
- _keys = _deserialize_text_glyphs_trans_keys + (cs<<1);
- _inds = _deserialize_text_glyphs_indicies + _deserialize_text_glyphs_index_offsets[cs];
-
- _slen = _deserialize_text_glyphs_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
- (*p) <= _keys[1] ?
- (*p) - _keys[0] : _slen ];
-
- cs = _deserialize_text_glyphs_trans_targs[_trans];
-
- if ( _deserialize_text_glyphs_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _deserialize_text_glyphs_trans_actions[_trans] ) {
- case 1:
-#line 51 "hb-buffer-deserialize-text-glyphs.rl"
- {
- tok = p;
-}
- break;
- case 7:
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
- break;
- case 14:
-#line 63 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
- break;
- case 2:
-#line 64 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.x_offset )) return false; }
- break;
- case 16:
-#line 65 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
- break;
- case 10:
-#line 66 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
- break;
- case 12:
-#line 67 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
- break;
- case 4:
-#line 38 "hb-buffer-deserialize-text-glyphs.rl"
- {
- hb_memset (&info, 0, sizeof (info));
- hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text-glyphs.rl"
- {
- tok = p;
-}
- break;
- case 6:
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 13:
-#line 63 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 15:
-#line 65 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 9:
-#line 66 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 11:
-#line 67 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 8:
-#line 68 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 5:
-#line 38 "hb-buffer-deserialize-text-glyphs.rl"
- {
- hb_memset (&info, 0, sizeof (info));
- hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text-glyphs.rl"
- {
- tok = p;
-}
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
- break;
- case 3:
-#line 38 "hb-buffer-deserialize-text-glyphs.rl"
- {
- hb_memset (&info, 0, sizeof (info));
- hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text-glyphs.rl"
- {
- tok = p;
-}
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 516 "hb-buffer-deserialize-text-glyphs.hh"
- }
-
-_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- switch ( _deserialize_text_glyphs_eof_actions[cs] ) {
- case 6:
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 13:
-#line 63 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 15:
-#line 65 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_offset )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 9:
-#line 66 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.x_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 11:
-#line 67 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_int (tok, p, &pos.y_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 8:
-#line 68 "hb-buffer-deserialize-text-glyphs.rl"
- { if (!parse_uint (tok, p, &info.mask )) return false; }
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 3:
-#line 38 "hb-buffer-deserialize-text-glyphs.rl"
- {
- hb_memset (&info, 0, sizeof (info));
- hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text-glyphs.rl"
- {
- tok = p;
-}
-#line 55 "hb-buffer-deserialize-text-glyphs.rl"
- {
- /* TODO Unescape delimiters. */
- if (!hb_font_glyph_from_string (font,
- tok, p - tok,
- &info.codepoint))
- return false;
-}
-#line 43 "hb-buffer-deserialize-text-glyphs.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 616 "hb-buffer-deserialize-text-glyphs.hh"
- }
- }
-
- _out: {}
- }
-
-#line 136 "hb-buffer-deserialize-text-glyphs.rl"
-
-
- if (pe < orig_pe && *pe == ']')
- {
- pe++;
- if (p == pe)
- p++;
- }
-
- *end_ptr = p;
-
- return p == pe;
-}
-
-#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh
deleted file mode 100644
index 8ca73bf25f4..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh
+++ /dev/null
@@ -1,332 +0,0 @@
-
-#line 1 "hb-buffer-deserialize-text-unicode.rl"
-/*
- * Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
-#define HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
-
-#include "hb.hh"
-
-
-#line 33 "hb-buffer-deserialize-text-unicode.hh"
-static const unsigned char _deserialize_text_unicode_trans_keys[] = {
- 0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u,
- 9u, 124u, 0
-};
-
-static const char _deserialize_text_unicode_key_spans[] = {
- 0, 109, 60, 55, 10, 116, 116, 116,
- 116
-};
-
-static const short _deserialize_text_unicode_index_offsets[] = {
- 0, 0, 110, 171, 227, 238, 355, 472,
- 589
-};
-
-static const char _deserialize_text_unicode_indicies[] = {
- 0, 0, 0, 0, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 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, 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, 1, 1, 2, 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, 1,
- 1, 1, 1, 1, 1, 2, 1, 3,
- 1, 1, 1, 1, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 1, 1,
- 1, 1, 1, 1, 1, 4, 4, 4,
- 4, 4, 4, 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, 1, 4, 4, 4,
- 4, 4, 4, 1, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 1, 1,
- 1, 1, 1, 1, 1, 4, 4, 4,
- 4, 4, 4, 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, 1, 4, 4, 4,
- 4, 4, 4, 1, 5, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 1, 7,
- 7, 7, 7, 7, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 7, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8,
- 1, 1, 1, 9, 1, 1, 1, 8,
- 8, 8, 8, 8, 8, 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, 1, 8,
- 8, 8, 8, 8, 8, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 10, 1, 11, 11, 11, 11,
- 11, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 11, 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, 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, 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, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0,
- 1, 12, 12, 12, 12, 12, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 12, 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, 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, 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, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 13, 1, 12, 12,
- 12, 12, 12, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 12, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 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,
- 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, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 13, 1, 0
-};
-
-static const char _deserialize_text_unicode_trans_targs[] = {
- 1, 0, 2, 3, 5, 7, 8, 6,
- 5, 4, 1, 6, 6, 1, 8
-};
-
-static const char _deserialize_text_unicode_trans_actions[] = {
- 0, 0, 1, 0, 2, 2, 2, 3,
- 0, 4, 3, 0, 5, 5, 0
-};
-
-static const char _deserialize_text_unicode_eof_actions[] = {
- 0, 0, 0, 0, 0, 3, 0, 5,
- 5
-};
-
-static const int deserialize_text_unicode_start = 1;
-static const int deserialize_text_unicode_first_final = 5;
-static const int deserialize_text_unicode_error = 0;
-
-static const int deserialize_text_unicode_en_main = 1;
-
-
-#line 79 "hb-buffer-deserialize-text-unicode.rl"
-
-
-static hb_bool_t
-_hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer,
- const char *buf,
- unsigned int buf_len,
- const char **end_ptr,
- hb_font_t *font)
-{
- const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
-
- while (p < pe && ISSPACE (*p))
- p++;
- if (p < pe && *p == (buffer->len ? '|' : '<'))
- *end_ptr = ++p;
-
- const char *end = strchr ((char *) p, '>');
- if (end)
- pe = eof = end;
- else
- {
- end = strrchr ((char *) p, '|');
- if (end)
- pe = eof = end;
- else
- pe = eof = p;
- }
-
-
- const char *tok = nullptr;
- int cs;
- hb_glyph_info_t info = {0};
- const hb_glyph_position_t pos = {0};
-
-#line 194 "hb-buffer-deserialize-text-unicode.hh"
- {
- cs = deserialize_text_unicode_start;
- }
-
-#line 197 "hb-buffer-deserialize-text-unicode.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
-_resume:
- _keys = _deserialize_text_unicode_trans_keys + (cs<<1);
- _inds = _deserialize_text_unicode_indicies + _deserialize_text_unicode_index_offsets[cs];
-
- _slen = _deserialize_text_unicode_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
- (*p) <= _keys[1] ?
- (*p) - _keys[0] : _slen ];
-
- cs = _deserialize_text_unicode_trans_targs[_trans];
-
- if ( _deserialize_text_unicode_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _deserialize_text_unicode_trans_actions[_trans] ) {
- case 1:
-#line 38 "hb-buffer-deserialize-text-unicode.rl"
- {
- hb_memset (&info, 0, sizeof (info));
-}
- break;
- case 2:
-#line 51 "hb-buffer-deserialize-text-unicode.rl"
- {
- tok = p;
-}
- break;
- case 4:
-#line 55 "hb-buffer-deserialize-text-unicode.rl"
- {if (!parse_hex (tok, p, &info.codepoint )) return false; }
- break;
- case 3:
-#line 55 "hb-buffer-deserialize-text-unicode.rl"
- {if (!parse_hex (tok, p, &info.codepoint )) return false; }
-#line 42 "hb-buffer-deserialize-text-unicode.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- if (buffer->have_positions)
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 5:
-#line 57 "hb-buffer-deserialize-text-unicode.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 42 "hb-buffer-deserialize-text-unicode.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- if (buffer->have_positions)
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 256 "hb-buffer-deserialize-text-unicode.hh"
- }
-
-_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- switch ( _deserialize_text_unicode_eof_actions[cs] ) {
- case 3:
-#line 55 "hb-buffer-deserialize-text-unicode.rl"
- {if (!parse_hex (tok, p, &info.codepoint )) return false; }
-#line 42 "hb-buffer-deserialize-text-unicode.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- if (buffer->have_positions)
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
- case 5:
-#line 57 "hb-buffer-deserialize-text-unicode.rl"
- { if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 42 "hb-buffer-deserialize-text-unicode.rl"
- {
- buffer->add_info (info);
- if (unlikely (!buffer->successful))
- return false;
- if (buffer->have_positions)
- buffer->pos[buffer->len - 1] = pos;
- *end_ptr = p;
-}
- break;
-#line 289 "hb-buffer-deserialize-text-unicode.hh"
- }
- }
-
- _out: {}
- }
-
-#line 115 "hb-buffer-deserialize-text-unicode.rl"
-
-
- if (pe < orig_pe && *pe == '>')
- {
- pe++;
- if (p == pe)
- p++;
- }
-
- *end_ptr = p;
-
- return p == pe;
-}
-
-#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
new file mode 100644
index 00000000000..d2d8daae7ed
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh
@@ -0,0 +1,571 @@
+
+#line 1 "hb-buffer-deserialize-text.rl"
+/*
+ * Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-buffer-deserialize-text.hh"
+static const unsigned char _deserialize_text_trans_keys[] = {
+ 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
+ 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
+ 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
+ 9u, 124u, 9u, 124u, 9u, 124u, 0
+};
+
+static const char _deserialize_text_key_spans[] = {
+ 0, 114, 13, 10, 13, 10, 10, 13,
+ 10, 1, 13, 10, 14, 116, 116, 0,
+ 114, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116
+};
+
+static const short _deserialize_text_index_offsets[] = {
+ 0, 0, 115, 129, 140, 154, 165, 176,
+ 190, 201, 203, 217, 228, 243, 360, 477,
+ 478, 593, 710, 827, 944, 1061, 1178, 1295,
+ 1412, 1529, 1646
+};
+
+static const char _deserialize_text_indicies[] = {
+ 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 1, 1, 1, 1, 1, 1,
+ 1, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 1, 1, 1, 1, 1,
+ 1, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 1, 5, 1, 1, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 1, 8, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 1, 10, 1, 1,
+ 11, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 1, 13, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 1, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 1, 17, 1, 1, 18, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 1, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 1, 22, 1, 23, 1, 1, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 1, 26, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 1, 22, 1, 1,
+ 1, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 1, 28, 28, 28, 28,
+ 28, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 28, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 29, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 30, 1, 1, 31, 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, 1, 1, 1,
+ 32, 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, 1, 1, 1, 1, 1, 33,
+ 1, 34, 34, 34, 34, 34, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 34, 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, 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, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 35, 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, 1,
+ 1, 1, 1, 1, 36, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 1, 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 1, 28, 28, 28, 28, 28, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 28, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 29, 1, 1, 1,
+ 1, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 1, 1, 1, 30, 1,
+ 1, 31, 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, 1, 1, 1, 32, 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,
+ 1, 1, 1, 1, 1, 33, 1, 38,
+ 38, 38, 38, 38, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 38, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 39, 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, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 40, 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, 1, 1, 1,
+ 1, 1, 41, 1, 42, 42, 42, 42,
+ 42, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 42, 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, 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, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 43, 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, 1, 1, 1, 1, 1, 44,
+ 1, 42, 42, 42, 42, 42, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 42, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 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, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 43, 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, 1,
+ 1, 1, 1, 1, 44, 1, 38, 38,
+ 38, 38, 38, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 38, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 39, 1, 1, 1, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 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,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 40, 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, 1, 1, 1, 1,
+ 1, 41, 1, 45, 45, 45, 45, 45,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 45, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 46, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 47, 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, 1, 1, 1, 48,
+ 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, 1, 1, 1, 1, 1, 49, 1,
+ 50, 50, 50, 50, 50, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 50,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 51, 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, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 52, 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, 1, 1,
+ 1, 1, 1, 53, 1, 50, 50, 50,
+ 50, 50, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 50, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 51,
+ 1, 1, 1, 1, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 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, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 52, 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, 1, 1, 1, 1, 1,
+ 53, 1, 45, 45, 45, 45, 45, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 45, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 46, 1, 1, 1,
+ 1, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 1, 1, 1, 1, 1,
+ 1, 47, 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, 1, 1, 1, 48, 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,
+ 1, 1, 1, 1, 1, 49, 1, 28,
+ 28, 28, 28, 28, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 28, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 29, 1, 55, 55, 1, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 1, 1, 1, 30, 1, 1, 31, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 1, 1, 32, 1, 55, 1, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 1, 33, 1, 0
+};
+
+static const char _deserialize_text_trans_targs[] = {
+ 1, 0, 13, 17, 26, 3, 18, 21,
+ 18, 21, 5, 19, 20, 19, 20, 22,
+ 25, 8, 9, 12, 9, 12, 10, 11,
+ 23, 24, 23, 24, 14, 2, 6, 7,
+ 15, 16, 14, 15, 16, 17, 14, 4,
+ 15, 16, 14, 15, 16, 14, 2, 7,
+ 15, 16, 14, 2, 15, 16, 25, 26
+};
+
+static const char _deserialize_text_trans_actions[] = {
+ 0, 0, 1, 1, 1, 2, 2, 2,
+ 0, 0, 2, 2, 2, 0, 0, 2,
+ 2, 2, 2, 2, 0, 0, 3, 2,
+ 2, 2, 0, 0, 4, 5, 5, 5,
+ 4, 4, 0, 0, 0, 0, 6, 7,
+ 6, 6, 8, 8, 8, 9, 10, 10,
+ 9, 9, 11, 12, 11, 11, 0, 0
+};
+
+static const char _deserialize_text_eof_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 4, 6, 8, 8, 6, 9, 11,
+ 11, 9, 4
+};
+
+static const int deserialize_text_start = 1;
+static const int deserialize_text_first_final = 13;
+static const int deserialize_text_error = 0;
+
+static const int deserialize_text_en_main = 1;
+
+
+#line 91 "hb-buffer-deserialize-text.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ const char **end_ptr,
+ hb_font_t *font)
+{
+ const char *p = buf, *pe = buf + buf_len;
+
+ /* Ensure we have positions. */
+ (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+ while (p < pe && ISSPACE (*p))
+ p++;
+ if (p < pe && *p == (buffer->len ? '|' : '['))
+ {
+ *end_ptr = ++p;
+ }
+
+ const char *eof = pe, *tok = NULL;
+ int cs;
+ hb_glyph_info_t info = {0};
+ hb_glyph_position_t pos = {0};
+
+#line 343 "hb-buffer-deserialize-text.hh"
+ {
+ cs = deserialize_text_start;
+ }
+
+#line 348 "hb-buffer-deserialize-text.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _deserialize_text_trans_keys + (cs<<1);
+ _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
+
+ _slen = _deserialize_text_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+ (*p) <= _keys[1] ?
+ (*p) - _keys[0] : _slen ];
+
+ cs = _deserialize_text_trans_targs[_trans];
+
+ if ( _deserialize_text_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _deserialize_text_trans_actions[_trans] ) {
+ case 2:
+#line 51 "hb-buffer-deserialize-text.rl"
+ {
+ tok = p;
+}
+ break;
+ case 5:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+ break;
+ case 10:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+ break;
+ case 3:
+#line 63 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_offset )) return false; }
+ break;
+ case 12:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+ break;
+ case 7:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+ break;
+ case 1:
+#line 38 "hb-buffer-deserialize-text.rl"
+ {
+ memset (&info, 0, sizeof (info));
+ memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text.rl"
+ {
+ tok = p;
+}
+ break;
+ case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+#line 480 "hb-buffer-deserialize-text.hh"
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ switch ( _deserialize_text_eof_actions[cs] ) {
+ case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+ {
+ if (!hb_font_glyph_from_string (font,
+ tok, p - tok,
+ &info.codepoint))
+ return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+ { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+ case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+ { if (!parse_int (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+ {
+ buffer->add_info (info);
+ if (buffer->in_error)
+ return false;
+ buffer->pos[buffer->len - 1] = pos;
+ *end_ptr = p;
+}
+ break;
+#line 557 "hb-buffer-deserialize-text.hh"
+ }
+ }
+
+ _out: {}
+ }
+
+#line 119 "hb-buffer-deserialize-text.rl"
+
+
+ *end_ptr = p;
+
+ return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
new file mode 100644
index 00000000000..97bdc1be305
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
@@ -0,0 +1,388 @@
+/*
+ * Copyright © 1998-2004 David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_PRIVATE_HH
+#define HB_BUFFER_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+#include "hb-unicode-private.hh"
+
+
+#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
+#endif
+#ifndef HB_BUFFER_MAX_LEN_DEFAULT
+#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
+#endif
+
+#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,
+ HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u,
+ 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,
+ HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u,
+ HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u,
+};
+HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
+
+
+/*
+ * hb_buffer_t
+ */
+
+struct hb_buffer_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ /* Information about how the text in the buffer should be treated */
+ hb_unicode_funcs_t *unicode; /* Unicode functions */
+ hb_buffer_flags_t flags; /* BOT / EOT / etc. */
+ hb_buffer_cluster_level_t cluster_level;
+ hb_codepoint_t replacement; /* U+FFFD or something else. */
+ hb_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;
+ hb_segment_properties_t props; /* Script, language, direction */
+
+ bool in_error; /* Allocation failed */
+ bool have_output; /* Whether we have an output buffer going on */
+ bool have_positions; /* Whether we have positions */
+
+ unsigned int idx; /* Cursor into ->info and ->pos arrays */
+ unsigned int len; /* Length of ->info and ->pos arrays */
+ unsigned int out_len; /* Length of ->out array if have_output */
+
+ unsigned int allocated; /* Length of allocated arrays */
+ hb_glyph_info_t *info;
+ hb_glyph_info_t *out_info;
+ hb_glyph_position_t *pos;
+
+ unsigned int serial;
+
+ /* Text before / after the main buffer contents.
+ * Always in Unicode, and ordered outward.
+ * Index 0 is for "pre-context", 1 for "post-context". */
+ static const unsigned int CONTEXT_LENGTH = 5;
+ hb_codepoint_t context[2][CONTEXT_LENGTH];
+ unsigned int context_len[2];
+
+ /* Debugging API */
+ hb_buffer_message_func_t message_func;
+ void *message_data;
+ hb_destroy_func_t message_destroy;
+
+ /* Internal debugging. */
+ /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
+#ifndef HB_NDEBUG
+ uint8_t allocated_var_bits;
+#endif
+
+
+ /* Methods */
+
+ inline void allocate_var (unsigned int start, unsigned int count)
+ {
+#ifndef HB_NDEBUG
+ unsigned int end = start + count;
+ assert (end <= 8);
+ unsigned int bits = (1u<<end) - (1u<<start);
+ assert (0 == (allocated_var_bits & bits));
+ allocated_var_bits |= bits;
+#endif
+ }
+ inline void deallocate_var (unsigned int start, unsigned int count)
+ {
+#ifndef HB_NDEBUG
+ unsigned int end = start + count;
+ assert (end <= 8);
+ unsigned int bits = (1u<<end) - (1u<<start);
+ assert (bits == (allocated_var_bits & bits));
+ allocated_var_bits &= ~bits;
+#endif
+ }
+ inline void assert_var (unsigned int start, unsigned int count)
+ {
+#ifndef HB_NDEBUG
+ unsigned int end = start + count;
+ assert (end <= 8);
+ unsigned int bits = (1u<<end) - (1u<<start);
+ assert (bits == (allocated_var_bits & bits));
+#endif
+ }
+ inline void deallocate_var_all (void)
+ {
+#ifndef HB_NDEBUG
+ allocated_var_bits = 0;
+#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; }
+
+
+ HB_INTERNAL void reset (void);
+ HB_INTERNAL void clear (void);
+
+ inline unsigned int backtrack_len (void) const
+ { return have_output? out_len : idx; }
+ inline unsigned int lookahead_len (void) const
+ { return len - idx; }
+ inline unsigned int next_serial (void) { return serial++; }
+
+ HB_INTERNAL void add (hb_codepoint_t codepoint,
+ unsigned int cluster);
+ HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
+
+ HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
+ HB_INTERNAL void reverse (void);
+ HB_INTERNAL void reverse_clusters (void);
+ HB_INTERNAL void guess_segment_properties (void);
+
+ HB_INTERNAL void swap_buffers (void);
+ HB_INTERNAL void remove_output (void);
+ HB_INTERNAL void clear_output (void);
+ HB_INTERNAL void clear_positions (void);
+
+ HB_INTERNAL void replace_glyphs (unsigned int num_in,
+ unsigned int num_out,
+ const hb_codepoint_t *glyph_data);
+
+ HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
+ /* Makes a copy of the glyph at idx to output and replace glyph_index */
+ HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
+ HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
+ /* Copies glyph at idx to output but doesn't advance idx */
+ HB_INTERNAL void copy_glyph (void);
+ HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+ /* Copies glyph at idx to output and advance idx.
+ * If there's no output, just advance idx. */
+ inline void
+ next_glyph (void)
+ {
+ if (have_output)
+ {
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
+ }
+ out_len++;
+ }
+
+ idx++;
+ }
+
+ /* Advance idx without copying to output. */
+ inline void skip_glyph (void) { idx++; }
+
+ inline void reset_masks (hb_mask_t mask)
+ {
+ for (unsigned int j = 0; j < len; j++)
+ info[j].mask = mask;
+ }
+ inline void add_masks (hb_mask_t mask)
+ {
+ 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);
+
+ 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);
+ /* 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);
+
+ inline bool ensure (unsigned int size)
+ { return likely (!size || size < allocated) ? true : enlarge (size); }
+
+ inline bool ensure_inplace (unsigned int size)
+ { return likely (!size || size < allocated); }
+
+ HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
+ HB_INTERNAL bool shift_forward (unsigned int count);
+
+ typedef long scratch_buffer_t;
+ HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
+
+ inline void clear_context (unsigned int side) { context_len[side] = 0; }
+
+ HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
+
+ inline bool messaging (void) { return unlikely (message_func); }
+ inline bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
+ {
+ if (!messaging ())
+ return true;
+ va_list ap;
+ va_start (ap, fmt);
+ bool ret = message_impl (font, fmt, ap);
+ va_end (ap);
+ 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))
+#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ())
+#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
+#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ())
+
+
+#endif /* HB_BUFFER_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
index 16f189519b1..ea62e9ffdb2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -24,14 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-buffer-private.hh"
-#ifndef HB_NO_BUFFER_SERIALIZE
-#include "hb-buffer.hh"
-
-
-static const char *_hb_buffer_serialize_formats[] = {
+static const char *serialize_formats[] = {
"text",
"json",
nullptr
@@ -48,21 +44,21 @@ static const char *_hb_buffer_serialize_formats[] = {
* Since: 0.9.7
**/
const char **
-hb_buffer_serialize_list_formats ()
+hb_buffer_serialize_list_formats (void)
{
- return _hb_buffer_serialize_formats;
+ return serialize_formats;
}
/**
* hb_buffer_serialize_format_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
+ * @len: length of @str, or -1 if string is %NULL terminated
*
* Parses a string into an #hb_buffer_serialize_format_t. Does not check if
* @str is a valid buffer serialization format, use
* hb_buffer_serialize_list_formats() to get the list of supported formats.
*
- * Return value:
+ * Return value:
* The parsed #hb_buffer_serialize_format_t.
*
* Since: 0.9.7
@@ -78,42 +74,41 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
* hb_buffer_serialize_format_to_string:
* @format: an #hb_buffer_serialize_format_t to convert.
*
- * Converts @format to the string corresponding it, or `NULL` if it is not a valid
+ * Converts @format to the string corresponding it, or %NULL if it is not a valid
* #hb_buffer_serialize_format_t.
*
* Return value: (transfer none):
- * A `NULL` terminated string corresponding to @format. Should not be freed.
+ * A %NULL terminated string corresponding to @format. Should not be freed.
*
* Since: 0.9.7
**/
const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
- switch ((unsigned) format)
+ switch (format)
{
- case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return _hb_buffer_serialize_formats[0];
- case HB_BUFFER_SERIALIZE_FORMAT_JSON: return _hb_buffer_serialize_formats[1];
+ 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 nullptr;
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
}
static unsigned int
_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
- hb_position_t x = 0, y = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
@@ -125,8 +120,6 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (i)
*p++ = ',';
- else
- *p++ = '[';
*p++ = '{';
@@ -136,119 +129,56 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
char g[128];
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
*p++ = '"';
- for (char *q = g; *q; q++)
- {
- if (unlikely (*q == '"' || *q == '\\'))
+ for (char *q = g; *q; q++) {
+ if (*q == '"')
*p++ = '\\';
*p++ = *q;
}
*p++ = '"';
}
else
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
}
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
- x+pos[i].x_offset, y+pos[i].y_offset));
- if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
- p += hb_max (0, 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 += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", 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)
{
hb_glyph_extents_t extents;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
- extents.x_bearing, extents.y_bearing));
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
- extents.width, extents.height));
- }
-
- *p++ = '}';
- if (i == end-1)
- *p++ = ']';
-
- unsigned int l = p - b;
- if (buf_size > l)
- {
- hb_memcpy (buf, b, l);
- buf += l;
- buf_size -= l;
- *buf_consumed += l;
- *buf = '\0';
- } else
- return i - start;
-
- if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
- {
- x += pos[i].x_advance;
- y += pos[i].y_advance;
- }
- }
-
- return end - start;
-}
-
-static unsigned int
-_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_buffer_serialize_flags_t flags)
-{
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
-
- *buf_consumed = 0;
- for (unsigned int i = start; i < end; i++)
- {
- char b[1024];
- char *p = b;
-
- if (i)
- *p++ = ',';
- else
- *p++ = '[';
-
- *p++ = '{';
-
- APPEND ("\"u\":");
-
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
-
- if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
+ extents.x_bearing, extents.y_bearing));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
+ extents.width, extents.height));
}
*p++ = '}';
- if (i == end-1)
- *p++ = ']';
-
unsigned int l = p - b;
if (buf_size > l)
{
- hb_memcpy (buf, b, l);
+ memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
-
}
return end - start;
@@ -256,20 +186,19 @@ _hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,
static unsigned int
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
- hb_position_t x = 0, y = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
@@ -279,119 +208,58 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (i)
*p++ = '|';
- else
- *p++ = '[';
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
{
- /* TODO Escape delimiters we use. */
hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
p += strlen (p);
}
else
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
}
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
- if (x+pos[i].x_offset || y+pos[i].y_offset)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
-
- if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
- {
- *p++ = '+';
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
- if (pos[i].y_advance)
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
- }
+ if (pos[i].x_offset || pos[i].y_offset)
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset));
+
+ *p++ = '+';
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+ if (pos[i].y_advance)
+ 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 += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
+ 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;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
- }
-
- if (i == end-1) {
- *p++ = ']';
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
}
unsigned int l = p - b;
if (buf_size > l)
{
- hb_memcpy (buf, b, l);
+ memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
-
- if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
- {
- x += pos[i].x_advance;
- y += pos[i].y_advance;
- }
}
return end - start;
}
-
-static unsigned int
-_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_buffer_serialize_flags_t flags)
-{
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
- *buf_consumed = 0;
- for (unsigned int i = start; i < end; i++)
- {
- char b[1024];
- char *p = b;
-
- if (i)
- *p++ = '|';
- else
- *p++ = '<';
-
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));
-
- if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
- p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
- }
-
- if (i == end-1)
- *p++ = '>';
-
- unsigned int l = p - b;
- if (buf_size > l)
- {
- hb_memcpy (buf, b, l);
- buf += l;
- buf_size -= l;
- *buf_consumed += l;
- *buf = '\0';
- } else
- return i - start;
- }
- return end - start;
-}
-
/**
* hb_buffer_serialize_glyphs:
* @buffer: an #hb_buffer_t buffer.
@@ -400,9 +268,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.
- * @font: (nullable): the #hb_font_t used to shape this buffer, needed to
- * read glyph names and extents. If `NULL`, an empty font will be used.
+ * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
+ * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
+ * read glyph names and extents. If %NULL, and empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
@@ -418,7 +286,6 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
* ```
* [uni0651=0@518,0+0|uni0628=0+1897]
* ```
- *
* - The serialized glyphs are delimited with `[` and `]`.
* - Glyphs are separated with `|`
* - Each glyph starts with glyph name, or glyph index if
@@ -427,47 +294,30 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:
* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,
* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,
- * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>`
+ * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the
+ * #hb_glyph_extents_t in the format
+ * `&lt;x_bearing,y_bearing,width,height&gt;`
*
* ## json
- * A machine-readable, structured format.
- * The serialized glyphs will look something like:
- *
- * ```
- * [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},
- * {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]
- * ```
- *
- * Each glyph is a JSON object, with the following properties:
- * - `g`: the glyph name or glyph index if
- * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.
- * - `cl`: #hb_glyph_info_t.cluster if
- * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
- * - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,
- * #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance
- * respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.
- * - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,
- * #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if
- * #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.
+ * TODO.
*
- * Return value:
+ * Return value:
* The number of serialized items.
*
* Since: 0.9.7
**/
unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags)
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
{
- end = hb_clamp (end, start, buffer->len);
- start = hb_min (start, end);
+ assert (start <= end && end <= buffer->len);
unsigned int sconsumed;
if (!buf_consumed)
@@ -476,7 +326,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
- buffer->assert_glyphs ();
+ assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+ buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
if (!buffer->have_positions)
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
@@ -491,106 +342,13 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_glyphs_text (buffer, start, end,
- buf, buf_size, buf_consumed,
- font, flags);
+ buf, buf_size, buf_consumed,
+ font, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_glyphs_json (buffer, start, end,
- buf, buf_size, buf_consumed,
- font, flags);
-
- default:
- case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
- return 0;
-
- }
-}
-
-/**
- * hb_buffer_serialize_unicode:
- * @buffer: an #hb_buffer_t buffer.
- * @start: the first item in @buffer to serialize.
- * @end: the last item in @buffer to serialize.
- * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
- * write serialized buffer into.
- * @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.
- * @format: the #hb_buffer_serialize_format_t to use for formatting the output.
- * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
- * to serialize.
- *
- * Serializes @buffer into a textual representation of its content,
- * when the buffer contains Unicode codepoints (i.e., before shaping). This is
- * useful for showing the contents of the buffer, for example during debugging.
- * There are currently two supported serialization formats:
- *
- * ## text
- * A human-readable, plain text format.
- * The serialized codepoints will look something like:
- *
- * ```
- *  <U+0651=0|U+0628=1>
- * ```
- *
- * - Glyphs are separated with `|`
- * - Unicode codepoints are expressed as zero-padded four (or more)
- * digit hexadecimal numbers preceded by `U+`
- * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster
- * will be indicated with a `=` then #hb_glyph_info_t.cluster.
- *
- * ## json
- * A machine-readable, structured format.
- * The serialized codepoints will be a list of objects with the following
- * properties:
- * - `u`: the Unicode codepoint as a decimal integer
- * - `cl`: #hb_glyph_info_t.cluster if
- * #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
- *
- * For example:
- *
- * ```
- * [{u:1617,cl:0},{u:1576,cl:1}]
- * ```
- *
- * Return value:
- * The number of serialized items.
- *
- * Since: 2.7.3
- **/
-unsigned int
-hb_buffer_serialize_unicode (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags)
-{
- end = hb_clamp (end, start, buffer->len);
- start = hb_min (start, end);
-
- unsigned int sconsumed;
- if (!buf_consumed)
- buf_consumed = &sconsumed;
- *buf_consumed = 0;
- if (buf_size)
- *buf = '\0';
-
- buffer->assert_unicode ();
-
- if (unlikely (start == end))
- return 0;
-
- switch (format)
- {
- case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
- return _hb_buffer_serialize_unicode_text (buffer, start, end,
- buf, buf_size, buf_consumed, flags);
-
- case HB_BUFFER_SERIALIZE_FORMAT_JSON:
- return _hb_buffer_serialize_unicode_json (buffer, start, end,
- buf, buf_size, buf_consumed, flags);
+ buf, buf_size, buf_consumed,
+ font, flags);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
@@ -599,121 +357,43 @@ hb_buffer_serialize_unicode (hb_buffer_t *buffer,
}
}
-static unsigned int
-_hb_buffer_serialize_invalid (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags)
-{
- assert (!buffer->len);
-
- unsigned int sconsumed;
- if (!buf_consumed)
- buf_consumed = &sconsumed;
- if (buf_size < 3)
- return 0;
- if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {
- *buf++ = '[';
- *buf++ = ']';
- *buf = '\0';
- } else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {
- *buf++ = '!';
- *buf++ = '!';
- *buf = '\0';
- }
- *buf_consumed = 2;
- return 0;
-}
-
-/**
- * hb_buffer_serialize:
- * @buffer: an #hb_buffer_t buffer.
- * @start: the first item in @buffer to serialize.
- * @end: the last item in @buffer to serialize.
- * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
- * write serialized buffer into.
- * @buf_size: the size of @buf.
- * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf.
- * @font: (nullable): the #hb_font_t used to shape this buffer, needed to
- * read glyph names and extents. If `NULL`, an empty font will be used.
- * @format: the #hb_buffer_serialize_format_t to use for formatting the output.
- * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
- * to serialize.
- *
- * Serializes @buffer into a textual representation of its content, whether
- * Unicode codepoints or glyph identifiers and positioning information. This is
- * useful for showing the contents of the buffer, for example during debugging.
- * See the documentation of hb_buffer_serialize_unicode() and
- * hb_buffer_serialize_glyphs() for a description of the output format.
- *
- * Return value:
- * The number of serialized items.
- *
- * Since: 2.7.3
- **/
-unsigned int
-hb_buffer_serialize (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags)
-{
- switch (buffer->content_type)
- {
-
- case HB_BUFFER_CONTENT_TYPE_GLYPHS:
- return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,
- buf_consumed, font, format, flags);
-
- case HB_BUFFER_CONTENT_TYPE_UNICODE:
- return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,
- buf_consumed, format, flags);
-
- case HB_BUFFER_CONTENT_TYPE_INVALID:
- default:
- return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,
- buf_consumed, format, flags);
- }
-}
-
-static bool
-parse_int (const char *pp, const char *end, int32_t *pv)
-{
- int v;
- const char *p = pp;
- if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
- return false;
-
- *pv = v;
- return true;
-}
-static bool
+static hb_bool_t
parse_uint (const char *pp, const char *end, uint32_t *pv)
{
- unsigned int v;
- const char *p = pp;
- if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
+ 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;
+ uint32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
return false;
*pv = v;
return true;
}
-static bool
-parse_hex (const char *pp, const char *end, uint32_t *pv)
+static hb_bool_t
+parse_int (const char *pp, const char *end, int32_t *pv)
{
- unsigned int v;
- const char *p = pp;
- if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))
+ 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;
+ int32_t v;
+
+ errno = 0;
+ v = strtol (p, &pend, 10);
+ if (errno || p == pend || pend - p != end - pp)
return false;
*pv = v;
@@ -721,48 +401,38 @@ parse_hex (const char *pp, const char *end, uint32_t *pv)
}
#include "hb-buffer-deserialize-json.hh"
-#include "hb-buffer-deserialize-text-glyphs.hh"
-#include "hb-buffer-deserialize-text-unicode.hh"
+#include "hb-buffer-deserialize-text.hh"
/**
* hb_buffer_deserialize_glyphs:
* @buffer: an #hb_buffer_t buffer.
- * @buf: (array length=buf_len): string to deserialize
- * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated
- * @end_ptr: (out) (optional): output pointer to the character after last
- * consumed one.
- * @font: (nullable): font for getting glyph IDs
- * @format: the #hb_buffer_serialize_format_t of the input @buf
+ * @buf: (array length=buf_len):
+ * @buf_len:
+ * @end_ptr: (out):
+ * @font:
+ * @format:
*
- * Deserializes glyphs @buffer from textual representation in the format
- * produced by hb_buffer_serialize_glyphs().
+ *
*
- * Return value: `true` if parse was successful, `false` if an error
- * occurred.
+ * Return value:
*
* Since: 0.9.7
**/
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 */
- hb_buffer_serialize_format_t format)
+ const char *buf,
+ int buf_len, /* -1 means nul-terminated */
+ const char **end_ptr, /* May be nullptr */
+ hb_font_t *font, /* May be nullptr */
+ hb_buffer_serialize_format_t format)
{
const char *end;
if (!end_ptr)
end_ptr = &end;
*end_ptr = buf;
- buffer->assert_glyphs ();
-
- if (unlikely (hb_object_is_immutable (buffer)))
- {
- if (end_ptr)
- *end_ptr = buf;
- return false;
- }
+ assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+ buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
if (buf_len == -1)
buf_len = strlen (buf);
@@ -781,85 +451,14 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
- return _hb_buffer_deserialize_text_glyphs (buffer,
+ return _hb_buffer_deserialize_glyphs_text (buffer,
buf, buf_len, end_ptr,
font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
- return _hb_buffer_deserialize_json (buffer,
- buf, buf_len, end_ptr,
- font);
-
- default:
- case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
- return false;
-
- }
-}
-
-
-/**
- * hb_buffer_deserialize_unicode:
- * @buffer: an #hb_buffer_t buffer.
- * @buf: (array length=buf_len): string to deserialize
- * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated
- * @end_ptr: (out) (optional): output pointer to the character after last
- * consumed one.
- * @format: the #hb_buffer_serialize_format_t of the input @buf
- *
- * Deserializes Unicode @buffer from textual representation in the format
- * produced by hb_buffer_serialize_unicode().
- *
- * Return value: `true` if parse was successful, `false` if an error
- * occurred.
- *
- * Since: 2.7.3
- **/
-hb_bool_t
-hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
- const char *buf,
- int buf_len, /* -1 means nul-terminated */
- const char **end_ptr, /* May be NULL */
- hb_buffer_serialize_format_t format)
-{
- const char *end;
- if (!end_ptr)
- end_ptr = &end;
- *end_ptr = buf;
-
- buffer->assert_unicode ();
-
- if (unlikely (hb_object_is_immutable (buffer)))
- {
- if (end_ptr)
- *end_ptr = buf;
- return false;
- }
-
- if (buf_len == -1)
- buf_len = strlen (buf);
-
- if (!buf_len)
- {
- *end_ptr = buf;
- return false;
- }
-
- hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
-
- hb_font_t* font = hb_font_get_empty ();
-
- switch (format)
- {
- case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
- return _hb_buffer_deserialize_text_unicode (buffer,
- buf, buf_len, end_ptr,
- font);
-
- case HB_BUFFER_SERIALIZE_FORMAT_JSON:
- return _hb_buffer_deserialize_json (buffer,
- buf, buf_len, end_ptr,
- font);
+ return _hb_buffer_deserialize_glyphs_json (buffer,
+ buf, buf_len, end_ptr,
+ font);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
@@ -867,6 +466,3 @@ hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
}
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc
deleted file mode 100644
index f111b2d8dcf..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-verify.cc
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.hh"
-
-#ifndef HB_NO_BUFFER_VERIFY
-
-#include "hb-buffer.hh"
-
-
-#define BUFFER_VERIFY_ERROR "buffer verify error: "
-static inline void
-buffer_verify_error (hb_buffer_t *buffer,
- hb_font_t *font,
- const char *fmt,
- ...) HB_PRINTF_FUNC(3, 4);
-
-static inline void
-buffer_verify_error (hb_buffer_t *buffer,
- hb_font_t *font,
- const char *fmt,
- ...)
-{
- va_list ap;
- va_start (ap, fmt);
- if (buffer->messaging ())
- {
- buffer->message_impl (font, fmt, ap);
- }
- else
- {
- fprintf (stderr, "harfbuzz ");
- vfprintf (stderr, fmt, ap);
- fprintf (stderr, "\n");
- }
- va_end (ap);
-}
-
-static bool
-buffer_verify_monotone (hb_buffer_t *buffer,
- hb_font_t *font)
-{
- /* Check that clusters are monotone. */
- if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES ||
- buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
- {
- bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
-
- unsigned int num_glyphs;
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
-
- for (unsigned int i = 1; i < num_glyphs; i++)
- if (info[i-1].cluster != info[i].cluster &&
- (info[i-1].cluster < info[i].cluster) != is_forward)
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone.");
- return false;
- }
- }
-
- return true;
-}
-
-static bool
-buffer_verify_unsafe_to_break (hb_buffer_t *buffer,
- hb_buffer_t *text_buffer,
- hb_font_t *font,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shapers)
-{
- if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES &&
- buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
- {
- /* Cannot perform this check without monotone clusters. */
- return true;
- }
-
- /* Check that breaking up shaping at safe-to-break is indeed safe. */
-
- hb_buffer_t *fragment = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (fragment, (hb_buffer_flags_t (hb_buffer_get_flags (fragment) & ~HB_BUFFER_FLAG_VERIFY)));
- hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY)));
-
- unsigned int num_glyphs;
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
-
- unsigned int num_chars;
- hb_glyph_info_t *text = hb_buffer_get_glyph_infos (text_buffer, &num_chars);
-
- /* Chop text and shape fragments. */
- bool forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
- unsigned int start = 0;
- unsigned int text_start = forward ? 0 : num_chars;
- unsigned int text_end = text_start;
- for (unsigned int end = 1; end < num_glyphs + 1; end++)
- {
- if (end < num_glyphs &&
- (info[end].cluster == info[end-1].cluster ||
- info[end-(forward?0:1)].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK))
- continue;
-
- /* Shape segment corresponding to glyphs start..end. */
- if (end == num_glyphs)
- {
- if (forward)
- text_end = num_chars;
- else
- text_start = 0;
- }
- else
- {
- if (forward)
- {
- unsigned int cluster = info[end].cluster;
- while (text_end < num_chars && text[text_end].cluster < cluster)
- text_end++;
- }
- else
- {
- unsigned int cluster = info[end - 1].cluster;
- while (text_start && text[text_start - 1].cluster >= cluster)
- text_start--;
- }
- }
- assert (text_start < text_end);
-
- if (0)
- printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end);
-
- hb_buffer_clear_contents (fragment);
-
- hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);
- if (0 < text_start)
- flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
- if (text_end < num_chars)
- flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
- hb_buffer_set_flags (fragment, flags);
-
- hb_buffer_append (fragment, text_buffer, text_start, text_end);
- if (!hb_shape_full (font, fragment, features, num_features, shapers))
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
- hb_buffer_destroy (reconstruction);
- hb_buffer_destroy (fragment);
- return false;
- }
- else if (!fragment->successful || fragment->shaping_failed)
- {
- hb_buffer_destroy (reconstruction);
- hb_buffer_destroy (fragment);
- return true;
- }
- hb_buffer_append (reconstruction, fragment, 0, -1);
-
- start = end;
- if (forward)
- text_start = text_end;
- else
- text_end = text_start;
- }
-
- bool ret = true;
- hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
- if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
- ret = false;
-
- /* Return the reconstructed result instead so it can be inspected. */
- hb_buffer_set_length (buffer, 0);
- hb_buffer_append (buffer, reconstruction, 0, -1);
- }
-
- hb_buffer_destroy (reconstruction);
- hb_buffer_destroy (fragment);
-
- return ret;
-}
-
-static bool
-buffer_verify_unsafe_to_concat (hb_buffer_t *buffer,
- hb_buffer_t *text_buffer,
- hb_font_t *font,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shapers)
-{
- if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES &&
- buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
- {
- /* Cannot perform this check without monotone clusters. */
- return true;
- }
-
- /* Check that shuffling up text before shaping at safe-to-concat points
- * is indeed safe. */
-
- /* This is what we do:
- *
- * 1. We shape text once. Then segment the text at all the safe-to-concat
- * points;
- *
- * 2. Then we create two buffers, one containing all the even segments and
- * one all the odd segments.
- *
- * 3. Because all these segments were safe-to-concat at both ends, we
- * expect that concatenating them and shaping should NOT change the
- * shaping results of each segment. As such, we expect that after
- * shaping the two buffers, we still get cluster boundaries at the
- * segment boundaries, and that those all are safe-to-concat points.
- * Moreover, that there are NOT any safe-to-concat points within the
- * segments.
- *
- * 4. Finally, we reconstruct the shaping results of the original text by
- * simply interleaving the shaping results of the segments from the two
- * buffers, and assert that the total shaping results is the same as
- * the one from original buffer in step 1.
- */
-
- hb_buffer_t *fragments[2] {hb_buffer_create_similar (buffer),
- hb_buffer_create_similar (buffer)};
- hb_buffer_set_flags (fragments[0], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[0]) & ~HB_BUFFER_FLAG_VERIFY)));
- hb_buffer_set_flags (fragments[1], (hb_buffer_flags_t (hb_buffer_get_flags (fragments[1]) & ~HB_BUFFER_FLAG_VERIFY)));
- hb_buffer_t *reconstruction = hb_buffer_create_similar (buffer);
- hb_buffer_set_flags (reconstruction, (hb_buffer_flags_t (hb_buffer_get_flags (reconstruction) & ~HB_BUFFER_FLAG_VERIFY)));
- hb_segment_properties_t props;
- hb_buffer_get_segment_properties (buffer, &props);
- hb_buffer_set_segment_properties (fragments[0], &props);
- hb_buffer_set_segment_properties (fragments[1], &props);
- hb_buffer_set_segment_properties (reconstruction, &props);
-
- unsigned num_glyphs;
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs);
-
- unsigned num_chars;
- hb_glyph_info_t *text = hb_buffer_get_glyph_infos (text_buffer, &num_chars);
-
- bool forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer));
-
- if (!forward)
- hb_buffer_reverse (buffer);
-
- /*
- * Split text into segments and collect into to fragment streams.
- */
- {
- unsigned fragment_idx = 0;
- unsigned start = 0;
- unsigned text_start = 0;
- unsigned text_end = 0;
- for (unsigned end = 1; end < num_glyphs + 1; end++)
- {
- if (end < num_glyphs &&
- (info[end].cluster == info[end-1].cluster ||
- info[end].mask & HB_GLYPH_FLAG_UNSAFE_TO_CONCAT))
- continue;
-
- /* Accumulate segment corresponding to glyphs start..end. */
- if (end == num_glyphs)
- text_end = num_chars;
- else
- {
- unsigned cluster = info[end].cluster;
- while (text_end < num_chars && text[text_end].cluster < cluster)
- text_end++;
- }
- assert (text_start < text_end);
-
- if (0)
- printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end);
-
-#if 0
- hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);
- if (0 < text_start)
- flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
- if (text_end < num_chars)
- flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
- hb_buffer_set_flags (fragment, flags);
-#endif
-
- hb_buffer_append (fragments[fragment_idx], text_buffer, text_start, text_end);
-
- start = end;
- text_start = text_end;
- fragment_idx = 1 - fragment_idx;
- }
- }
-
- bool ret = true;
- hb_buffer_diff_flags_t diff;
- /*
- * Shape the two fragment streams.
- */
- if (!hb_shape_full (font, fragments[0], features, num_features, shapers))
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
- ret = false;
- goto out;
- }
- else if (!fragments[0]->successful || fragments[0]->shaping_failed)
- {
- ret = true;
- goto out;
- }
- if (!hb_shape_full (font, fragments[1], features, num_features, shapers))
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
- ret = false;
- goto out;
- }
- else if (!fragments[1]->successful || fragments[1]->shaping_failed)
- {
- ret = true;
- goto out;
- }
-
- if (!forward)
- {
- hb_buffer_reverse (fragments[0]);
- hb_buffer_reverse (fragments[1]);
- }
-
- /*
- * Reconstruct results.
- */
- {
- unsigned fragment_idx = 0;
- unsigned fragment_start[2] {0, 0};
- unsigned fragment_num_glyphs[2];
- hb_glyph_info_t *fragment_info[2];
- for (unsigned i = 0; i < 2; i++)
- fragment_info[i] = hb_buffer_get_glyph_infos (fragments[i], &fragment_num_glyphs[i]);
- while (fragment_start[0] < fragment_num_glyphs[0] ||
- fragment_start[1] < fragment_num_glyphs[1])
- {
- unsigned fragment_end = fragment_start[fragment_idx] + 1;
- while (fragment_end < fragment_num_glyphs[fragment_idx] &&
- (fragment_info[fragment_idx][fragment_end].cluster == fragment_info[fragment_idx][fragment_end - 1].cluster ||
- fragment_info[fragment_idx][fragment_end].mask & HB_GLYPH_FLAG_UNSAFE_TO_CONCAT))
- fragment_end++;
-
- hb_buffer_append (reconstruction, fragments[fragment_idx], fragment_start[fragment_idx], fragment_end);
-
- fragment_start[fragment_idx] = fragment_end;
- fragment_idx = 1 - fragment_idx;
- }
- }
-
- if (!forward)
- {
- hb_buffer_reverse (buffer);
- hb_buffer_reverse (reconstruction);
- }
-
- /*
- * Diff results.
- */
- diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
- if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
- {
- buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
- ret = false;
-
- /* Return the reconstructed result instead so it can be inspected. */
- hb_buffer_set_length (buffer, 0);
- hb_buffer_append (buffer, reconstruction, 0, -1);
- }
-
-
-out:
- hb_buffer_destroy (reconstruction);
- hb_buffer_destroy (fragments[0]);
- hb_buffer_destroy (fragments[1]);
-
- return ret;
-}
-
-bool
-hb_buffer_t::verify (hb_buffer_t *text_buffer,
- hb_font_t *font,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shapers)
-{
- bool ret = true;
- if (!buffer_verify_monotone (this, font))
- ret = false;
- if (!buffer_verify_unsafe_to_break (this, text_buffer, font, features, num_features, shapers))
- ret = false;
- if ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) != 0 &&
- !buffer_verify_unsafe_to_concat (this, text_buffer, font, features, num_features, shapers))
- ret = false;
- if (!ret)
- {
-#ifndef HB_NO_BUFFER_SERIALIZE
- unsigned len = text_buffer->len;
- hb_vector_t<char> bytes;
- if (likely (bytes.resize (len * 10 + 16)))
- {
- hb_buffer_serialize_unicode (text_buffer,
- 0, len,
- bytes.arrayZ, bytes.length,
- &len,
- HB_BUFFER_SERIALIZE_FORMAT_TEXT,
- HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS);
- buffer_verify_error (this, font, BUFFER_VERIFY_ERROR "text was: %s.", bytes.arrayZ);
- }
-#endif
- }
- return ret;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
index 616cee807f6..7ead43b0184 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -27,27 +27,20 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-buffer.hh"
-#include "hb-utf.hh"
+#include "hb-buffer-private.hh"
+#include "hb-utf-private.hh"
/**
* SECTION: hb-buffer
- * @title: hb-buffer
+ * @title: Buffers
* @short_description: Input and output buffers
* @include: hb.h
*
- * Buffers serve a dual role in HarfBuzz; before shaping, they hold
- * the input characters that are passed to hb_shape(), and after
- * shaping they hold the output glyphs.
- *
- * The input buffer is a sequence of Unicode codepoints, with
- * associated attributes such as direction and script. The output
- * buffer is a sequence of glyphs, with associated attributes such
- * as position and cluster.
+ * Buffers serve dual role in HarfBuzz; they hold the input characters that are
+ * passed hb_shape(), and after shaping they hold the output glyphs.
**/
-
/**
* hb_segment_properties_equal:
* @a: first #hb_segment_properties_t to compare.
@@ -56,7 +49,7 @@
* Checks the equality of two #hb_segment_properties_t's.
*
* Return value:
- * `true` if all properties of @a equal those of @b, `false` otherwise.
+ * %true if all properties of @a equal those of @b, false otherwise.
*
* Since: 0.9.7
**/
@@ -86,51 +79,12 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p)
{
- return ((unsigned int) p->direction * 31 +
- (unsigned int) p->script) * 31 +
+ return (unsigned int) p->direction ^
+ (unsigned int) p->script ^
(intptr_t) (p->language);
}
-/**
- * hb_segment_properties_overlay:
- * @p: #hb_segment_properties_t to fill in.
- * @src: #hb_segment_properties_t to fill in from.
- *
- * Fills in missing fields of @p from @src in a considered manner.
- *
- * First, if @p does not have direction set, direction is copied from @src.
- *
- * Next, if @p and @src have the same direction (which can be unset), if @p
- * does not have script set, script is copied from @src.
- *
- * Finally, if @p and @src have the same direction and script (which either
- * can be unset), if @p does not have language set, language is copied from
- * @src.
- *
- * Since: 3.3.0
- **/
-void
-hb_segment_properties_overlay (hb_segment_properties_t *p,
- const hb_segment_properties_t *src)
-{
- if (unlikely (!p || !src))
- return;
-
- if (!p->direction)
- p->direction = src->direction;
-
- if (p->direction != src->direction)
- return;
-
- if (!p->script)
- p->script = src->script;
- if (p->script != src->script)
- return;
-
- if (!p->language)
- p->language = src->language;
-}
/* Here is how the buffer works internally:
*
@@ -140,15 +94,14 @@ hb_segment_properties_overlay (hb_segment_properties_t *p,
* As an optimization, both info and out_info may point to the
* same piece of memory, which is owned by info. This remains the
* case as long as out_len doesn't exceed i at any time.
- * In that case, sync() is mostly no-op and the glyph operations
- * operate mostly in-place.
+ * In that case, swap_buffers() is no-op and the glyph operations operate
+ * mostly in-place.
*
* As soon as out_info gets longer than info, out_info is moved over
- * to an alternate buffer (which we reuse the pos buffer for), and its
+ * to an alternate buffer (which we reuse the pos buffer for!), and its
* current contents (out_len entries) are copied to the new place.
- *
- * This should all remain transparent to the user. sync() then
- * switches info over to out_info and does housekeeping.
+ * This should all remain transparent to the user. swap_buffers() then
+ * switches info and out_info.
*/
@@ -158,11 +111,11 @@ hb_segment_properties_overlay (hb_segment_properties_t *p,
bool
hb_buffer_t::enlarge (unsigned int size)
{
- if (unlikely (!successful))
+ if (unlikely (in_error))
return false;
if (unlikely (size > max_len))
{
- successful = false;
+ in_error = true;
return false;
}
@@ -171,23 +124,22 @@ hb_buffer_t::enlarge (unsigned int size)
hb_glyph_info_t *new_info = nullptr;
bool separate_out = out_info != info;
- if (unlikely (hb_unsigned_mul_overflows (size, sizeof (info[0]))))
+ if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
goto done;
while (size >= new_allocated)
new_allocated += (new_allocated >> 1) + 32;
- unsigned new_bytes;
- if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes)))
+ static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
+ if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
goto done;
- static_assert (sizeof (info[0]) == sizeof (pos[0]), "");
- new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes);
- new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes);
+ new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
+ new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
done:
if (unlikely (!new_pos || !new_info))
- successful = false;
+ in_error = true;
if (likely (new_pos))
pos = new_pos;
@@ -196,10 +148,10 @@ done:
info = new_info;
out_info = separate_out ? (hb_glyph_info_t *) pos : info;
- if (likely (successful))
+ if (likely (!in_error))
allocated = new_allocated;
- return likely (successful);
+ return likely (!in_error);
}
bool
@@ -214,7 +166,7 @@ hb_buffer_t::make_room_for (unsigned int num_in,
assert (have_output);
out_info = (hb_glyph_info_t *) pos;
- hb_memcpy (out_info, info, out_len * sizeof (out_info[0]));
+ memcpy (out_info, info, out_len * sizeof (out_info[0]));
}
return true;
@@ -230,12 +182,8 @@ hb_buffer_t::shift_forward (unsigned int count)
if (idx + count > len)
{
/* Under memory failure we might expose this area. At least
- * clean it up. Oh well...
- *
- * Ideally, we should at least set Default_Ignorable bits on
- * these, as well as consistent cluster values. But the former
- * is layering violation... */
- hb_memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
+ * clean it up. Oh well... */
+ memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
}
len += count;
idx += count;
@@ -262,40 +210,31 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
/* HarfBuzz-Internal API */
void
-hb_buffer_t::similar (const hb_buffer_t &src)
+hb_buffer_t::reset (void)
{
- hb_unicode_funcs_destroy (unicode);
- unicode = hb_unicode_funcs_reference (src.unicode);
- flags = src.flags;
- cluster_level = src.cluster_level;
- replacement = src.invisible;
- invisible = src.invisible;
- not_found = src.not_found;
-}
+ if (unlikely (hb_object_is_inert (this)))
+ return;
-void
-hb_buffer_t::reset ()
-{
hb_unicode_funcs_destroy (unicode);
- unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
+ unicode = hb_unicode_funcs_get_default ();
flags = HB_BUFFER_FLAG_DEFAULT;
- cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
- invisible = 0;
- not_found = 0;
clear ();
}
void
-hb_buffer_t::clear ()
+hb_buffer_t::clear (void)
{
- content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
props = default_props;
+ scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- successful = true;
- shaping_failed = false;
+ content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
+ in_error = false;
have_output = false;
have_positions = false;
@@ -304,42 +243,14 @@ hb_buffer_t::clear ()
out_len = 0;
out_info = info;
- hb_memset (context, 0, sizeof context);
- hb_memset (context_len, 0, sizeof context_len);
-
- deallocate_var_all ();
serial = 0;
- scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
-}
-void
-hb_buffer_t::enter ()
-{
- deallocate_var_all ();
- serial = 0;
- shaping_failed = false;
- scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- unsigned mul;
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul)))
- {
- max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN);
- }
- if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul)))
- {
- max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN);
- }
-}
-void
-hb_buffer_t::leave ()
-{
- max_len = HB_BUFFER_MAX_LEN_DEFAULT;
- max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
+ memset (context, 0, sizeof context);
+ memset (context_len, 0, sizeof context_len);
+
deallocate_var_all ();
- serial = 0;
- // Intentionally not reseting shaping_failed, such that it can be inspected.
}
-
void
hb_buffer_t::add (hb_codepoint_t codepoint,
unsigned int cluster)
@@ -350,7 +261,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint,
glyph = &info[len];
- hb_memset (glyph, 0, sizeof (*glyph));
+ memset (glyph, 0, sizeof (*glyph));
glyph->codepoint = codepoint;
glyph->mask = 0;
glyph->cluster = cluster;
@@ -370,79 +281,123 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
void
-hb_buffer_t::clear_output ()
+hb_buffer_t::remove_output (void)
{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ have_output = false;
+ have_positions = false;
+
+ out_len = 0;
+ out_info = info;
+}
+
+void
+hb_buffer_t::clear_output (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
have_output = true;
have_positions = false;
- idx = 0;
out_len = 0;
out_info = info;
}
void
-hb_buffer_t::clear_positions ()
+hb_buffer_t::clear_positions (void)
{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
have_output = false;
have_positions = true;
out_len = 0;
out_info = info;
- hb_memset (pos, 0, sizeof (pos[0]) * len);
+ memset (pos, 0, sizeof (pos[0]) * len);
}
-bool
-hb_buffer_t::sync ()
+void
+hb_buffer_t::swap_buffers (void)
{
- bool ret = false;
+ if (unlikely (in_error)) return;
assert (have_output);
-
- assert (idx <= len);
-
- if (unlikely (!successful || !next_glyphs (len - idx)))
- goto reset;
+ have_output = false;
if (out_info != info)
{
- pos = (hb_glyph_position_t *) info;
+ hb_glyph_info_t *tmp_string;
+ tmp_string = info;
info = out_info;
+ out_info = tmp_string;
+ pos = (hb_glyph_position_t *) out_info;
}
+
+ unsigned int tmp;
+ tmp = len;
len = out_len;
- ret = true;
+ out_len = tmp;
-reset:
- have_output = false;
- out_len = 0;
- out_info = info;
idx = 0;
-
- return ret;
}
-int
-hb_buffer_t::sync_so_far ()
+
+void
+hb_buffer_t::replace_glyphs (unsigned int num_in,
+ unsigned int num_out,
+ const uint32_t *glyph_data)
{
- bool had_output = have_output;
- unsigned out_i = out_len;
- unsigned i = idx;
- unsigned old_idx = idx;
+ if (unlikely (!make_room_for (num_in, num_out))) return;
- if (sync ())
- idx = out_i;
- else
- idx = i;
+ merge_clusters (idx, idx + num_in);
- if (had_output)
+ hb_glyph_info_t orig_info = info[idx];
+ hb_glyph_info_t *pinfo = &out_info[out_len];
+ for (unsigned int i = 0; i < num_out; i++)
{
- have_output = true;
- out_len = idx;
+ *pinfo = orig_info;
+ pinfo->codepoint = glyph_data[i];
+ pinfo++;
}
- assert (idx <= len);
+ idx += num_in;
+ out_len += num_out;
+}
+
+void
+hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = info[idx];
+ out_info[out_len].codepoint = glyph_index;
- return idx - old_idx;
+ out_len++;
+}
+
+void
+hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = glyph_info;
+
+ out_len++;
+}
+
+void
+hb_buffer_t::copy_glyph (void)
+{
+ if (unlikely (!make_room_for (0, 1))) return;
+
+ out_info[out_len] = info[idx];
+
+ out_len++;
}
bool
@@ -454,7 +409,7 @@ hb_buffer_t::move_to (unsigned int i)
idx = i;
return true;
}
- if (unlikely (!successful))
+ if (unlikely (in_error))
return false;
assert (i <= out_len + (len - idx));
@@ -474,13 +429,8 @@ hb_buffer_t::move_to (unsigned int i)
unsigned int count = out_len - i;
/* This will blow in our face if memory allocation fails later
- * in this same lookup...
- *
- * We used to shift with extra 32 items.
- * But that would leave empty slots in the buffer in case of allocation
- * failures. See comments in shift_forward(). This can cause O(N^2)
- * behavior more severely than adding 32 empty slots can... */
- if (unlikely (idx < count && !shift_forward (count - idx))) return false;
+ * in this same lookup... */
+ if (unlikely (idx < count && !shift_forward (count + 32))) return false;
assert (idx >= count);
@@ -492,6 +442,19 @@ hb_buffer_t::move_to (unsigned int i)
return true;
}
+void
+hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
+{
+ if (unlikely (out_info != info || out_len != idx)) {
+ if (unlikely (!make_room_for (1, 1))) return;
+ out_info[out_len] = info[idx];
+ }
+ out_info[out_len].codepoint = glyph_index;
+
+ idx++;
+ out_len++;
+}
+
void
hb_buffer_t::set_masks (hb_mask_t value,
@@ -505,6 +468,13 @@ hb_buffer_t::set_masks (hb_mask_t value,
if (!mask)
return;
+ if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].mask = (info[i].mask & not_mask) | value;
+ return;
+ }
+
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
@@ -512,6 +482,66 @@ hb_buffer_t::set_masks (hb_mask_t value,
}
void
+hb_buffer_t::reverse_range (unsigned int start,
+ unsigned int end)
+{
+ unsigned int i, j;
+
+ if (end - start < 2)
+ return;
+
+ for (i = start, j = end - 1; i < j; i++, j--) {
+ hb_glyph_info_t t;
+
+ t = info[i];
+ info[i] = info[j];
+ info[j] = t;
+ }
+
+ if (have_positions) {
+ for (i = start, j = end - 1; i < j; i++, j--) {
+ hb_glyph_position_t t;
+
+ t = pos[i];
+ pos[i] = pos[j];
+ pos[j] = t;
+ }
+ }
+}
+
+void
+hb_buffer_t::reverse (void)
+{
+ if (unlikely (!len))
+ return;
+
+ reverse_range (0, len);
+}
+
+void
+hb_buffer_t::reverse_clusters (void)
+{
+ unsigned int i, start, count, last_cluster;
+
+ if (unlikely (!len))
+ return;
+
+ reverse ();
+
+ count = len;
+ start = 0;
+ last_cluster = info[0].cluster;
+ for (i = 1; i < count; i++) {
+ if (last_cluster != info[i].cluster) {
+ reverse_range (start, i);
+ start = i;
+ last_cluster = info[i].cluster;
+ }
+ }
+ reverse_range (start, i);
+}
+
+void
hb_buffer_t::merge_clusters_impl (unsigned int start,
unsigned int end)
{
@@ -524,20 +554,18 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
unsigned int cluster = info[start].cluster;
for (unsigned int i = start + 1; i < end; i++)
- cluster = hb_min (cluster, info[i].cluster);
+ cluster = MIN<unsigned int> (cluster, info[i].cluster);
/* Extend end */
- if (cluster != info[end - 1].cluster)
- while (end < len && info[end - 1].cluster == info[end].cluster)
- end++;
+ while (end < len && info[end - 1].cluster == info[end].cluster)
+ end++;
/* Extend start */
- if (cluster != info[start].cluster)
- while (idx < start && info[start - 1].cluster == info[start].cluster)
- start--;
+ while (idx < start && info[start - 1].cluster == info[start].cluster)
+ start--;
/* If we hit the start of buffer, continue in out-buffer. */
- if (idx == start && info[start].cluster != cluster)
+ if (idx == start)
for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
set_cluster (out_info[i - 1], cluster);
@@ -557,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 = hb_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)
@@ -581,8 +609,7 @@ 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) ||
- (out_len && cluster == out_info[out_len - 1].cluster))
+ if (idx + 1 < len && cluster == info[idx + 1].cluster)
{
/* Cluster survives; do nothing. */
goto done;
@@ -613,56 +640,36 @@ done:
}
void
-hb_buffer_t::delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info))
+hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
{
- /* Merge clusters and delete filtered glyphs.
- * NOTE! We can't use out-buffer as we have positioning data. */
- unsigned int j = 0;
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
+ 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)
{
- if (filter (&info[i]))
- {
- /* Merge clusters.
- * Same logic as delete_glyph(), but for in-place removal. */
-
- unsigned int cluster = info[i].cluster;
- if (i + 1 < count && cluster == info[i + 1].cluster)
- continue; /* Cluster survives; do nothing. */
-
- if (j)
- {
- /* 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--)
- set_cluster (info[k - 1], cluster, mask);
- }
- continue;
- }
-
- if (i + 1 < count)
- merge_clusters (i, i + 2); /* Merge cluster forward. */
+ unsafe_to_break_impl (start, end);
+ return;
+ }
- continue;
- }
+ assert (start <= out_len);
+ assert (idx <= end);
- if (j != i)
- {
- info[j] = info[i];
- pos[j] = pos[i];
- }
- j++;
- }
- len = j;
+ 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 ()
+hb_buffer_t::guess_segment_properties (void)
{
- assert_unicode ();
+ assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
/* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) {
@@ -671,8 +678,8 @@ hb_buffer_t::guess_segment_properties ()
if (likely (script != HB_SCRIPT_COMMON &&
script != HB_SCRIPT_INHERITED &&
script != HB_SCRIPT_UNKNOWN)) {
- props.script = script;
- break;
+ props.script = script;
+ break;
}
}
}
@@ -680,8 +687,6 @@ hb_buffer_t::guess_segment_properties ()
/* If direction is set to INVALID, guess from script */
if (props.direction == HB_DIRECTION_INVALID) {
props.direction = hb_script_get_horizontal_direction (props.script);
- if (props.direction == HB_DIRECTION_INVALID)
- props.direction = HB_DIRECTION_LTR;
}
/* If language is not set, use default language from locale */
@@ -694,46 +699,22 @@ hb_buffer_t::guess_segment_properties ()
/* Public API */
-DEFINE_NULL_INSTANCE (hb_buffer_t) =
-{
- HB_OBJECT_HEADER_STATIC,
-
- const_cast<hb_unicode_funcs_t *> (&_hb_Null_hb_unicode_funcs_t),
- HB_BUFFER_FLAG_DEFAULT,
- HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
- HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
- 0, /* invisible */
- 0, /* not_found */
-
-
- HB_BUFFER_CONTENT_TYPE_INVALID,
- HB_SEGMENT_PROPERTIES_DEFAULT,
-
- false, /* successful */
- true, /* shaping_failed */
- false, /* have_output */
- true /* have_positions */
-
- /* Zero is good enough for everything else. */
-};
-
-
/**
- * hb_buffer_create:
+ * hb_buffer_create: (Xconstructor)
*
* Creates a new #hb_buffer_t with all properties to defaults.
*
* Return value: (transfer full):
* A newly allocated #hb_buffer_t with a reference count of 1. The initial
* reference count should be released with hb_buffer_destroy() when you are done
- * using the #hb_buffer_t. This function never returns `NULL`. If memory cannot
+ * using the #hb_buffer_t. This function never returns %NULL. If memory cannot
* be allocated, a special #hb_buffer_t object will be returned on which
- * hb_buffer_allocation_successful() returns `false`.
+ * hb_buffer_allocation_successful() returns %false.
*
* Since: 0.9.2
**/
hb_buffer_t *
-hb_buffer_create ()
+hb_buffer_create (void)
{
hb_buffer_t *buffer;
@@ -749,63 +730,43 @@ hb_buffer_create ()
}
/**
- * hb_buffer_create_similar:
- * @src: An #hb_buffer_t
+ * hb_buffer_get_empty:
*
- * Creates a new #hb_buffer_t, similar to hb_buffer_create(). The only
- * difference is that the buffer is configured similarly to @src.
+ *
*
* Return value: (transfer full):
- * A newly allocated #hb_buffer_t, similar to hb_buffer_create().
*
- * Since: 3.3.0
+ * Since: 0.9.2
**/
hb_buffer_t *
-hb_buffer_create_similar (const hb_buffer_t *src)
+hb_buffer_get_empty (void)
{
- hb_buffer_t *buffer = hb_buffer_create ();
+ static const hb_buffer_t _hb_buffer_nil = {
+ HB_OBJECT_HEADER_STATIC,
- buffer->similar (*src);
+ const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
+ HB_BUFFER_FLAG_DEFAULT,
+ HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
+ HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
+ HB_BUFFER_SCRATCH_FLAG_DEFAULT,
+ HB_BUFFER_MAX_LEN_DEFAULT,
+ HB_BUFFER_MAX_OPS_DEFAULT,
- return buffer;
-}
+ HB_BUFFER_CONTENT_TYPE_INVALID,
+ HB_SEGMENT_PROPERTIES_DEFAULT,
+ true, /* in_error */
+ true, /* have_output */
+ true /* have_positions */
-/**
- * hb_buffer_reset:
- * @buffer: An #hb_buffer_t
- *
- * Resets the buffer to its initial status, as if it was just newly created
- * with hb_buffer_create().
- *
- * Since: 0.9.2
- **/
-void
-hb_buffer_reset (hb_buffer_t *buffer)
-{
- if (unlikely (hb_object_is_immutable (buffer)))
- return;
+ /* Zero is good enough for everything else. */
+ };
- buffer->reset ();
-}
-
-/**
- * hb_buffer_get_empty:
- *
- * Fetches an empty #hb_buffer_t.
- *
- * Return value: (transfer full): The empty buffer
- *
- * Since: 0.9.2
- **/
-hb_buffer_t *
-hb_buffer_get_empty ()
-{
- return const_cast<hb_buffer_t *> (&Null (hb_buffer_t));
+ return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
}
/**
* hb_buffer_reference: (skip)
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Increases the reference count on @buffer by one. This prevents @buffer from
* being destroyed until a matching call to hb_buffer_destroy() is made.
@@ -823,7 +784,7 @@ hb_buffer_reference (hb_buffer_t *buffer)
/**
* hb_buffer_destroy: (skip)
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Deallocate the @buffer.
* Decreases the reference count on @buffer by one. If the result is zero, then
@@ -838,27 +799,25 @@ hb_buffer_destroy (hb_buffer_t *buffer)
hb_unicode_funcs_destroy (buffer->unicode);
- hb_free (buffer->info);
- hb_free (buffer->pos);
-#ifndef HB_NO_BUFFER_MESSAGE
+ free (buffer->info);
+ free (buffer->pos);
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
-#endif
- hb_free (buffer);
+ free (buffer);
}
/**
* hb_buffer_set_user_data: (skip)
- * @buffer: An #hb_buffer_t
- * @key: The user-data key
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @buffer: an #hb_buffer_t.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the specified buffer.
+ *
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -874,18 +833,17 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_get_user_data: (skip)
- * @buffer: An #hb_buffer_t
- * @key: The user-data key to query
+ * @buffer: an #hb_buffer_t.
+ * @key:
*
- * Fetches the user data associated with the specified key,
- * attached to the specified buffer.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value:
*
* Since: 0.9.2
**/
void *
-hb_buffer_get_user_data (const hb_buffer_t *buffer,
+hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (buffer, key);
@@ -894,37 +852,11 @@ hb_buffer_get_user_data (const hb_buffer_t *buffer,
/**
* hb_buffer_set_content_type:
- * @buffer: An #hb_buffer_t
- * @content_type: The type of buffer contents to set
- *
- * Sets the type of @buffer contents. Buffers are either empty, contain
- * characters (before shaping), or contain glyphs (the result of shaping).
- *
- * You rarely need to call this function, since a number of other
- * functions transition the content type for you. Namely:
- *
- * - A newly created buffer starts with content type
- * %HB_BUFFER_CONTENT_TYPE_INVALID. Calling hb_buffer_reset(),
- * hb_buffer_clear_contents(), as well as calling hb_buffer_set_length()
- * with an argument of zero all set the buffer content type to invalid
- * as well.
- *
- * - Calling hb_buffer_add_utf8(), hb_buffer_add_utf16(),
- * hb_buffer_add_utf32(), hb_buffer_add_codepoints() and
- * hb_buffer_add_latin1() expect that buffer is either empty and
- * have a content type of invalid, or that buffer content type is
- * %HB_BUFFER_CONTENT_TYPE_UNICODE, and they also set the content
- * type to Unicode if they added anything to an empty buffer.
- *
- * - Finally hb_shape() and hb_shape_full() expect that the buffer
- * is either empty and have content type of invalid, or that buffer
- * content type is %HB_BUFFER_CONTENT_TYPE_UNICODE, and upon
- * success they set the buffer content type to
- * %HB_BUFFER_CONTENT_TYPE_GLYPHS.
- *
- * The above transitions are designed such that one can use a buffer
- * in a loop of "reset : add-text : shape" without needing to ever
- * modify the content type manually.
+ * @buffer: an #hb_buffer_t.
+ * @content_type: the type of buffer contents to set
+ *
+ * Sets the type of @buffer contents, buffers are either empty, contain
+ * characters (before shaping) or glyphs (the result of shaping).
*
* Since: 0.9.5
**/
@@ -937,18 +869,17 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
/**
* hb_buffer_get_content_type:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the type of @buffer contents. Buffers are either empty, contain
- * characters (before shaping), or contain glyphs (the result of shaping).
+ * see hb_buffer_set_content_type().
*
* Return value:
- * The type of @buffer contents
+ * The type of @buffer contents.
*
* Since: 0.9.5
**/
hb_buffer_content_type_t
-hb_buffer_get_content_type (const hb_buffer_t *buffer)
+hb_buffer_get_content_type (hb_buffer_t *buffer)
{
return buffer->content_type;
}
@@ -956,11 +887,10 @@ hb_buffer_get_content_type (const hb_buffer_t *buffer)
/**
* hb_buffer_set_unicode_funcs:
- * @buffer: An #hb_buffer_t
- * @unicode_funcs: The Unicode-functions structure
+ * @buffer: an #hb_buffer_t.
+ * @unicode_funcs:
*
- * Sets the Unicode-functions structure of a buffer to
- * @unicode_funcs.
+ *
*
* Since: 0.9.2
**/
@@ -968,12 +898,13 @@ void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
hb_unicode_funcs_t *unicode_funcs)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
if (!unicode_funcs)
unicode_funcs = hb_unicode_funcs_get_default ();
+
hb_unicode_funcs_reference (unicode_funcs);
hb_unicode_funcs_destroy (buffer->unicode);
buffer->unicode = unicode_funcs;
@@ -981,23 +912,23 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
/**
* hb_buffer_get_unicode_funcs:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the Unicode-functions structure of a buffer.
+ *
*
- * Return value: The Unicode-functions structure
+ * Return value:
*
* Since: 0.9.2
**/
hb_unicode_funcs_t *
-hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer)
+hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
{
return buffer->unicode;
}
/**
* hb_buffer_set_direction:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
* @direction: the #hb_direction_t of the @buffer
*
* Set the text flow direction of the buffer. No shaping can happen without
@@ -1013,8 +944,9 @@ hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer)
void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction)
+
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->props.direction = direction;
@@ -1022,7 +954,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
/**
* hb_buffer_get_direction:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* See hb_buffer_set_direction()
*
@@ -1032,15 +964,15 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_direction_t
-hb_buffer_get_direction (const hb_buffer_t *buffer)
+hb_buffer_get_direction (hb_buffer_t *buffer)
{
return buffer->props.direction;
}
/**
* hb_buffer_set_script:
- * @buffer: An #hb_buffer_t
- * @script: An #hb_script_t to set.
+ * @buffer: an #hb_buffer_t.
+ * @script: an #hb_script_t to set.
*
* Sets the script of @buffer to @script.
*
@@ -1050,7 +982,7 @@ hb_buffer_get_direction (const hb_buffer_t *buffer)
*
* You can pass one of the predefined #hb_script_t values, or use
* hb_script_from_string() or hb_script_from_iso15924_tag() to get the
- * corresponding script from an ISO 15924 script tag.
+ * corresponding script from an ISO 15924 script tag.
*
* Since: 0.9.2
**/
@@ -1058,7 +990,7 @@ void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->props.script = script;
@@ -1066,25 +998,25 @@ hb_buffer_set_script (hb_buffer_t *buffer,
/**
* hb_buffer_get_script:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the script of @buffer.
+ * See hb_buffer_set_script().
*
* Return value:
- * The #hb_script_t of the @buffer
+ * The #hb_script_t of the @buffer.
*
* Since: 0.9.2
**/
hb_script_t
-hb_buffer_get_script (const hb_buffer_t *buffer)
+hb_buffer_get_script (hb_buffer_t *buffer)
{
return buffer->props.script;
}
/**
* hb_buffer_set_language:
- * @buffer: An #hb_buffer_t
- * @language: An hb_language_t to set
+ * @buffer: an #hb_buffer_t.
+ * @language: an hb_language_t to set.
*
* Sets the language of @buffer to @language.
*
@@ -1093,7 +1025,7 @@ hb_buffer_get_script (const hb_buffer_t *buffer)
* are orthogonal to the scripts, and though they are related, they are
* different concepts and should not be confused with each other.
*
- * Use hb_language_from_string() to convert from BCP 47 language tags to
+ * Use hb_language_from_string() to convert from ISO 639 language codes to
* #hb_language_t.
*
* Since: 0.9.2
@@ -1102,7 +1034,7 @@ void
hb_buffer_set_language (hb_buffer_t *buffer,
hb_language_t language)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->props.language = language;
@@ -1110,7 +1042,7 @@ hb_buffer_set_language (hb_buffer_t *buffer,
/**
* hb_buffer_get_language:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* See hb_buffer_set_language().
*
@@ -1120,15 +1052,15 @@ hb_buffer_set_language (hb_buffer_t *buffer,
* Since: 0.9.2
**/
hb_language_t
-hb_buffer_get_language (const hb_buffer_t *buffer)
+hb_buffer_get_language (hb_buffer_t *buffer)
{
return buffer->props.language;
}
/**
* hb_buffer_set_segment_properties:
- * @buffer: An #hb_buffer_t
- * @props: An #hb_segment_properties_t to use
+ * @buffer: an #hb_buffer_t.
+ * @props: an #hb_segment_properties_t to use.
*
* Sets the segment properties of the buffer, a shortcut for calling
* hb_buffer_set_direction(), hb_buffer_set_script() and
@@ -1140,7 +1072,7 @@ void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->props = *props;
@@ -1148,15 +1080,15 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_get_segment_properties:
- * @buffer: An #hb_buffer_t
- * @props: (out): The output #hb_segment_properties_t
+ * @buffer: an #hb_buffer_t.
+ * @props: (out): the output #hb_segment_properties_t.
*
* Sets @props to the #hb_segment_properties_t of @buffer.
*
* Since: 0.9.7
**/
void
-hb_buffer_get_segment_properties (const hb_buffer_t *buffer,
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
hb_segment_properties_t *props)
{
*props = buffer->props;
@@ -1165,8 +1097,8 @@ hb_buffer_get_segment_properties (const hb_buffer_t *buffer,
/**
* hb_buffer_set_flags:
- * @buffer: An #hb_buffer_t
- * @flags: The buffer flags to set
+ * @buffer: an #hb_buffer_t.
+ * @flags: the buffer flags to set.
*
* Sets @buffer flags to @flags. See #hb_buffer_flags_t.
*
@@ -1176,7 +1108,7 @@ void
hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->flags = flags;
@@ -1184,37 +1116,35 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
/**
* hb_buffer_get_flags:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the #hb_buffer_flags_t of @buffer.
+ * See hb_buffer_set_flags().
*
- * Return value:
- * The @buffer flags
+ * Return value:
+ * The @buffer flags.
*
* Since: 0.9.7
**/
hb_buffer_flags_t
-hb_buffer_get_flags (const hb_buffer_t *buffer)
+hb_buffer_get_flags (hb_buffer_t *buffer)
{
return buffer->flags;
}
/**
* hb_buffer_set_cluster_level:
- * @buffer: An #hb_buffer_t
- * @cluster_level: The cluster level to set on the buffer
+ * @buffer: an #hb_buffer_t.
+ * @cluster_level:
*
- * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t
- * dictates one aspect of how HarfBuzz will treat non-base characters
- * during shaping.
+ *
*
* Since: 0.9.42
**/
void
-hb_buffer_set_cluster_level (hb_buffer_t *buffer,
- hb_buffer_cluster_level_t cluster_level)
+hb_buffer_set_cluster_level (hb_buffer_t *buffer,
+ hb_buffer_cluster_level_t cluster_level)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->cluster_level = cluster_level;
@@ -1222,18 +1152,16 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
/**
* hb_buffer_get_cluster_level:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t
- * dictates one aspect of how HarfBuzz will treat non-base characters
- * during shaping.
+ *
*
- * Return value: The cluster level of @buffer
+ * Return value:
*
* Since: 0.9.42
**/
hb_buffer_cluster_level_t
-hb_buffer_get_cluster_level (const hb_buffer_t *buffer)
+hb_buffer_get_cluster_level (hb_buffer_t *buffer)
{
return buffer->cluster_level;
}
@@ -1241,13 +1169,13 @@ hb_buffer_get_cluster_level (const hb_buffer_t *buffer)
/**
* hb_buffer_set_replacement_codepoint:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
* @replacement: the replacement #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
* when adding text to @buffer.
*
- * Default is #HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
+ * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
*
* Since: 0.9.31
**/
@@ -1255,7 +1183,7 @@ void
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
hb_codepoint_t replacement)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
buffer->replacement = replacement;
@@ -1263,106 +1191,40 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
/**
* hb_buffer_get_replacement_codepoint:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
- * Fetches the #hb_codepoint_t that replaces invalid entries for a given encoding
- * when adding text to @buffer.
+ * See hb_buffer_set_replacement_codepoint().
*
- * Return value:
- * The @buffer replacement #hb_codepoint_t
+ * Return value:
+ * The @buffer replacement #hb_codepoint_t.
*
* Since: 0.9.31
**/
hb_codepoint_t
-hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer)
+hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
{
return buffer->replacement;
}
/**
- * hb_buffer_set_invisible_glyph:
- * @buffer: An #hb_buffer_t
- * @invisible: the invisible #hb_codepoint_t
- *
- * Sets the #hb_codepoint_t that replaces invisible characters in
- * the shaping result. If set to zero (default), the glyph for the
- * U+0020 SPACE character is used. Otherwise, this value is used
- * verbatim.
- *
- * Since: 2.0.0
- **/
-void
-hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
- hb_codepoint_t invisible)
-{
- if (unlikely (hb_object_is_immutable (buffer)))
- return;
-
- buffer->invisible = invisible;
-}
-
-/**
- * hb_buffer_get_invisible_glyph:
- * @buffer: An #hb_buffer_t
- *
- * See hb_buffer_set_invisible_glyph().
- *
- * Return value:
- * The @buffer invisible #hb_codepoint_t
- *
- * Since: 2.0.0
- **/
-hb_codepoint_t
-hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer)
-{
- return buffer->invisible;
-}
-
-/**
- * hb_buffer_set_not_found_glyph:
- * @buffer: An #hb_buffer_t
- * @not_found: the not-found #hb_codepoint_t
- *
- * Sets the #hb_codepoint_t that replaces characters not found in
- * the font during shaping.
+ * hb_buffer_reset:
+ * @buffer: an #hb_buffer_t.
*
- * The not-found glyph defaults to zero, sometimes knows as the
- * ".notdef" glyph. This API allows for differentiating the two.
+ * Resets the buffer to its initial status, as if it was just newly created
+ * with hb_buffer_create().
*
- * Since: 3.1.0
+ * Since: 0.9.2
**/
void
-hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
- hb_codepoint_t not_found)
-{
- if (unlikely (hb_object_is_immutable (buffer)))
- return;
-
- buffer->not_found = not_found;
-}
-
-/**
- * hb_buffer_get_not_found_glyph:
- * @buffer: An #hb_buffer_t
- *
- * See hb_buffer_set_not_found_glyph().
- *
- * Return value:
- * The @buffer not-found #hb_codepoint_t
- *
- * Since: 3.1.0
- **/
-hb_codepoint_t
-hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer)
+hb_buffer_reset (hb_buffer_t *buffer)
{
- return buffer->not_found;
+ buffer->reset ();
}
-
/**
* hb_buffer_clear_contents:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Similar to hb_buffer_reset(), but does not clear the Unicode functions and
* the replacement code point.
@@ -1372,21 +1234,18 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer)
void
hb_buffer_clear_contents (hb_buffer_t *buffer)
{
- if (unlikely (hb_object_is_immutable (buffer)))
- return;
-
buffer->clear ();
}
/**
* hb_buffer_pre_allocate:
- * @buffer: An #hb_buffer_t
- * @size: Number of items to pre allocate.
+ * @buffer: an #hb_buffer_t.
+ * @size: number of items to pre allocate.
*
* Pre allocates memory for @buffer to fit at least @size number of items.
*
* Return value:
- * `true` if @buffer memory allocation succeeded, `false` otherwise
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
@@ -1398,26 +1257,26 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
/**
* hb_buffer_allocation_successful:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Check if allocating memory for the buffer succeeded.
*
* Return value:
- * `true` if @buffer memory allocation succeeded, `false` otherwise.
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t *buffer)
{
- return buffer->successful;
+ return !buffer->in_error;
}
/**
* hb_buffer_add:
- * @buffer: An #hb_buffer_t
- * @codepoint: A Unicode code point.
- * @cluster: The cluster value of @codepoint.
+ * @buffer: an #hb_buffer_t.
+ * @codepoint: a Unicode code point.
+ * @cluster: the cluster value of @codepoint.
*
* Appends a character with the Unicode value of @codepoint to @buffer, and
* gives it the initial cluster value of @cluster. Clusters can be any thing
@@ -1441,14 +1300,14 @@ hb_buffer_add (hb_buffer_t *buffer,
/**
* hb_buffer_set_length:
- * @buffer: An #hb_buffer_t
- * @length: The new length of @buffer
+ * @buffer: an #hb_buffer_t.
+ * @length: the new length of @buffer.
*
* Similar to hb_buffer_pre_allocate(), but clears any new items added at the
* end.
*
- * Return value:
- * `true` if @buffer memory allocation succeeded, `false` otherwise.
+ * Return value:
+ * %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
@@ -1456,17 +1315,17 @@ hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length)
{
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return length == 0;
- if (unlikely (!buffer->ensure (length)))
+ if (!buffer->ensure (length))
return false;
/* Wipe the new space */
if (length > buffer->len) {
- hb_memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+ memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
if (buffer->have_positions)
- hb_memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+ memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
}
buffer->len = length;
@@ -1483,7 +1342,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/**
* hb_buffer_get_length:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Returns the number of items in the buffer.
*
@@ -1494,15 +1353,15 @@ hb_buffer_set_length (hb_buffer_t *buffer,
* Since: 0.9.2
**/
unsigned int
-hb_buffer_get_length (const hb_buffer_t *buffer)
+hb_buffer_get_length (hb_buffer_t *buffer)
{
return buffer->len;
}
/**
* hb_buffer_get_glyph_infos:
- * @buffer: An #hb_buffer_t
- * @length: (out): The output-array length.
+ * @buffer: an #hb_buffer_t.
+ * @length: (out): output array length.
*
* Returns @buffer glyph information array. Returned pointer
* is valid as long as @buffer contents are not modified.
@@ -1515,7 +1374,7 @@ hb_buffer_get_length (const hb_buffer_t *buffer)
**/
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
- unsigned int *length)
+ unsigned int *length)
{
if (length)
*length = buffer->len;
@@ -1525,17 +1384,12 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
/**
* hb_buffer_get_glyph_positions:
- * @buffer: An #hb_buffer_t
- * @length: (out): The output length
+ * @buffer: an #hb_buffer_t.
+ * @length: (out): output length.
*
* Returns @buffer glyph position array. Returned pointer
* is valid as long as @buffer contents are not modified.
*
- * If buffer did not have positions before, the positions will be
- * initialized to zeros, unless this function is called from
- * within a buffer message callback (see hb_buffer_set_message_func()),
- * in which case `NULL` is returned.
- *
* Return value: (transfer none) (array length=length):
* The @buffer glyph position array.
* The value valid as long as buffer has not been modified.
@@ -1544,49 +1398,25 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
**/
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
- unsigned int *length)
+ unsigned int *length)
{
- if (length)
- *length = buffer->len;
-
if (!buffer->have_positions)
- {
- if (unlikely (buffer->message_depth))
- return nullptr;
-
buffer->clear_positions ();
- }
- return (hb_glyph_position_t *) buffer->pos;
-}
+ if (length)
+ *length = buffer->len;
-/**
- * hb_buffer_has_positions:
- * @buffer: an #hb_buffer_t.
- *
- * Returns whether @buffer has glyph position data.
- * A buffer gains position data when hb_buffer_get_glyph_positions() is called on it,
- * and cleared of position data when hb_buffer_clear_contents() is called.
- *
- * Return value:
- * `true` if the @buffer has position array, `false` otherwise.
- *
- * Since: 2.7.3
- **/
-HB_EXTERN hb_bool_t
-hb_buffer_has_positions (hb_buffer_t *buffer)
-{
- return buffer->have_positions;
+ return (hb_glyph_position_t *) buffer->pos;
}
/**
* hb_glyph_info_get_glyph_flags:
- * @info: a #hb_glyph_info_t
+ * @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
+ * The #hb_glyph_flags_t encoded within @info.
*
* Since: 1.5.0
**/
@@ -1598,7 +1428,7 @@ hb_glyph_flags_t
/**
* hb_buffer_reverse:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Reverses buffer contents.
*
@@ -1612,11 +1442,11 @@ hb_buffer_reverse (hb_buffer_t *buffer)
/**
* hb_buffer_reverse_range:
- * @buffer: An #hb_buffer_t
- * @start: start index
- * @end: end index
+ * @buffer: an #hb_buffer_t.
+ * @start: start index.
+ * @end: end index.
*
- * Reverses buffer contents between @start and @end.
+ * Reverses buffer contents between start to end.
*
* Since: 0.9.41
**/
@@ -1629,7 +1459,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer,
/**
* hb_buffer_reverse_clusters:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Reverses buffer clusters. That is, the buffer contents are
* reversed, then each cluster (consecutive items having the
@@ -1645,29 +1475,25 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
/**
* hb_buffer_guess_segment_properties:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Sets unset buffer segment properties based on buffer Unicode
* contents. If buffer is not empty, it must have content type
- * #HB_BUFFER_CONTENT_TYPE_UNICODE.
+ * %HB_BUFFER_CONTENT_TYPE_UNICODE.
*
- * If buffer script is not set (ie. is #HB_SCRIPT_INVALID), it
+ * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
* will be set to the Unicode script of the first character in
- * the buffer that has a script other than #HB_SCRIPT_COMMON,
- * #HB_SCRIPT_INHERITED, and #HB_SCRIPT_UNKNOWN.
+ * the buffer that has a script other than %HB_SCRIPT_COMMON,
+ * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
*
- * Next, if buffer direction is not set (ie. is #HB_DIRECTION_INVALID),
+ * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
* it will be set to the natural horizontal direction of the
* buffer script as returned by hb_script_get_horizontal_direction().
- * If hb_script_get_horizontal_direction() returns #HB_DIRECTION_INVALID,
- * then #HB_DIRECTION_LTR is used.
*
- * Finally, if buffer language is not set (ie. is #HB_LANGUAGE_INVALID),
+ * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
* it will be set to the process's default language as returned by
* hb_language_get_default(). This may change in the future by
* taking buffer script into consideration when choosing a language.
- * Note that hb_language_get_default() is NOT threadsafe the first time
- * it is called. See documentation for that function for details.
*
* Since: 0.9.7
**/
@@ -1688,9 +1514,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
typedef typename utf_t::codepoint_t T;
const hb_codepoint_t replacement = buffer->replacement;
- buffer->assert_unicode ();
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
- if (unlikely (hb_object_is_immutable (buffer)))
+ if (unlikely (hb_object_is_inert (buffer)))
return;
if (text_length == -1)
@@ -1699,10 +1526,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
if (item_length == -1)
item_length = text_length - item_offset;
- if (unlikely (item_length < 0 ||
- item_length > INT_MAX / 8 ||
- !buffer->ensure (buffer->len + item_length * sizeof (T) / 4)))
- return;
+ buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
/* If buffer is empty and pre-context provided, install it.
* This check is written this way, to make sure people can
@@ -1750,13 +1574,13 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf8:
- * @buffer: An #hb_buffer_t
- * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
* characters to append.
- * @text_length: The length of the @text, or -1 if it is `NULL` terminated.
- * @item_offset: The offset of the first character to add to the @buffer.
- * @item_length: The number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is `NULL` terminated).
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
* See hb_buffer_add_codepoints().
*
@@ -1777,12 +1601,12 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf16:
- * @buffer: An #hb_buffer_t
- * @text: (array length=text_length): An array of UTF-16 characters to append
- * @text_length: The length of the @text, or -1 if it is `NULL` terminated
- * @item_offset: The offset of the first character to add to the @buffer
- * @item_length: The number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is `NULL` terminated)
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length): an array of UTF-16 characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
* See hb_buffer_add_codepoints().
*
@@ -1803,12 +1627,12 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf32:
- * @buffer: An #hb_buffer_t
- * @text: (array length=text_length): An array of UTF-32 characters to append
- * @text_length: The length of the @text, or -1 if it is `NULL` terminated
- * @item_offset: The offset of the first character to add to the @buffer
- * @item_length: The number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is `NULL` terminated)
+ * @buffer: an #hb_buffer_t.
+ * @text: (array length=text_length): an array of UTF-32 characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
+ * @item_length: the number of characters to add to the @buffer, or -1 for the
+ * end of @text (assuming it is %NULL terminated).
*
* See hb_buffer_add_codepoints().
*
@@ -1824,18 +1648,18 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length)
{
- hb_buffer_add_utf<hb_utf32_t> (buffer, text, text_length, item_offset, item_length);
+ hb_buffer_add_utf<hb_utf32_t<> > (buffer, text, text_length, item_offset, item_length);
}
/**
* hb_buffer_add_latin1:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
- * characters to append
- * @text_length: the length of the @text, or -1 if it is `NULL` terminated
- * @item_offset: the offset of the first character to add to the @buffer
+ * characters to append.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
+ * @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
- * end of @text (assuming it is `NULL` terminated)
+ * end of @text (assuming it is %NULL terminated).
*
* Similar to hb_buffer_add_codepoints(), but allows only access to first 256
* Unicode code points that can fit in 8-bit strings.
@@ -1858,10 +1682,10 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer,
* hb_buffer_add_codepoints:
* @buffer: a #hb_buffer_t to append characters to.
* @text: (array length=text_length): an array of Unicode code points to append.
- * @text_length: the length of the @text, or -1 if it is `NULL` terminated.
+ * @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first code point to add to the @buffer.
* @item_length: the number of code points to add to the @buffer, or -1 for the
- * end of @text (assuming it is `NULL` terminated).
+ * end of @text (assuming it is %NULL terminated).
*
* Appends characters from @text array to @buffer. The @item_offset is the
* position of the first character from @text that will be appended, and
@@ -1874,9 +1698,7 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer,
* marks at stat of run.
*
* This function does not check the validity of @text, it is up to the caller
- * to ensure it contains a valid Unicode scalar values. In contrast,
- * hb_buffer_add_utf32() can be used that takes similar input but performs
- * sanity-check on the input.
+ * to ensure it contains a valid Unicode code points.
*
* Since: 0.9.31
**/
@@ -1887,16 +1709,16 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length)
{
- hb_buffer_add_utf<hb_utf32_novalidate_t> (buffer, text, text_length, item_offset, item_length);
+ hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length);
}
/**
* hb_buffer_append:
- * @buffer: An #hb_buffer_t
- * @source: source #hb_buffer_t
+ * @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 @HB_FEATURE_GLOBAL_END to copy to end 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.
*
@@ -1904,7 +1726,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
**/
HB_EXTERN void
hb_buffer_append (hb_buffer_t *buffer,
- const hb_buffer_t *source,
+ hb_buffer_t *source,
unsigned int start,
unsigned int end)
{
@@ -1921,49 +1743,25 @@ hb_buffer_append (hb_buffer_t *buffer,
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->successful = false;
+ buffer->in_error = true;
return;
}
unsigned int orig_len = buffer->len;
hb_buffer_set_length (buffer, buffer->len + (end - start));
- if (unlikely (!buffer->successful))
+ if (buffer->in_error)
return;
- if (!orig_len)
- buffer->content_type = source->content_type;
- if (!buffer->have_positions && source->have_positions)
- buffer->clear_positions ();
-
- hb_segment_properties_overlay (&buffer->props, &source->props);
-
- hb_memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
+ memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
if (buffer->have_positions)
- hb_memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
-
- if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
- {
- /* See similar logic in add_utf. */
-
- /* pre-context */
- if (!orig_len && start + source->context_len[0] > 0)
- {
- buffer->clear_context (0);
- while (start > 0 && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
- buffer->context[0][buffer->context_len[0]++] = source->info[--start].codepoint;
- for (auto i = 0u; i < source->context_len[0] && buffer->context_len[0] < buffer->CONTEXT_LENGTH; i++)
- buffer->context[0][buffer->context_len[0]++] = source->context[0][i];
- }
-
- /* post-context */
- buffer->clear_context (1);
- while (end < source->len && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
- buffer->context[1][buffer->context_len[1]++] = source->info[end++].codepoint;
- for (auto i = 0u; i < source->context_len[1] && buffer->context_len[1] < buffer->CONTEXT_LENGTH; i++)
- buffer->context[1][buffer->context_len[1]++] = source->context[1][i];
- }
+ memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
}
@@ -2024,7 +1822,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
/**
* hb_buffer_normalize_glyphs:
- * @buffer: An #hb_buffer_t
+ * @buffer: an #hb_buffer_t.
*
* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
* The resulting clusters should behave identical to pre-reordering clusters.
@@ -2037,13 +1835,23 @@ void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
assert (buffer->have_positions);
-
- buffer->assert_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);
- foreach_cluster (buffer, start, end)
- normalize_glyphs_cluster (buffer, start, end, backward);
+ unsigned int count = buffer->len;
+ if (unlikely (!count)) return;
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int start = 0;
+ unsigned int end;
+ for (end = start + 1; end < count; end++)
+ if (info[start].cluster != info[end].cluster) {
+ normalize_glyphs_cluster (buffer, start, end, backward);
+ start = end;
+ }
+ normalize_glyphs_cluster (buffer, start, end, backward);
}
void
@@ -2074,13 +1882,9 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g
/**
* hb_buffer_diff:
- * @buffer: a buffer.
- * @reference: other buffer to compare to.
- * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
- * @position_fuzz: allowed absolute difference in position values.
*
- * 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
+ * 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
@@ -2110,9 +1914,9 @@ hb_buffer_diff (hb_buffer_t *buffer,
for (i = 0; i < count; i++)
{
if (contains && info[i].codepoint == dottedcircle_glyph)
- result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
+ 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_NOTDEF_PRESENT;
}
result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
return hb_buffer_diff_flags_t (result);
@@ -2129,7 +1933,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
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 ^ ref_info->mask) & HB_GLYPH_FLAG_DEFINED)
+ 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;
@@ -2147,12 +1951,12 @@ hb_buffer_diff (hb_buffer_t *buffer,
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)
+ (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;
+ result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
+ break;
}
buf_pos++;
ref_pos++;
@@ -2167,15 +1971,14 @@ hb_buffer_diff (hb_buffer_t *buffer,
* Debugging.
*/
-#ifndef HB_NO_BUFFER_MESSAGE
/**
* hb_buffer_set_message_func:
- * @buffer: An #hb_buffer_t
- * @func: (closure user_data) (destroy destroy) (scope notified): Callback function
- * @user_data: (nullable): Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @buffer: an #hb_buffer_t.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_buffer_message_func_t.
+ *
*
* Since: 1.1.3
**/
@@ -2184,13 +1987,6 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
hb_buffer_message_func_t func,
void *user_data, hb_destroy_func_t destroy)
{
- if (unlikely (hb_object_is_immutable (buffer)))
- {
- if (destroy)
- destroy (user_data);
- return;
- }
-
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
@@ -2204,19 +2000,11 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
buffer->message_destroy = nullptr;
}
}
+
bool
hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
{
- assert (!have_output || (out_info == info && out_len == idx));
-
- message_depth++;
-
char buf[100];
- vsnprintf (buf, sizeof (buf), fmt, ap);
- bool ret = (bool) this->message_func (this, font, buf, this->message_data);
-
- message_depth--;
-
- return ret;
+ vsnprintf (buf, sizeof (buf), fmt, ap);
+ return (bool) this->message_func (this, font, buf, this->message_data);
}
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
index bff78543c87..a8a4b84e97b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
@@ -27,7 +27,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -44,6 +44,7 @@ HB_BEGIN_DECLS
* hb_glyph_info_t:
* @codepoint: either a Unicode code point (before shaping) or a glyph index
* (after shaping).
+ * @mask:
* @cluster: the index of the character in the original text that corresponds
* to this #hb_glyph_info_t, or whatever the client passes to
* hb_buffer_add(). More than one #hb_glyph_info_t can have the same
@@ -58,12 +59,11 @@ HB_BEGIN_DECLS
*
* The #hb_glyph_info_t is the structure that holds information about the
* glyphs and their relation to input text.
+ *
*/
typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
- /*< private >*/
- hb_mask_t mask;
- /*< public >*/
+ hb_mask_t mask; /* Holds hb_glyph_flags_t after hb_shape(), plus other things. */
uint32_t cluster;
/*< private >*/
@@ -71,98 +71,10 @@ typedef struct hb_glyph_info_t {
hb_var_int_t var2;
} hb_glyph_info_t;
-/**
- * hb_glyph_flags_t:
- * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
- * beginning of the cluster this glyph is part of,
- * then both sides need to be re-shaped, as the
- * result might be different.
- * On the flip side, it means that when this
- * flag is not present, then it is safe to break
- * the glyph-run at the beginning of this
- * cluster, and the two sides will represent the
- * exact same result one would get if breaking
- * input text at the beginning of this cluster
- * and shaping the two sides separately.
- * This can be used to optimize paragraph
- * layout, by avoiding re-shaping of each line
- * after line-breaking.
- * @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT: Indicates that if input text is changed on one
- * side of the beginning of the cluster this glyph
- * is part of, then the shaping results for the
- * other side might change.
- * Note that the absence of this flag will NOT by
- * itself mean that it IS safe to concat text.
- * Only two pieces of text both of which clear of
- * this flag can be concatenated safely.
- * This can be used to optimize paragraph
- * layout, by avoiding re-shaping of each line
- * after line-breaking, by limiting the
- * reshaping to a small piece around the
- * breaking positin only, even if the breaking
- * position carries the
- * #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
- * hyphenation or other text transformation
- * happens at line-break position, in the following
- * way:
- * 1. Iterate back from the line-break position
- * until the first cluster start position that is
- * NOT unsafe-to-concat, 2. shape the segment from
- * there till the end of line, 3. check whether the
- * resulting glyph-run also is clear of the
- * unsafe-to-concat at its start-of-text position;
- * if it is, just splice it into place and the line
- * is shaped; If not, move on to a position further
- * back that is clear of unsafe-to-concat and retry
- * from there, and repeat.
- * At the start of next line a similar algorithm can
- * be implemented. That is: 1. Iterate forward from
- * the line-break position until the first cluster
- * start position that is NOT unsafe-to-concat, 2.
- * shape the segment from beginning of the line to
- * that position, 3. check whether the resulting
- * glyph-run also is clear of the unsafe-to-concat
- * at its end-of-text position; if it is, just splice
- * it into place and the beginning is shaped; If not,
- * move on to a position further forward that is clear
- * of unsafe-to-concat and retry up to there, and repeat.
- * A slight complication will arise in the
- * implementation of the algorithm above,
- * because while our buffer API has a way to
- * return flags for position corresponding to
- * start-of-text, there is currently no position
- * corresponding to end-of-text. This limitation
- * can be alleviated by shaping more text than needed
- * and looking for unsafe-to-concat flag within text
- * clusters.
- * The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
- * always imply this flag.
- * To use this flag, you must enable the buffer flag
- * @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT during
- * shaping, otherwise the buffer flag will not be
- * reliably produced.
- * Since: 4.0.0
- * @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL: In scripts that use elongation (Arabic,
- Mongolian, Syriac, etc.), this flag signifies
- that it is safe to insert a U+0640 TATWEEL
- character before this cluster for elongation.
- This flag does not determine the
- script-specific elongation places, but only
- when it is safe to do the elongation without
- interrupting text shaping.
- Since: 5.1.0
- * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
- *
- * Flags for #hb_glyph_info_t.
- *
- * Since: 1.5.0
- */
typedef enum { /*< flags >*/
- HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
- HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002,
- HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL = 0x00000004,
+ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
- HB_GLYPH_FLAG_DEFINED = 0x00000007 /* OR of all defined flags */
+ HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
} hb_glyph_flags_t;
HB_EXTERN hb_glyph_flags_t
@@ -217,11 +129,6 @@ typedef struct hb_segment_properties_t {
void *reserved2;
} hb_segment_properties_t;
-/**
- * HB_SEGMENT_PROPERTIES_DEFAULT:
- *
- * The default #hb_segment_properties_t of of freshly created #hb_buffer_t.
- */
#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
HB_SCRIPT_INVALID, \
HB_LANGUAGE_INVALID, \
@@ -235,9 +142,6 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
HB_EXTERN unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p);
-HB_EXTERN void
-hb_segment_properties_overlay (hb_segment_properties_t *p,
- const hb_segment_properties_t *src);
/**
@@ -253,13 +157,6 @@ HB_EXTERN hb_buffer_t *
hb_buffer_create (void);
HB_EXTERN hb_buffer_t *
-hb_buffer_create_similar (const hb_buffer_t *src);
-
-HB_EXTERN void
-hb_buffer_reset (hb_buffer_t *buffer);
-
-
-HB_EXTERN hb_buffer_t *
hb_buffer_get_empty (void);
HB_EXTERN hb_buffer_t *
@@ -276,7 +173,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
hb_bool_t replace);
HB_EXTERN void *
-hb_buffer_get_user_data (const hb_buffer_t *buffer,
+hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key);
@@ -285,8 +182,6 @@ hb_buffer_get_user_data (const hb_buffer_t *buffer,
* @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer.
* @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping).
* @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping).
- *
- * The type of #hb_buffer_t contents.
*/
typedef enum {
HB_BUFFER_CONTENT_TYPE_INVALID = 0,
@@ -299,7 +194,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type);
HB_EXTERN hb_buffer_content_type_t
-hb_buffer_get_content_type (const hb_buffer_t *buffer);
+hb_buffer_get_content_type (hb_buffer_t *buffer);
HB_EXTERN void
@@ -307,21 +202,21 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
hb_unicode_funcs_t *unicode_funcs);
HB_EXTERN hb_unicode_funcs_t *
-hb_buffer_get_unicode_funcs (const hb_buffer_t *buffer);
+hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction);
HB_EXTERN hb_direction_t
-hb_buffer_get_direction (const hb_buffer_t *buffer);
+hb_buffer_get_direction (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script);
HB_EXTERN hb_script_t
-hb_buffer_get_script (const hb_buffer_t *buffer);
+hb_buffer_get_script (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_language (hb_buffer_t *buffer,
@@ -329,14 +224,14 @@ hb_buffer_set_language (hb_buffer_t *buffer,
HB_EXTERN hb_language_t
-hb_buffer_get_language (const hb_buffer_t *buffer);
+hb_buffer_get_language (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props);
HB_EXTERN void
-hb_buffer_get_segment_properties (const hb_buffer_t *buffer,
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
hb_segment_properties_t *props);
HB_EXTERN void
@@ -352,44 +247,13 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
* of the text without the full context.
* @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text
* paragraph can be applied to this buffer, similar to
- * @HB_BUFFER_FLAG_BOT.
+ * @HB_BUFFER_FLAG_EOT.
* @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES:
* flag indication that character with Default_Ignorable
* Unicode property should use the corresponding glyph
- * from the font, instead of hiding them (done by
- * replacing them with the space glyph and zeroing the
- * advance width.) This flag takes precedence over
- * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES.
- * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES:
- * flag indication that character with Default_Ignorable
- * Unicode property should be removed from glyph string
- * instead of hiding them (done by replacing them with the
- * space glyph and zeroing the advance width.)
- * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES takes
- * precedence over this flag. Since: 1.8.0
- * @HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE:
- * flag indicating that a dotted circle should
- * not be inserted in the rendering of incorrect
- * character sequences (such at <0905 093E>). Since: 2.4.0
- * @HB_BUFFER_FLAG_VERIFY:
- * flag indicating that the hb_shape() call and its variants
- * should perform various verification processes on the results
- * of the shaping operation on the buffer. If the verification
- * fails, then either a buffer message is sent, if a message
- * handler is installed on the buffer, or a message is written
- * to standard error. In either case, the shaping result might
- * be modified to show the failed output. Since: 3.4.0
- * @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT:
- * flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
- * glyph-flag should be produced by the shaper. By default
- * it will not be produced since it incurs a cost. Since: 4.0.0
- * @HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL:
- * flag indicating that the @HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL
- * glyph-flag should be produced by the shaper. By default
- * it will not be produced. Since: 5.1.0
- * @HB_BUFFER_FLAG_DEFINED: All currently defined flags: Since: 4.4.0
- *
- * Flags for #hb_buffer_t.
+ * from the font, instead of hiding them (currently done
+ * by replacing them with the space glyph and zeroing the
+ * advance width.)
*
* Since: 0.9.20
*/
@@ -397,14 +261,7 @@ typedef enum { /*< flags >*/
HB_BUFFER_FLAG_DEFAULT = 0x00000000u,
HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
- HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u,
- HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u,
- HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u,
- HB_BUFFER_FLAG_VERIFY = 0x00000020u,
- HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u,
- HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL = 0x00000080u,
-
- HB_BUFFER_FLAG_DEFINED = 0x000000FFu
+ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
} hb_buffer_flags_t;
HB_EXTERN void
@@ -412,34 +269,9 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags);
HB_EXTERN hb_buffer_flags_t
-hb_buffer_get_flags (const hb_buffer_t *buffer);
+hb_buffer_get_flags (hb_buffer_t *buffer);
-/**
- * hb_buffer_cluster_level_t:
- * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: Return cluster values grouped by graphemes into
- * monotone order.
- * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: Return cluster values grouped into monotone order.
- * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values.
- * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level,
- * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES.
- *
- * Data type for holding HarfBuzz's clustering behavior options. The cluster level
- * dictates one aspect of how HarfBuzz will treat non-base characters
- * during shaping.
- *
- * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base
- * characters are merged into the cluster of the base character that precedes them.
- *
- * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially
- * assigned their own cluster values, which are not merged into preceding base
- * clusters. This allows HarfBuzz to perform additional operations like reorder
- * sequences of adjacent marks.
- *
- * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains
- * backward compatibility with older versions of HarfBuzz. New client programs that
- * do not need to maintain such backward compatibility are recommended to use
- * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS instead of the default.
- *
+/*
* Since: 0.9.42
*/
typedef enum {
@@ -454,7 +286,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
hb_buffer_cluster_level_t cluster_level);
HB_EXTERN hb_buffer_cluster_level_t
-hb_buffer_get_cluster_level (const hb_buffer_t *buffer);
+hb_buffer_get_cluster_level (hb_buffer_t *buffer);
/**
* HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT:
@@ -471,33 +303,18 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
hb_codepoint_t replacement);
HB_EXTERN hb_codepoint_t
-hb_buffer_get_replacement_codepoint (const hb_buffer_t *buffer);
+hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
-HB_EXTERN void
-hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
- hb_codepoint_t invisible);
-
-HB_EXTERN hb_codepoint_t
-hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer);
HB_EXTERN void
-hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
- hb_codepoint_t not_found);
-
-HB_EXTERN hb_codepoint_t
-hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer);
-
-
-/*
- * Content API.
- */
+hb_buffer_reset (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_clear_contents (hb_buffer_t *buffer);
HB_EXTERN hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer,
- unsigned int size);
+ unsigned int size);
HB_EXTERN hb_bool_t
@@ -558,7 +375,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
HB_EXTERN void
hb_buffer_append (hb_buffer_t *buffer,
- const hb_buffer_t *source,
+ hb_buffer_t *source,
unsigned int start,
unsigned int end);
@@ -567,20 +384,17 @@ hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length);
HB_EXTERN unsigned int
-hb_buffer_get_length (const hb_buffer_t *buffer);
+hb_buffer_get_length (hb_buffer_t *buffer);
/* Getting glyphs out of the buffer */
HB_EXTERN hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
- unsigned int *length);
+ unsigned int *length);
HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
- unsigned int *length);
-
-HB_EXTERN hb_bool_t
-hb_buffer_has_positions (hb_buffer_t *buffer);
+ unsigned int *length);
HB_EXTERN void
@@ -598,10 +412,6 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
* @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information.
* @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name.
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents.
- * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0
- * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances,
- * glyph offsets will reflect absolute glyph positions. Since: 1.8.0
- * @HB_BUFFER_SERIALIZE_FLAG_DEFINED: All currently defined flags. Since: 4.4.0
*
* Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
*
@@ -613,10 +423,7 @@ typedef enum { /*< flags >*/
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_FLAGS = 0x00000010u,
- HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u,
-
- HB_BUFFER_SERIALIZE_FLAG_DEFINED = 0x0000003Fu
+ HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u
} hb_buffer_serialize_flags_t;
/**
@@ -656,27 +463,6 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
-HB_EXTERN unsigned int
-hb_buffer_serialize_unicode (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags);
-
-HB_EXTERN unsigned int
-hb_buffer_serialize (hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end,
- char *buf,
- unsigned int buf_size,
- unsigned int *buf_consumed,
- hb_font_t *font,
- hb_buffer_serialize_format_t format,
- hb_buffer_serialize_flags_t flags);
-
HB_EXTERN hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
@@ -685,48 +471,11 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font,
hb_buffer_serialize_format_t format);
-HB_EXTERN hb_bool_t
-hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
- const char *buf,
- int buf_len,
- const char **end_ptr,
- hb_buffer_serialize_format_t format);
-
-
/*
* Compare buffers
*/
-/**
- * hb_buffer_diff_flags_t:
- * @HB_BUFFER_DIFF_FLAG_EQUAL: equal buffers.
- * @HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH: buffers with different
- * #hb_buffer_content_type_t.
- * @HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH: buffers with differing length.
- * @HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT: `.notdef` glyph is present in the
- * reference buffer.
- * @HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT: dotted circle glyph is present
- * in the reference buffer.
- * @HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH: difference in #hb_glyph_info_t.codepoint
- * @HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH: difference in #hb_glyph_info_t.cluster
- * @HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH: difference in #hb_glyph_flags_t.
- * @HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH: difference in #hb_glyph_position_t.
- *
- * Flags from comparing two #hb_buffer_t's.
- *
- * Buffer with different #hb_buffer_content_type_t cannot be meaningfully
- * compared in any further detail.
- *
- * For buffers with differing length, the per-glyph comparison is not
- * attempted, though we do still scan reference buffer for dotted circle and
- * `.notdef` glyphs.
- *
- * 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.
- *
- * Since: 1.5.0
- */
typedef enum { /*< flags >*/
HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000,
@@ -763,26 +512,9 @@ hb_buffer_diff (hb_buffer_t *buffer,
/*
- * Tracing.
+ * Debugging.
*/
-/**
- * hb_buffer_message_func_t:
- * @buffer: An #hb_buffer_t to work upon
- * @font: The #hb_font_t the @buffer is shaped with
- * @message: `NULL`-terminated message passed to the function
- * @user_data: User data pointer passed by the caller
- *
- * A callback method for #hb_buffer_t. The method gets called with the
- * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a
- * message describing what step of the shaping process will be performed.
- * Returning `false` from this method will skip this shaping step and move to
- * the next one.
- *
- * Return value: `true` to perform the shaping step, `false` to skip it.
- *
- * Since: 1.1.3
- */
typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer,
hb_font_t *font,
const char *message,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh
deleted file mode 100644
index 5a43cabcb75..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * Copyright © 1998-2004 David Turner and Werner Lemberg
- * Copyright © 2004,2007,2009,2010 Red Hat, Inc.
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_BUFFER_HH
-#define HB_BUFFER_HH
-
-#include "hb.hh"
-#include "hb-unicode.hh"
-#include "hb-set-digest.hh"
-
-
-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_glyph_flags_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,
- HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u,
- 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_CGJ = 0x00000010u,
- HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u,
- HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u,
-
- /* Reserved for shapers' internal use. */
- HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u,
- HB_BUFFER_SCRATCH_FLAG_SHAPER1 = 0x02000000u,
- HB_BUFFER_SCRATCH_FLAG_SHAPER2 = 0x04000000u,
- HB_BUFFER_SCRATCH_FLAG_SHAPER3 = 0x08000000u,
-};
-HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
-
-
-/*
- * hb_buffer_t
- */
-
-struct hb_buffer_t
-{
- hb_object_header_t header;
-
- /*
- * Information about how the text in the buffer should be treated.
- */
-
- hb_unicode_funcs_t *unicode; /* Unicode functions */
- hb_buffer_flags_t flags; /* BOT / EOT / etc. */
- hb_buffer_cluster_level_t cluster_level;
- hb_codepoint_t replacement; /* U+FFFD or something else. */
- hb_codepoint_t invisible; /* 0 or something else. */
- hb_codepoint_t not_found; /* 0 or something else. */
-
- /*
- * Buffer contents
- */
-
- hb_buffer_content_type_t content_type;
- hb_segment_properties_t props; /* Script, language, direction */
-
- bool successful; /* Allocations successful */
- bool shaping_failed; /* Shaping failure */
- bool have_output; /* Whether we have an output buffer going on */
- bool have_positions; /* Whether we have positions */
-
- unsigned int idx; /* Cursor into ->info and ->pos arrays */
- unsigned int len; /* Length of ->info and ->pos arrays */
- unsigned int out_len; /* Length of ->out_info array if have_output */
-
- unsigned int allocated; /* Length of allocated arrays */
- hb_glyph_info_t *info;
- hb_glyph_info_t *out_info;
- hb_glyph_position_t *pos;
-
- /* Text before / after the main buffer contents.
- * Always in Unicode, and ordered outward.
- * Index 0 is for "pre-context", 1 for "post-context". */
- static constexpr unsigned CONTEXT_LENGTH = 5u;
- hb_codepoint_t context[2][CONTEXT_LENGTH];
- unsigned int context_len[2];
-
-
- /*
- * Managed by enter / leave
- */
-
- uint8_t allocated_var_bits;
- uint8_t serial;
- hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
- unsigned int max_len; /* Maximum allowed len. */
- int max_ops; /* Maximum allowed operations. */
- /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
-
-
- /*
- * Messaging callback
- */
-
-#ifndef HB_NO_BUFFER_MESSAGE
- hb_buffer_message_func_t message_func;
- void *message_data;
- hb_destroy_func_t message_destroy;
- unsigned message_depth; /* How deeply are we inside a message callback? */
-#else
- static constexpr unsigned message_depth = 0u;
-#endif
-
-
-
- /* Methods */
-
- HB_NODISCARD bool in_error () const { return !successful; }
-
- void allocate_var (unsigned int start, unsigned int count)
- {
- unsigned int end = start + count;
- assert (end <= 8);
- unsigned int bits = (1u<<end) - (1u<<start);
- assert (0 == (allocated_var_bits & bits));
- allocated_var_bits |= bits;
- }
- bool try_allocate_var (unsigned int start, unsigned int count)
- {
- unsigned int end = start + count;
- assert (end <= 8);
- unsigned int bits = (1u<<end) - (1u<<start);
- if (allocated_var_bits & bits)
- return false;
- allocated_var_bits |= bits;
- return true;
- }
- void deallocate_var (unsigned int start, unsigned int count)
- {
- unsigned int end = start + count;
- assert (end <= 8);
- unsigned int bits = (1u<<end) - (1u<<start);
- assert (bits == (allocated_var_bits & bits));
- allocated_var_bits &= ~bits;
- }
- void assert_var (unsigned int start, unsigned int count)
- {
- unsigned int end = start + count;
- assert (end <= 8);
- HB_UNUSED unsigned int bits = (1u<<end) - (1u<<start);
- assert (bits == (allocated_var_bits & bits));
- }
- void deallocate_var_all ()
- {
- allocated_var_bits = 0;
- }
-
- hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
- hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
-
- hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
- hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
-
- hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
- hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
-
- hb_set_digest_t digest () const
- {
- hb_set_digest_t d;
- d.init ();
- d.add_array (&info[0].codepoint, len, sizeof (info[0]));
- return d;
- }
-
- HB_INTERNAL void similar (const hb_buffer_t &src);
- HB_INTERNAL void reset ();
- HB_INTERNAL void clear ();
-
- /* Called around shape() */
- HB_INTERNAL void enter ();
- HB_INTERNAL void leave ();
-
-#ifndef HB_NO_BUFFER_VERIFY
- HB_INTERNAL
-#endif
- bool verify (hb_buffer_t *text_buffer,
- hb_font_t *font,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shapers)
-#ifndef HB_NO_BUFFER_VERIFY
- ;
-#else
- { return true; }
-#endif
-
- unsigned int backtrack_len () const { return have_output ? out_len : idx; }
- unsigned int lookahead_len () const { return len - idx; }
- uint8_t next_serial () { return ++serial ? serial : ++serial; }
-
- HB_INTERNAL void add (hb_codepoint_t codepoint,
- unsigned int cluster);
- HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
-
- void reverse_range (unsigned start, unsigned end)
- {
- hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
- if (have_positions)
- hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
- }
- void reverse () { reverse_range (0, len); }
-
- template <typename FuncType>
- void reverse_groups (const FuncType& group,
- bool merge_clusters = false)
- {
- if (unlikely (!len))
- return;
-
- unsigned start = 0;
- unsigned i;
- for (i = 1; i < len; i++)
- {
- if (!group (info[i - 1], info[i]))
- {
- if (merge_clusters)
- this->merge_clusters (start, i);
- reverse_range (start, i);
- start = i;
- }
- }
- if (merge_clusters)
- this->merge_clusters (start, i);
- reverse_range (start, i);
-
- reverse ();
- }
-
- template <typename FuncType>
- unsigned group_end (unsigned start, const FuncType& group) const
- {
- while (++start < len && group (info[start - 1], info[start]))
- ;
-
- return start;
- }
-
- static bool _cluster_group_func (const hb_glyph_info_t& a,
- const hb_glyph_info_t& b)
- { return a.cluster == b.cluster; }
-
- void reverse_clusters () { reverse_groups (_cluster_group_func); }
-
- HB_INTERNAL void guess_segment_properties ();
-
- HB_INTERNAL bool sync ();
- HB_INTERNAL int sync_so_far ();
- HB_INTERNAL void clear_output ();
- HB_INTERNAL void clear_positions ();
-
- template <typename T>
- HB_NODISCARD bool replace_glyphs (unsigned int num_in,
- unsigned int num_out,
- const T *glyph_data)
- {
- if (unlikely (!make_room_for (num_in, num_out))) return false;
-
- assert (idx + num_in <= len);
-
- merge_clusters (idx, idx + num_in);
-
- hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
-
- hb_glyph_info_t *pinfo = &out_info[out_len];
- for (unsigned int i = 0; i < num_out; i++)
- {
- *pinfo = orig_info;
- pinfo->codepoint = glyph_data[i];
- pinfo++;
- }
-
- idx += num_in;
- out_len += num_out;
- return true;
- }
-
- HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index)
- { return replace_glyphs (1, 1, &glyph_index); }
-
- /* Makes a copy of the glyph at idx to output and replace glyph_index */
- HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index)
- { return replace_glyphs (0, 1, &glyph_index); }
-
- HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info)
- {
- if (unlikely (!make_room_for (0, 1))) return false;
-
- out_info[out_len] = glyph_info;
-
- out_len++;
- return true;
- }
- /* Copies glyph at idx to output but doesn't advance idx */
- HB_NODISCARD bool copy_glyph ()
- {
- /* Extra copy because cur()'s return can be freed within
- * output_info() call if buffer reallocates. */
- return output_info (hb_glyph_info_t (cur()));
- }
-
- /* Copies glyph at idx to output and advance idx.
- * If there's no output, just advance idx. */
- HB_NODISCARD bool next_glyph ()
- {
- if (have_output)
- {
- if (out_info != info || out_len != idx)
- {
- if (unlikely (!make_room_for (1, 1))) return false;
- out_info[out_len] = info[idx];
- }
- out_len++;
- }
-
- idx++;
- return true;
- }
- /* Copies n glyphs at idx to output and advance idx.
- * If there's no output, just advance idx. */
- HB_NODISCARD bool next_glyphs (unsigned int n)
- {
- if (have_output)
- {
- if (out_info != info || out_len != idx)
- {
- if (unlikely (!make_room_for (n, n))) return false;
- memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
- }
- out_len += n;
- }
-
- idx += n;
- return true;
- }
- /* Advance idx without copying to output. */
- void skip_glyph () { idx++; }
- void reset_masks (hb_mask_t mask)
- {
- for (unsigned int j = 0; j < len; j++)
- info[j].mask = mask;
- }
- void add_masks (hb_mask_t mask)
- {
- 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);
-
- 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);
- /* Merge clusters for deleting current glyph, and skip it. */
- HB_INTERNAL void delete_glyph ();
- HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info));
-
-
-
- /* Adds glyph flags in mask to infos with clusters between start and end.
- * The start index will be from out-buffer if from_out_buffer is true.
- * If interior is true, then the cluster having the minimum value is skipped. */
- void _set_glyph_flags (hb_mask_t mask,
- unsigned start = 0,
- unsigned end = (unsigned) -1,
- bool interior = false,
- bool from_out_buffer = false)
- {
- end = hb_min (end, len);
-
- if (interior && !from_out_buffer && end - start < 2)
- return;
-
- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
-
- if (!from_out_buffer || !have_output)
- {
- if (!interior)
- {
- for (unsigned i = start; i < end; i++)
- info[i].mask |= mask;
- }
- else
- {
- unsigned cluster = _infos_find_min_cluster (info, start, end);
- _infos_set_glyph_flags (info, start, end, cluster, mask);
- }
- }
- else
- {
- assert (start <= out_len);
- assert (idx <= end);
-
- if (!interior)
- {
- for (unsigned i = start; i < out_len; i++)
- out_info[i].mask |= mask;
- for (unsigned i = idx; i < end; i++)
- info[i].mask |= mask;
- }
- else
- {
- unsigned cluster = _infos_find_min_cluster (info, idx, end);
- cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
-
- _infos_set_glyph_flags (out_info, start, out_len, cluster, mask);
- _infos_set_glyph_flags (info, idx, end, cluster, mask);
- }
- }
- }
-
- void unsafe_to_break (unsigned int start = 0, unsigned int end = -1)
- {
- _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
- start, end,
- true);
- }
- void safe_to_insert_tatweel (unsigned int start = 0, unsigned int end = -1)
- {
- if ((flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0)
- {
- unsafe_to_break (start, end);
- return;
- }
- _set_glyph_flags (HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL,
- start, end,
- true);
- }
- void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
- {
- if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
- return;
- _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
- start, end,
- true);
- }
- void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
- {
- _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
- start, end,
- true, true);
- }
- void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
- {
- if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
- return;
- _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
- start, end,
- false, true);
- }
-
-
- /* Internal methods */
- HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
-
- HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
-
- HB_NODISCARD bool ensure (unsigned int size)
- { return likely (!size || size < allocated) ? true : enlarge (size); }
-
- HB_NODISCARD bool ensure_inplace (unsigned int size)
- { return likely (!size || size < allocated); }
-
- void assert_glyphs ()
- {
- assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
- (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
- }
- void assert_unicode ()
- {
- assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
- (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
- }
- HB_NODISCARD bool ensure_glyphs ()
- {
- if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
- {
- if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
- return false;
- assert (len == 0);
- content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
- }
- return true;
- }
- HB_NODISCARD bool ensure_unicode ()
- {
- if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
- {
- if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
- return false;
- assert (len == 0);
- content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
- }
- return true;
- }
-
- HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
- HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count);
-
- typedef long scratch_buffer_t;
- HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
-
- void clear_context (unsigned int side) { context_len[side] = 0; }
-
- HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
-
- bool messaging ()
- {
-#ifdef HB_NO_BUFFER_MESSAGE
- return false;
-#else
- return unlikely (message_func);
-#endif
- }
- bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
- {
-#ifdef HB_NO_BUFFER_MESSAGE
- return true;
-#else
- if (likely (!messaging ()))
- return true;
-
- va_list ap;
- va_start (ap, fmt);
- bool ret = message_impl (font, fmt, ap);
- va_end (ap);
-
- return ret;
-#endif
- }
- HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
-
- static void
- set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
- {
- if (inf.cluster != cluster)
- inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
- inf.cluster = cluster;
- }
- void
- _infos_set_glyph_flags (hb_glyph_info_t *infos,
- unsigned int start, unsigned int end,
- unsigned int cluster,
- hb_mask_t mask)
- {
- if (unlikely (start == end))
- return;
-
- unsigned cluster_first = infos[start].cluster;
- unsigned cluster_last = infos[end - 1].cluster;
-
- if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS ||
- (cluster != cluster_first && cluster != cluster_last))
- {
- for (unsigned int i = start; i < end; i++)
- if (cluster != infos[i].cluster)
- {
- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
- infos[i].mask |= mask;
- }
- return;
- }
-
- /* Monotone clusters */
-
- if (cluster == cluster_first)
- {
- for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--)
- {
- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
- infos[i - 1].mask |= mask;
- }
- }
- else /* cluster == cluster_last */
- {
- for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++)
- {
- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
- infos[i].mask |= mask;
- }
- }
- }
- unsigned
- _infos_find_min_cluster (const hb_glyph_info_t *infos,
- unsigned start, unsigned end,
- unsigned cluster = UINT_MAX)
- {
- if (unlikely (start == end))
- return cluster;
-
- if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
- {
- for (unsigned int i = start; i < end; i++)
- cluster = hb_min (cluster, infos[i].cluster);
- return cluster;
- }
-
- return hb_min (cluster, hb_min (infos[start].cluster, infos[end - 1].cluster));
- }
-
- void clear_glyph_flags (hb_mask_t mask = 0)
- {
- for (unsigned int i = 0; i < len; i++)
- info[i].mask = (info[i].mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
- }
-};
-DECLARE_NULL_INSTANCE (hb_buffer_t);
-
-
-#define foreach_group(buffer, start, end, group_func) \
- for (unsigned int \
- _count = buffer->len, \
- start = 0, end = _count ? buffer->group_end (0, group_func) : 0; \
- start < _count; \
- start = end, end = buffer->group_end (start, group_func))
-
-#define foreach_cluster(buffer, start, end) \
- foreach_group (buffer, start, end, hb_buffer_t::_cluster_group_func)
-
-
-#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))
-#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ())
-#define HB_BUFFER_TRY_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, try_allocate_var, var ())
-#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
-#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ())
-
-
-#endif /* HB_BUFFER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
new file mode 100644
index 00000000000..24957e1e96f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh
@@ -0,0 +1,74 @@
+/*
+ * 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_CACHE_PRIVATE_HH
+#define HB_CACHE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* Implements a lock-free cache for int->int functions. */
+
+template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
+struct hb_cache_t
+{
+ ASSERT_STATIC (key_bits >= cache_bits);
+ ASSERT_STATIC (key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int));
+
+ inline void clear (void)
+ {
+ memset (values, 255, sizeof (values));
+ }
+
+ inline bool get (unsigned int key, unsigned int *value)
+ {
+ unsigned int k = key & ((1u<<cache_bits)-1);
+ unsigned int v = values[k];
+ if ((v >> value_bits) != (key >> cache_bits))
+ return false;
+ *value = v & ((1u<<value_bits)-1);
+ return true;
+ }
+
+ inline bool set (unsigned int key, unsigned int value)
+ {
+ if (unlikely ((key >> key_bits) || (value >> value_bits)))
+ return false; /* Overflows */
+ unsigned int k = key & ((1u<<cache_bits)-1);
+ unsigned int v = ((key>>cache_bits)<<value_bits) | value;
+ values[k] = v;
+ return true;
+ }
+
+ private:
+ unsigned int values[1u<<cache_bits];
+};
+
+typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
+typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
+
+
+#endif /* HB_CACHE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache.hh
deleted file mode 100644
index 8371465c6c2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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_CACHE_HH
-#define HB_CACHE_HH
-
-#include "hb.hh"
-
-
-/* Implements a lockfree cache for int->int functions.
- *
- * The cache is a fixed-size array of 16-bit or 32-bit integers.
- * The key is split into two parts: the cache index and the rest.
- *
- * The cache index is used to index into the array. The rest is used
- * to store the key and the value.
- *
- * The value is stored in the least significant bits of the integer.
- * The key is stored in the most significant bits of the integer.
- * The key is shifted by cache_bits to the left to make room for the
- * value.
- */
-
-template <unsigned int key_bits=16,
- unsigned int value_bits=8 + 32 - key_bits,
- unsigned int cache_bits=8,
- bool thread_safe=true>
-struct hb_cache_t
-{
- using item_t = typename std::conditional<thread_safe,
- typename std::conditional<key_bits + value_bits - cache_bits <= 16,
- hb_atomic_short_t,
- hb_atomic_int_t>::type,
- typename std::conditional<key_bits + value_bits - cache_bits <= 16,
- short,
- int>::type
- >::type;
-
- static_assert ((key_bits >= cache_bits), "");
- static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
-
- hb_cache_t () { init (); }
-
- void init () { clear (); }
-
- void clear ()
- {
- for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
- values[i] = -1;
- }
-
- bool get (unsigned int key, unsigned int *value) const
- {
- unsigned int k = key & ((1u<<cache_bits)-1);
- unsigned int v = values[k];
- if ((key_bits + value_bits - cache_bits == 8 * sizeof (item_t) && v == (unsigned int) -1) ||
- (v >> value_bits) != (key >> cache_bits))
- return false;
- *value = v & ((1u<<value_bits)-1);
- return true;
- }
-
- bool set (unsigned int key, unsigned int value)
- {
- if (unlikely ((key >> key_bits) || (value >> value_bits)))
- return false; /* Overflows */
- unsigned int k = key & ((1u<<cache_bits)-1);
- unsigned int v = ((key>>cache_bits)<<value_bits) | value;
- values[k] = v;
- return true;
- }
-
- private:
- item_t values[1u<<cache_bits];
-};
-
-
-#endif /* HB_CACHE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc b/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc
deleted file mode 100644
index 0f94d8169f2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.cc
+++ /dev/null
@@ -1,874 +0,0 @@
-/*
- * Copyright © 2022 Red Hat, Inc
- * Copyright © 2021, 2022 Black Foundry
- *
- * 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): Matthias Clasen
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_CAIRO
-
-#include "hb-cairo-utils.hh"
-
-#include <cairo.h>
-
-/* Some routines in this file were ported from BlackRenderer by Black Foundry.
- * Used by permission to relicense to HarfBuzz license.
- *
- * https://github.com/BlackFoundryCom/black-renderer
- */
-
-#define PREALLOCATED_COLOR_STOPS 16
-
-typedef struct {
- float r, g, b, a;
-} hb_cairo_color_t;
-
-static inline cairo_extend_t
-hb_cairo_extend (hb_paint_extend_t extend)
-{
- switch (extend)
- {
- case HB_PAINT_EXTEND_PAD: return CAIRO_EXTEND_PAD;
- case HB_PAINT_EXTEND_REPEAT: return CAIRO_EXTEND_REPEAT;
- case HB_PAINT_EXTEND_REFLECT: return CAIRO_EXTEND_REFLECT;
- default: break;
- }
-
- return CAIRO_EXTEND_PAD;
-}
-
-#ifdef CAIRO_HAS_PNG_FUNCTIONS
-typedef struct
-{
- hb_blob_t *blob;
- unsigned int offset;
-} hb_cairo_read_blob_data_t;
-
-static cairo_status_t
-hb_cairo_read_blob (void *closure,
- unsigned char *data,
- unsigned int length)
-{
- hb_cairo_read_blob_data_t *r = (hb_cairo_read_blob_data_t *) closure;
- const char *d;
- unsigned int size;
-
- d = hb_blob_get_data (r->blob, &size);
-
- if (r->offset + length > size)
- return CAIRO_STATUS_READ_ERROR;
-
- memcpy (data, d + r->offset, length);
- r->offset += length;
-
- return CAIRO_STATUS_SUCCESS;
-}
-#endif
-
-static const cairo_user_data_key_t *_hb_cairo_surface_blob_user_data_key = {0};
-
-static void
-_hb_cairo_destroy_blob (void *p)
-{
- hb_blob_destroy ((hb_blob_t *) p);
-}
-
-hb_bool_t
-_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
- hb_blob_t *blob,
- unsigned width,
- unsigned height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents)
-{
- cairo_t *cr = c->cr;
-
- if (!extents) /* SVG currently. */
- return false;
-
- cairo_surface_t *surface = nullptr;
-
-#ifdef CAIRO_HAS_PNG_FUNCTIONS
- if (format == HB_PAINT_IMAGE_FORMAT_PNG)
- {
- hb_cairo_read_blob_data_t r;
- r.blob = blob;
- r.offset = 0;
- surface = cairo_image_surface_create_from_png_stream (hb_cairo_read_blob, &r);
-
- /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(.
- * Just pull them out of the surface. */
- width = cairo_image_surface_get_width (surface);
- height = cairo_image_surface_get_width (surface);
- }
- else
-#endif
- if (format == HB_PAINT_IMAGE_FORMAT_BGRA)
- {
- /* Byte-endian conversion. */
- unsigned data_size = hb_blob_get_length (blob);
- if (data_size < width * height * 4)
- return false;
-
- unsigned char *data;
-#ifdef __BYTE_ORDER
- if (__BYTE_ORDER == __BIG_ENDIAN)
- {
- data = (unsigned char *) hb_blob_get_data_writable (blob, nullptr);
- if (!data)
- return false;
-
- unsigned count = width * height * 4;
- for (unsigned i = 0; i < count; i += 4)
- {
- unsigned char b;
- b = data[i];
- data[i] = data[i+3];
- data[i+3] = b;
- b = data[i+1];
- data[i+1] = data[i+2];
- data[i+2] = b;
- }
- }
- else
-#endif
- data = (unsigned char *) hb_blob_get_data (blob, nullptr);
-
- surface = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32,
- width, height,
- width * 4);
-
- cairo_surface_set_user_data (surface,
- _hb_cairo_surface_blob_user_data_key,
- hb_blob_reference (blob),
- _hb_cairo_destroy_blob);
- }
-
- if (!surface)
- return false;
-
- cairo_save (cr);
- /* this clip is here to work around recording surface limitations */
- cairo_rectangle (cr,
- extents->x_bearing,
- extents->y_bearing,
- extents->width,
- extents->height);
- cairo_clip (cr);
-
- cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
-
- cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0};
- cairo_pattern_set_matrix (pattern, &matrix);
-
- /* Undo slant in the extents and apply it in the context. */
- extents->width -= extents->height * slant;
- extents->x_bearing -= extents->y_bearing * slant;
- cairo_matrix_t cairo_matrix = {1., 0., (double) slant, 1., 0., 0.};
- cairo_transform (cr, &cairo_matrix);
-
- cairo_translate (cr, extents->x_bearing, extents->y_bearing);
- cairo_scale (cr, extents->width, extents->height);
- cairo_set_source (cr, pattern);
-
- cairo_paint (cr);
-
- cairo_pattern_destroy (pattern);
- cairo_surface_destroy (surface);
-
- cairo_restore (cr);
-
- return true;
-}
-
-static void
-_hb_cairo_reduce_anchors (float x0, float y0,
- float x1, float y1,
- float x2, float y2,
- float *xx0, float *yy0,
- float *xx1, float *yy1)
-{
- float q1x, q1y, q2x, q2y;
- float s;
- float k;
-
- q2x = x2 - x0;
- q2y = y2 - y0;
- q1x = x1 - x0;
- q1y = y1 - y0;
-
- s = q2x * q2x + q2y * q2y;
- if (s < 0.000001f)
- {
- *xx0 = x0; *yy0 = y0;
- *xx1 = x1; *yy1 = y1;
- return;
- }
-
- k = (q2x * q1x + q2y * q1y) / s;
- *xx0 = x0;
- *yy0 = y0;
- *xx1 = x1 - k * q2x;
- *yy1 = y1 - k * q2y;
-}
-
-static int
-_hb_cairo_cmp_color_stop (const void *p1,
- const void *p2)
-{
- const hb_color_stop_t *c1 = (const hb_color_stop_t *) p1;
- const hb_color_stop_t *c2 = (const hb_color_stop_t *) p2;
-
- if (c1->offset < c2->offset)
- return -1;
- else if (c1->offset > c2->offset)
- return 1;
- else
- return 0;
-}
-
-static void
-_hb_cairo_normalize_color_line (hb_color_stop_t *stops,
- unsigned int len,
- float *omin,
- float *omax)
-{
- float min, max;
-
- hb_qsort (stops, len, sizeof (hb_color_stop_t), _hb_cairo_cmp_color_stop);
-
- min = max = stops[0].offset;
- for (unsigned int i = 0; i < len; i++)
- {
- min = hb_min (min, stops[i].offset);
- max = hb_max (max, stops[i].offset);
- }
-
- if (min != max)
- {
- for (unsigned int i = 0; i < len; i++)
- stops[i].offset = (stops[i].offset - min) / (max - min);
- }
-
- *omin = min;
- *omax = max;
-}
-
-static bool
-_hb_cairo_get_color_stops (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- unsigned *count,
- hb_color_stop_t **stops)
-{
- unsigned len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
- if (len > *count)
- {
- *stops = (hb_color_stop_t *) hb_malloc (len * sizeof (hb_color_stop_t));
- if (unlikely (!stops))
- return false;
- }
- hb_color_line_get_color_stops (color_line, 0, &len, *stops);
- for (unsigned i = 0; i < len; i++)
- if ((*stops)[i].is_foreground)
- {
-#ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
- double r, g, b, a;
- cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
- if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
- (*stops)[i].color = HB_COLOR (round (b * 255.), round (g * 255.), round (r * 255.),
- round (a * hb_color_get_alpha ((*stops)[i].color)));
- else
-#endif
- (*stops)[i].color = HB_COLOR (0, 0, 0, hb_color_get_alpha ((*stops)[i].color));
- }
-
- *count = len;
- return true;
-}
-
-void
-_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2)
-{
- cairo_t *cr = c->cr;
-
- unsigned int len = PREALLOCATED_COLOR_STOPS;
- hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
- hb_color_stop_t *stops = stops_;
- float xx0, yy0, xx1, yy1;
- float xxx0, yyy0, xxx1, yyy1;
- float min, max;
- cairo_pattern_t *pattern;
-
- if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
- return;
- _hb_cairo_normalize_color_line (stops, len, &min, &max);
-
- _hb_cairo_reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1);
-
- xxx0 = xx0 + min * (xx1 - xx0);
- yyy0 = yy0 + min * (yy1 - yy0);
- xxx1 = xx0 + max * (xx1 - xx0);
- yyy1 = yy0 + max * (yy1 - yy0);
-
- pattern = cairo_pattern_create_linear ((double) xxx0, (double) yyy0, (double) xxx1, (double) yyy1);
- cairo_pattern_set_extend (pattern, hb_cairo_extend (hb_color_line_get_extend (color_line)));
- for (unsigned int i = 0; i < len; i++)
- {
- double r, g, b, a;
- r = hb_color_get_red (stops[i].color) / 255.;
- g = hb_color_get_green (stops[i].color) / 255.;
- b = hb_color_get_blue (stops[i].color) / 255.;
- a = hb_color_get_alpha (stops[i].color) / 255.;
- cairo_pattern_add_color_stop_rgba (pattern, (double) stops[i].offset, r, g, b, a);
- }
-
- cairo_set_source (cr, pattern);
- cairo_paint (cr);
-
- cairo_pattern_destroy (pattern);
-
- if (stops != stops_)
- hb_free (stops);
-}
-
-void
-_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1)
-{
- cairo_t *cr = c->cr;
-
- unsigned int len = PREALLOCATED_COLOR_STOPS;
- hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
- hb_color_stop_t *stops = stops_;
- float min, max;
- float xx0, yy0, xx1, yy1;
- float rr0, rr1;
- cairo_pattern_t *pattern;
-
- if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
- return;
- _hb_cairo_normalize_color_line (stops, len, &min, &max);
-
- xx0 = x0 + min * (x1 - x0);
- yy0 = y0 + min * (y1 - y0);
- xx1 = x0 + max * (x1 - x0);
- yy1 = y0 + max * (y1 - y0);
- rr0 = r0 + min * (r1 - r0);
- rr1 = r0 + max * (r1 - r0);
-
- pattern = cairo_pattern_create_radial ((double) xx0, (double) yy0, (double) rr0, (double) xx1, (double) yy1, (double) rr1);
- cairo_pattern_set_extend (pattern, hb_cairo_extend (hb_color_line_get_extend (color_line)));
-
- for (unsigned int i = 0; i < len; i++)
- {
- double r, g, b, a;
- r = hb_color_get_red (stops[i].color) / 255.;
- g = hb_color_get_green (stops[i].color) / 255.;
- b = hb_color_get_blue (stops[i].color) / 255.;
- a = hb_color_get_alpha (stops[i].color) / 255.;
- cairo_pattern_add_color_stop_rgba (pattern, (double) stops[i].offset, r, g, b, a);
- }
-
- cairo_set_source (cr, pattern);
- cairo_paint (cr);
-
- cairo_pattern_destroy (pattern);
-
- if (stops != stops_)
- hb_free (stops);
-}
-
-typedef struct {
- float x, y;
-} hb_cairo_point_t;
-
-static inline float
-_hb_cairo_interpolate (float f0, float f1, float f)
-{
- return f0 + f * (f1 - f0);
-}
-
-static inline void
-_hb_cairo_premultiply (hb_cairo_color_t *c)
-{
- c->r *= c->a;
- c->g *= c->a;
- c->b *= c->a;
-}
-
-static inline void
-_hb_cairo_unpremultiply (hb_cairo_color_t *c)
-{
- if (c->a != 0.f)
- {
- c->r /= c->a;
- c->g /= c->a;
- c->b /= c->a;
- }
-}
-
-static void
-_hb_cairo_interpolate_colors (hb_cairo_color_t *c0, hb_cairo_color_t *c1, float k, hb_cairo_color_t *c)
-{
- // According to the COLR specification, gradients
- // should be interpolated in premultiplied form
- _hb_cairo_premultiply (c0);
- _hb_cairo_premultiply (c1);
- c->r = c0->r + k * (c1->r - c0->r);
- c->g = c0->g + k * (c1->g - c0->g);
- c->b = c0->b + k * (c1->b - c0->b);
- c->a = c0->a + k * (c1->a - c0->a);
- _hb_cairo_unpremultiply (c);
-}
-
-static inline float
-_hb_cairo_dot (hb_cairo_point_t p, hb_cairo_point_t q)
-{
- return p.x * q.x + p.y * q.y;
-}
-
-static inline hb_cairo_point_t
-_hb_cairo_normalize (hb_cairo_point_t p)
-{
- float len = sqrtf (_hb_cairo_dot (p, p));
-
- return hb_cairo_point_t { p.x / len, p.y / len };
-}
-
-static inline hb_cairo_point_t
-_hb_cairo_sum (hb_cairo_point_t p, hb_cairo_point_t q)
-{
- return hb_cairo_point_t { p.x + q.x, p.y + q.y };
-}
-
-static inline hb_cairo_point_t
-_hb_cairo_difference (hb_cairo_point_t p, hb_cairo_point_t q)
-{
- return hb_cairo_point_t { p.x - q.x, p.y - q.y };
-}
-
-static inline hb_cairo_point_t
-_hb_cairo_scale (hb_cairo_point_t p, float f)
-{
- return hb_cairo_point_t { p.x * f, p.y * f };
-}
-
-typedef struct {
- hb_cairo_point_t center, p0, c0, c1, p1;
- hb_cairo_color_t color0, color1;
-} hb_cairo_patch_t;
-
-static void
-_hb_cairo_add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cairo_patch_t *p)
-{
- cairo_mesh_pattern_begin_patch (pattern);
- cairo_mesh_pattern_move_to (pattern, (double) center->x, (double) center->y);
- cairo_mesh_pattern_line_to (pattern, (double) p->p0.x, (double) p->p0.y);
- cairo_mesh_pattern_curve_to (pattern,
- (double) p->c0.x, (double) p->c0.y,
- (double) p->c1.x, (double) p->c1.y,
- (double) p->p1.x, (double) p->p1.y);
- cairo_mesh_pattern_line_to (pattern, (double) center->x, (double) center->y);
- cairo_mesh_pattern_set_corner_color_rgba (pattern, 0,
- (double) p->color0.r,
- (double) p->color0.g,
- (double) p->color0.b,
- (double) p->color0.a);
- cairo_mesh_pattern_set_corner_color_rgba (pattern, 1,
- (double) p->color0.r,
- (double) p->color0.g,
- (double) p->color0.b,
- (double) p->color0.a);
- cairo_mesh_pattern_set_corner_color_rgba (pattern, 2,
- (double) p->color1.r,
- (double) p->color1.g,
- (double) p->color1.b,
- (double) p->color1.a);
- cairo_mesh_pattern_set_corner_color_rgba (pattern, 3,
- (double) p->color1.r,
- (double) p->color1.g,
- (double) p->color1.b,
- (double) p->color1.a);
- cairo_mesh_pattern_end_patch (pattern);
-}
-
-#define MAX_ANGLE (HB_PI / 8.f)
-
-static void
-_hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
- float a0, hb_cairo_color_t *c0,
- float a1, hb_cairo_color_t *c1,
- cairo_pattern_t *pattern)
-{
- hb_cairo_point_t center = hb_cairo_point_t { cx, cy };
- int num_splits;
- hb_cairo_point_t p0;
- hb_cairo_color_t color0, color1;
-
- num_splits = ceilf (fabsf (a1 - a0) / MAX_ANGLE);
- p0 = hb_cairo_point_t { cosf (a0), sinf (a0) };
- color0 = *c0;
-
- for (int a = 0; a < num_splits; a++)
- {
- float k = (a + 1.) / num_splits;
- float angle1;
- hb_cairo_point_t p1;
- hb_cairo_point_t A, U;
- hb_cairo_point_t C0, C1;
- hb_cairo_patch_t patch;
-
- angle1 = _hb_cairo_interpolate (a0, a1, k);
- _hb_cairo_interpolate_colors (c0, c1, k, &color1);
-
- patch.color0 = color0;
- patch.color1 = color1;
-
- p1 = hb_cairo_point_t { cosf (angle1), sinf (angle1) };
- patch.p0 = _hb_cairo_sum (center, _hb_cairo_scale (p0, radius));
- patch.p1 = _hb_cairo_sum (center, _hb_cairo_scale (p1, radius));
-
- A = _hb_cairo_normalize (_hb_cairo_sum (p0, p1));
- U = hb_cairo_point_t { -A.y, A.x };
- C0 = _hb_cairo_sum (A, _hb_cairo_scale (U, _hb_cairo_dot (_hb_cairo_difference (p0, A), p0) / _hb_cairo_dot (U, p0)));
- C1 = _hb_cairo_sum (A, _hb_cairo_scale (U, _hb_cairo_dot (_hb_cairo_difference (p1, A), p1) / _hb_cairo_dot (U, p1)));
-
- patch.c0 = _hb_cairo_sum (center, _hb_cairo_scale (_hb_cairo_sum (C0, _hb_cairo_scale (_hb_cairo_difference (C0, p0), 0.33333f)), radius));
- patch.c1 = _hb_cairo_sum (center, _hb_cairo_scale (_hb_cairo_sum (C1, _hb_cairo_scale (_hb_cairo_difference (C1, p1), 0.33333f)), radius));
-
- _hb_cairo_add_patch (pattern, &center, &patch);
-
- p0 = p1;
- color0 = color1;
- }
-}
-
-static void
-_hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
- unsigned int n_stops,
- cairo_extend_t extend,
- float cx, float cy,
- float radius,
- float start_angle,
- float end_angle,
- cairo_pattern_t *pattern)
-{
- float angles_[PREALLOCATED_COLOR_STOPS];
- float *angles = angles_;
- hb_cairo_color_t colors_[PREALLOCATED_COLOR_STOPS];
- hb_cairo_color_t *colors = colors_;
- hb_cairo_color_t color0, color1;
-
- if (start_angle == end_angle)
- {
- if (extend == CAIRO_EXTEND_PAD)
- {
- hb_cairo_color_t c;
- if (start_angle > 0)
- {
- c.r = hb_color_get_red (stops[0].color) / 255.;
- c.g = hb_color_get_green (stops[0].color) / 255.;
- c.b = hb_color_get_blue (stops[0].color) / 255.;
- c.a = hb_color_get_alpha (stops[0].color) / 255.;
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- 0., &c,
- start_angle, &c,
- pattern);
- }
- if (end_angle < HB_2_PI)
- {
- c.r = hb_color_get_red (stops[n_stops - 1].color) / 255.;
- c.g = hb_color_get_green (stops[n_stops - 1].color) / 255.;
- c.b = hb_color_get_blue (stops[n_stops - 1].color) / 255.;
- c.a = hb_color_get_alpha (stops[n_stops - 1].color) / 255.;
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- end_angle, &c,
- HB_2_PI, &c,
- pattern);
- }
- }
- return;
- }
-
- assert (start_angle != end_angle);
-
- /* handle directions */
- if (end_angle < start_angle)
- {
- hb_swap (start_angle, end_angle);
-
- for (unsigned i = 0; i < n_stops - 1 - i; i++)
- hb_swap (stops[i], stops[n_stops - 1 - i]);
- for (unsigned i = 0; i < n_stops; i++)
- stops[i].offset = 1 - stops[i].offset;
- }
-
- if (n_stops > PREALLOCATED_COLOR_STOPS)
- {
- angles = (float *) hb_malloc (sizeof (float) * n_stops);
- colors = (hb_cairo_color_t *) hb_malloc (sizeof (hb_cairo_color_t) * n_stops);
- if (unlikely (!angles || !colors))
- {
- hb_free (angles);
- hb_free (colors);
- return;
- }
- }
-
- for (unsigned i = 0; i < n_stops; i++)
- {
- angles[i] = start_angle + stops[i].offset * (end_angle - start_angle);
- colors[i].r = hb_color_get_red (stops[i].color) / 255.;
- colors[i].g = hb_color_get_green (stops[i].color) / 255.;
- colors[i].b = hb_color_get_blue (stops[i].color) / 255.;
- colors[i].a = hb_color_get_alpha (stops[i].color) / 255.;
- }
-
- if (extend == CAIRO_EXTEND_PAD)
- {
- unsigned pos;
-
- color0 = colors[0];
- for (pos = 0; pos < n_stops; pos++)
- {
- if (angles[pos] >= 0)
- {
- if (pos > 0)
- {
- float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
- _hb_cairo_interpolate_colors (&colors[pos-1], &colors[pos], k, &color0);
- }
- break;
- }
- }
- if (pos == n_stops)
- {
- /* everything is below 0 */
- color0 = colors[n_stops-1];
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- 0., &color0,
- HB_2_PI, &color0,
- pattern);
- goto done;
- }
-
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- 0., &color0,
- angles[pos], &colors[pos],
- pattern);
-
- for (pos++; pos < n_stops; pos++)
- {
- if (angles[pos] <= HB_2_PI)
- {
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- angles[pos - 1], &colors[pos-1],
- angles[pos], &colors[pos],
- pattern);
- }
- else
- {
- float k = (HB_2_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
- _hb_cairo_interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1);
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- angles[pos - 1], &colors[pos - 1],
- HB_2_PI, &color1,
- pattern);
- break;
- }
- }
-
- if (pos == n_stops)
- {
- /* everything is below 2*M_PI */
- color0 = colors[n_stops - 1];
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- angles[n_stops - 1], &color0,
- HB_2_PI, &color0,
- pattern);
- goto done;
- }
- }
- else
- {
- int k;
- float span;
-
- span = angles[n_stops - 1] - angles[0];
- k = 0;
- if (angles[0] >= 0)
- {
- float ss = angles[0];
- while (ss > 0)
- {
- if (span > 0)
- {
- ss -= span;
- k--;
- }
- else
- {
- ss += span;
- k++;
- }
- }
- }
- else if (angles[0] < 0)
- {
- float ee = angles[n_stops - 1];
- while (ee < 0)
- {
- if (span > 0)
- {
- ee += span;
- k++;
- }
- else
- {
- ee -= span;
- k--;
- }
- }
- }
-
- //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span);
- span = fabs (span);
-
- for (signed l = k; l < 1000; l++)
- {
- for (unsigned i = 1; i < n_stops; i++)
- {
- float a0, a1;
- hb_cairo_color_t *c0, *c1;
-
- if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT))
- {
- a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span;
- a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span;
- c0 = &colors[n_stops - 1 - (i - 1)];
- c1 = &colors[n_stops - 1 - i];
- }
- else
- {
- a0 = angles[i-1] + l * span;
- a1 = angles[i] + l * span;
- c0 = &colors[i-1];
- c1 = &colors[i];
- }
-
- if (a1 < 0)
- continue;
- if (a0 < 0)
- {
- hb_cairo_color_t color;
- float f = (0 - a0)/(a1 - a0);
- _hb_cairo_interpolate_colors (c0, c1, f, &color);
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- 0, &color,
- a1, c1,
- pattern);
- }
- else if (a1 >= HB_2_PI)
- {
- hb_cairo_color_t color;
- float f = (HB_2_PI - a0)/(a1 - a0);
- _hb_cairo_interpolate_colors (c0, c1, f, &color);
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- a0, c0,
- HB_2_PI, &color,
- pattern);
- goto done;
- }
- else
- {
- _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
- a0, c0,
- a1, c1,
- pattern);
- }
- }
- }
- }
-
-done:
-
- if (angles != angles_)
- hb_free (angles);
- if (colors != colors_)
- hb_free (colors);
-}
-
-void
-_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float cx, float cy,
- float start_angle,
- float end_angle)
-{
- cairo_t *cr = c->cr;
-
- unsigned int len = PREALLOCATED_COLOR_STOPS;
- hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
- hb_color_stop_t *stops = stops_;
- cairo_extend_t extend;
- double x1, y1, x2, y2;
- float max_x, max_y, radius;
- cairo_pattern_t *pattern;
-
- if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
- return;
-
- hb_qsort (stops, len, sizeof (hb_color_stop_t), _hb_cairo_cmp_color_stop);
-
- cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
- max_x = (float) hb_max ((x1 - (double) cx) * (x1 - (double) cx), (x2 - (double) cx) * (x2 - (double) cx));
- max_y = (float) hb_max ((y1 - (double) cy) * (y1 - (double) cy), (y2 - (double) cy) * (y2 - (double) cy));
- radius = sqrtf (max_x + max_y);
-
- extend = hb_cairo_extend (hb_color_line_get_extend (color_line));
- pattern = cairo_pattern_create_mesh ();
-
- _hb_cairo_add_sweep_gradient_patches (stops, len, extend, cx, cy,
- radius, start_angle, end_angle, pattern);
-
- cairo_set_source (cr, pattern);
- cairo_paint (cr);
-
- cairo_pattern_destroy (pattern);
-
- if (stops != stops_)
- hb_free (stops);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.hh b/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.hh
deleted file mode 100644
index a26bf59d918..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cairo-utils.hh
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright © 2022 Red Hat, 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): Matthias Clasen
- */
-
-#ifndef HB_CAIRO_UTILS_H
-#define HB_CAIRO_UTILS_H
-
-#include "hb.hh"
-#include "hb-cairo.h"
-
-
-typedef struct
-{
- cairo_scaled_font_t *scaled_font;
- cairo_t *cr;
- hb_map_t *color_cache;
-} hb_cairo_context_t;
-
-static inline cairo_operator_t
-_hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
-{
- switch (mode)
- {
- case HB_PAINT_COMPOSITE_MODE_CLEAR: return CAIRO_OPERATOR_CLEAR;
- case HB_PAINT_COMPOSITE_MODE_SRC: return CAIRO_OPERATOR_SOURCE;
- case HB_PAINT_COMPOSITE_MODE_DEST: return CAIRO_OPERATOR_DEST;
- case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return CAIRO_OPERATOR_OVER;
- case HB_PAINT_COMPOSITE_MODE_DEST_OVER: return CAIRO_OPERATOR_DEST_OVER;
- case HB_PAINT_COMPOSITE_MODE_SRC_IN: return CAIRO_OPERATOR_IN;
- case HB_PAINT_COMPOSITE_MODE_DEST_IN: return CAIRO_OPERATOR_DEST_IN;
- case HB_PAINT_COMPOSITE_MODE_SRC_OUT: return CAIRO_OPERATOR_OUT;
- case HB_PAINT_COMPOSITE_MODE_DEST_OUT: return CAIRO_OPERATOR_DEST_OUT;
- case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: return CAIRO_OPERATOR_ATOP;
- case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: return CAIRO_OPERATOR_DEST_ATOP;
- case HB_PAINT_COMPOSITE_MODE_XOR: return CAIRO_OPERATOR_XOR;
- case HB_PAINT_COMPOSITE_MODE_PLUS: return CAIRO_OPERATOR_ADD;
- case HB_PAINT_COMPOSITE_MODE_SCREEN: return CAIRO_OPERATOR_SCREEN;
- case HB_PAINT_COMPOSITE_MODE_OVERLAY: return CAIRO_OPERATOR_OVERLAY;
- case HB_PAINT_COMPOSITE_MODE_DARKEN: return CAIRO_OPERATOR_DARKEN;
- case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return CAIRO_OPERATOR_LIGHTEN;
- case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return CAIRO_OPERATOR_COLOR_DODGE;
- case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return CAIRO_OPERATOR_COLOR_BURN;
- case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return CAIRO_OPERATOR_HARD_LIGHT;
- case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return CAIRO_OPERATOR_SOFT_LIGHT;
- case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return CAIRO_OPERATOR_DIFFERENCE;
- case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return CAIRO_OPERATOR_EXCLUSION;
- case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return CAIRO_OPERATOR_MULTIPLY;
- case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return CAIRO_OPERATOR_HSL_HUE;
- case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return CAIRO_OPERATOR_HSL_SATURATION;
- case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return CAIRO_OPERATOR_HSL_COLOR;
- case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return CAIRO_OPERATOR_HSL_LUMINOSITY;
- default: return CAIRO_OPERATOR_CLEAR;
- }
-}
-
-HB_INTERNAL hb_bool_t
-_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
- hb_blob_t *blob,
- unsigned width,
- unsigned height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents);
-
-HB_INTERNAL void
-_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2);
-
-HB_INTERNAL void
-_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1);
-
-HB_INTERNAL void
-_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle, float end_angle);
-
-
-#endif /* HB_CAIRO_UTILS_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc b/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc
deleted file mode 100644
index f005afd17e7..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cairo.cc
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright © 2022 Red Hat, 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): Matthias Clasen
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_CAIRO
-
-#include "hb-cairo.h"
-
-#include "hb-cairo-utils.hh"
-
-#include "hb-machinery.hh"
-#include "hb-utf.hh"
-
-
-/**
- * SECTION:hb-cairo
- * @title: hb-cairo
- * @short_description: Cairo integration
- * @include: hb-cairo.h
- *
- * Functions for using HarfBuzz with the cairo library.
- *
- * HarfBuzz supports using cairo for rendering.
- **/
-
-static void
-hb_cairo_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *draw_data,
- hb_draw_state_t *st HB_UNUSED,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- cairo_t *cr = (cairo_t *) draw_data;
-
- cairo_move_to (cr, (double) to_x, (double) to_y);
-}
-
-static void
-hb_cairo_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *draw_data,
- hb_draw_state_t *st HB_UNUSED,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- cairo_t *cr = (cairo_t *) draw_data;
-
- cairo_line_to (cr, (double) to_x, (double) to_y);
-}
-
-static void
-hb_cairo_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *draw_data,
- hb_draw_state_t *st HB_UNUSED,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- cairo_t *cr = (cairo_t *) draw_data;
-
- cairo_curve_to (cr,
- (double) control1_x, (double) control1_y,
- (double) control2_x, (double) control2_y,
- (double) to_x, (double) to_y);
-}
-
-static void
-hb_cairo_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *draw_data,
- hb_draw_state_t *st HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- cairo_t *cr = (cairo_t *) draw_data;
-
- cairo_close_path (cr);
-}
-
-static inline void free_static_cairo_draw_funcs ();
-
-static struct hb_cairo_draw_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_cairo_draw_funcs_lazy_loader_t>
-{
- static hb_draw_funcs_t *create ()
- {
- hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
-
- hb_draw_funcs_set_move_to_func (funcs, hb_cairo_move_to, nullptr, nullptr);
- hb_draw_funcs_set_line_to_func (funcs, hb_cairo_line_to, nullptr, nullptr);
- hb_draw_funcs_set_cubic_to_func (funcs, hb_cairo_cubic_to, nullptr, nullptr);
- hb_draw_funcs_set_close_path_func (funcs, hb_cairo_close_path, nullptr, nullptr);
-
- hb_draw_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_cairo_draw_funcs);
-
- return funcs;
- }
-} static_cairo_draw_funcs;
-
-static inline
-void free_static_cairo_draw_funcs ()
-{
- static_cairo_draw_funcs.free_instance ();
-}
-
-static hb_draw_funcs_t *
-hb_cairo_draw_get_funcs ()
-{
- return static_cairo_draw_funcs.get_unconst ();
-}
-
-
-#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
-
-static void
-hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_matrix_t m;
-
- cairo_save (cr);
- cairo_matrix_init (&m, (double) xx, (double) yx,
- (double) xy, (double) yy,
- (double) dx, (double) dy);
- cairo_transform (cr, &m);
-}
-
-static void
-hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_restore (cr);
-}
-
-static void
-hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_save (cr);
- cairo_new_path (cr);
- hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
- cairo_close_path (cr);
- cairo_clip (cr);
-}
-
-static void
-hb_cairo_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- float xmin, float ymin, float xmax, float ymax,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_save (cr);
- cairo_rectangle (cr,
- (double) xmin, (double) ymin,
- (double) (xmax - xmin), (double) (ymax - ymin));
- cairo_clip (cr);
-}
-
-static void
-hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_restore (cr);
-}
-
-static void
-hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_save (cr);
- cairo_push_group (cr);
-}
-
-static void
-hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_paint_composite_mode_t mode,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- cairo_pop_group_to_source (cr);
- cairo_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode));
- cairo_paint (cr);
-
- cairo_restore (cr);
-}
-
-static void
-hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_bool_t use_foreground,
- hb_color_t color,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
- if (use_foreground)
- {
-#ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
- double r, g, b, a;
- cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
- if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
- cairo_set_source_rgba (cr, r, g, b, a * hb_color_get_alpha (color) / 255.);
- else
-#endif
- cairo_set_source_rgba (cr, 0, 0, 0, hb_color_get_alpha (color) / 255.);
- }
- else
- cairo_set_source_rgba (cr,
- hb_color_get_red (color) / 255.,
- hb_color_get_green (color) / 255.,
- hb_color_get_blue (color) / 255.,
- hb_color_get_alpha (color) / 255.);
- cairo_paint (cr);
-}
-
-static hb_bool_t
-hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_blob_t *blob,
- unsigned width,
- unsigned height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
-
- return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
-}
-
-static void
-hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
-
- _hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
-}
-
-static void
-hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
-
- _hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
-}
-
-static void
-hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle, float end_angle,
- void *user_data HB_UNUSED)
-{
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
-
- _hb_cairo_paint_sweep_gradient (c, color_line, x0, y0, start_angle, end_angle);
-}
-
-static const cairo_user_data_key_t color_cache_key = {0};
-
-static void
-_hb_cairo_destroy_map (void *p)
-{
- hb_map_destroy ((hb_map_t *) p);
-}
-
-static hb_bool_t
-hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
- void *paint_data,
- unsigned int color_index,
- hb_color_t *color,
- void *user_data HB_UNUSED)
-{
-#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
- hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
- cairo_t *cr = c->cr;
-
-#define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF)
-
- hb_map_t *color_cache = c->color_cache;
- hb_codepoint_t *v;
- if (likely (color_cache && color_cache->has (color_index, &v)))
- {
- if (*v == HB_DEADBEEF)
- return false;
- *color = *v;
- return true;
- }
-
- cairo_font_options_t *options;
- double red, green, blue, alpha;
-
- options = cairo_font_options_create ();
- cairo_get_font_options (cr, options);
- if (CAIRO_STATUS_SUCCESS ==
- cairo_font_options_get_custom_palette_color (options, color_index,
- &red, &green, &blue, &alpha))
- {
- cairo_font_options_destroy (options);
- *color = HB_COLOR (round (255 * blue),
- round (255 * green),
- round (255 * red),
- round (255 * alpha));
-
- if (likely (color_cache && *color != HB_DEADBEEF))
- color_cache->set (color_index, *color);
-
- return true;
- }
- cairo_font_options_destroy (options);
-
- if (likely (color_cache))
- color_cache->set (color_index, HB_DEADBEEF);
-
-#undef HB_DEADBEEF
-
-#endif
-
- return false;
-}
-
-static inline void free_static_cairo_paint_funcs ();
-
-static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
-{
- static hb_paint_funcs_t *create ()
- {
- hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
-
- hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr);
- hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr);
- hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr);
- hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr);
- hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr);
- hb_paint_funcs_set_push_group_func (funcs, hb_cairo_push_group, nullptr, nullptr);
- hb_paint_funcs_set_pop_group_func (funcs, hb_cairo_pop_group, nullptr, nullptr);
- hb_paint_funcs_set_color_func (funcs, hb_cairo_paint_color, nullptr, nullptr);
- hb_paint_funcs_set_image_func (funcs, hb_cairo_paint_image, nullptr, nullptr);
- hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
- hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
- hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
- hb_paint_funcs_set_custom_palette_color_func (funcs, hb_cairo_paint_custom_palette_color, nullptr, nullptr);
-
- hb_paint_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_cairo_paint_funcs);
-
- return funcs;
- }
-} static_cairo_paint_funcs;
-
-static inline
-void free_static_cairo_paint_funcs ()
-{
- static_cairo_paint_funcs.free_instance ();
-}
-
-static hb_paint_funcs_t *
-hb_cairo_paint_get_funcs ()
-{
- return static_cairo_paint_funcs.get_unconst ();
-}
-#endif
-
-static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
-static const cairo_user_data_key_t hb_cairo_font_user_data_key = {0};
-static const cairo_user_data_key_t hb_cairo_font_init_func_user_data_key = {0};
-static const cairo_user_data_key_t hb_cairo_font_init_user_data_user_data_key = {0};
-static const cairo_user_data_key_t hb_cairo_scale_factor_user_data_key = {0};
-
-static void hb_cairo_face_destroy (void *p) { hb_face_destroy ((hb_face_t *) p); }
-static void hb_cairo_font_destroy (void *p) { hb_font_destroy ((hb_font_t *) p); }
-
-static cairo_status_t
-hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
- cairo_t *cr HB_UNUSED,
- cairo_font_extents_t *extents)
-{
- cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (scaled_font);
-
- hb_font_t *font = (hb_font_t *) cairo_font_face_get_user_data (font_face,
- &hb_cairo_font_user_data_key);
-
- if (!font)
- {
- hb_face_t *face = (hb_face_t *) cairo_font_face_get_user_data (font_face,
- &hb_cairo_face_user_data_key);
- font = hb_font_create (face);
-
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,16,0)
- cairo_font_options_t *font_options = cairo_font_options_create ();
-
- // Set variations
- cairo_scaled_font_get_font_options (scaled_font, font_options);
- const char *variations = cairo_font_options_get_variations (font_options);
- hb_vector_t<hb_variation_t> vars;
- const char *p = variations;
- while (p && *p)
- {
- const char *end = strpbrk ((char *) p, ", ");
- hb_variation_t var;
- if (hb_variation_from_string (p, end ? end - p : -1, &var))
- vars.push (var);
- p = end ? end + 1 : nullptr;
- }
- hb_font_set_variations (font, &vars[0], vars.length);
-
- cairo_font_options_destroy (font_options);
-#endif
-
- // Set scale; Note: should NOT set slant, or we'll double-slant.
- unsigned scale_factor = hb_cairo_font_face_get_scale_factor (font_face);
- if (scale_factor)
- {
- cairo_matrix_t font_matrix;
- cairo_scaled_font_get_scale_matrix (scaled_font, &font_matrix);
- hb_font_set_scale (font,
- round (font_matrix.xx * scale_factor),
- round (font_matrix.yy * scale_factor));
- }
-
- auto *init_func = (hb_cairo_font_init_func_t)
- cairo_font_face_get_user_data (font_face,
- &hb_cairo_font_init_func_user_data_key);
- if (init_func)
- {
- void *user_data = cairo_font_face_get_user_data (font_face,
- &hb_cairo_font_init_user_data_user_data_key);
- font = init_func (font, scaled_font, user_data);
- }
-
- hb_font_make_immutable (font);
- }
-
- cairo_scaled_font_set_user_data (scaled_font,
- &hb_cairo_font_user_data_key,
- (void *) hb_font_reference (font),
- hb_cairo_font_destroy);
-
- hb_position_t x_scale, y_scale;
- hb_font_get_scale (font, &x_scale, &y_scale);
-
- hb_font_extents_t hb_extents;
- hb_font_get_h_extents (font, &hb_extents);
-
- extents->ascent = (double) hb_extents.ascender / y_scale;
- extents->descent = (double) -hb_extents.descender / y_scale;
- extents->height = extents->ascent + extents->descent;
-
-#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
- hb_map_t *color_cache = hb_map_create ();
- if (unlikely (CAIRO_STATUS_SUCCESS != cairo_scaled_font_set_user_data (scaled_font,
- &color_cache_key,
- color_cache,
- _hb_cairo_destroy_map)))
- hb_map_destroy (color_cache);
-#endif
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-hb_cairo_text_to_glyphs (cairo_scaled_font_t *scaled_font,
- const char *utf8,
- int utf8_len,
- cairo_glyph_t **glyphs,
- int *num_glyphs,
- cairo_text_cluster_t **clusters,
- int *num_clusters,
- cairo_text_cluster_flags_t *cluster_flags)
-{
- hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
- &hb_cairo_font_user_data_key);
-
- hb_buffer_t *buffer = hb_buffer_create ();
- hb_buffer_add_utf8 (buffer, utf8, utf8_len, 0, utf8_len);
- hb_buffer_guess_segment_properties (buffer);
- hb_shape (font, buffer, nullptr, 0);
-
- hb_cairo_glyphs_from_buffer (buffer,
- true,
- font->x_scale, font->y_scale,
- 0., 0.,
- utf8, utf8_len,
- glyphs, (unsigned *) num_glyphs,
- clusters, (unsigned *) num_clusters,
- cluster_flags);
-
- hb_buffer_destroy (buffer);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-hb_cairo_render_glyph (cairo_scaled_font_t *scaled_font,
- unsigned long glyph,
- cairo_t *cr,
- cairo_text_extents_t *extents)
-{
- hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
- &hb_cairo_font_user_data_key);
-
- hb_position_t x_scale, y_scale;
- hb_font_get_scale (font, &x_scale, &y_scale);
- cairo_scale (cr, +1./x_scale, -1./y_scale);
-
- hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
-
- cairo_fill (cr);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
-
-static cairo_status_t
-hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
- unsigned long glyph,
- cairo_t *cr,
- cairo_text_extents_t *extents)
-{
- hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
- &hb_cairo_font_user_data_key);
-
- unsigned int palette = 0;
-#ifdef CAIRO_COLOR_PALETTE_DEFAULT
- cairo_font_options_t *options = cairo_font_options_create ();
- cairo_scaled_font_get_font_options (scaled_font, options);
- palette = cairo_font_options_get_color_palette (options);
- cairo_font_options_destroy (options);
-#endif
-
- hb_color_t color = HB_COLOR (0, 0, 0, 255);
- hb_position_t x_scale, y_scale;
- hb_font_get_scale (font, &x_scale, &y_scale);
- cairo_scale (cr, +1./x_scale, -1./y_scale);
-
- hb_cairo_context_t c;
- c.scaled_font = scaled_font;
- c.cr = cr;
- c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key);
-
- hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color);
-
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-#endif
-
-static cairo_font_face_t *
-user_font_face_create (hb_face_t *face)
-{
- cairo_font_face_t *cairo_face;
-
- cairo_face = cairo_user_font_face_create ();
- cairo_user_font_face_set_init_func (cairo_face, hb_cairo_init_scaled_font);
- cairo_user_font_face_set_text_to_glyphs_func (cairo_face, hb_cairo_text_to_glyphs);
- cairo_user_font_face_set_render_glyph_func (cairo_face, hb_cairo_render_glyph);
-#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
- if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face))
- cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph);
-#endif
-
- if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
- &hb_cairo_face_user_data_key,
- (void *) hb_face_reference (face),
- hb_cairo_face_destroy)))
- hb_face_destroy (face);
-
- return cairo_face;
-}
-
-/**
- * hb_cairo_font_face_create_for_font:
- * @font: a #hb_font_t
- *
- * Creates a #cairo_font_face_t for rendering text according
- * to @font.
- *
- * Note that the scale of @font does not affect the rendering,
- * but the variations and slant that are set on @font do.
- *
- * Returns: (transfer full): a newly created #cairo_font_face_t
- *
- * Since: 7.0.0
- */
-cairo_font_face_t *
-hb_cairo_font_face_create_for_font (hb_font_t *font)
-{
- hb_font_make_immutable (font);
-
- auto *cairo_face = user_font_face_create (font->face);
-
- if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
- &hb_cairo_font_user_data_key,
- (void *) hb_font_reference (font),
- hb_cairo_font_destroy)))
- hb_font_destroy (font);
-
- return cairo_face;
-}
-
-/**
- * hb_cairo_font_face_get_font:
- * @font_face: a #cairo_font_face_t
- *
- * Gets the #hb_font_t that @font_face was created from.
- *
- * Returns: (nullable) (transfer none): the #hb_font_t that @font_face was created from
- *
- * Since: 7.0.0
- */
-hb_font_t *
-hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
-{
- return (hb_font_t *) cairo_font_face_get_user_data (font_face,
- &hb_cairo_font_user_data_key);
-}
-
-/**
- * hb_cairo_font_face_create_for_face:
- * @face: a #hb_face_t
- *
- * Creates a #cairo_font_face_t for rendering text according
- * to @face.
- *
- * Returns: (transfer full): a newly created #cairo_font_face_t
- *
- * Since: 7.0.0
- */
-cairo_font_face_t *
-hb_cairo_font_face_create_for_face (hb_face_t *face)
-{
- hb_face_make_immutable (face);
-
- return user_font_face_create (face);
-}
-
-/**
- * hb_cairo_font_face_get_face:
- * @font_face: a #cairo_font_face_t
- *
- * Gets the #hb_face_t associated with @font_face.
- *
- * Returns: (nullable) (transfer none): the #hb_face_t associated with @font_face
- *
- * Since: 7.0.0
- */
-hb_face_t *
-hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
-{
- return (hb_face_t *) cairo_font_face_get_user_data (font_face,
- &hb_cairo_face_user_data_key);
-}
-
-/**
- * hb_cairo_font_face_set_font_init_func:
- * @font_face: a #cairo_font_face_t
- * @func: The virtual method to use
- * @user_data: user data accompanying the method
- * @destroy: function to call when @user_data is not needed anymore
- *
- * Set the virtual method to be called when a cairo
- * face created using hb_cairo_font_face_create_for_face()
- * creates an #hb_font_t for a #cairo_scaled_font_t.
- *
- * Since: 7.0.0
- */
-void
-hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
- hb_cairo_font_init_func_t func,
- void *user_data,
- hb_destroy_func_t destroy)
-{
- cairo_font_face_set_user_data (font_face,
- &hb_cairo_font_init_func_user_data_key,
- (void *) func,
- nullptr);
- if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (font_face,
- &hb_cairo_font_init_user_data_user_data_key,
- (void *) user_data,
- destroy)) && destroy)
- {
- destroy (user_data);
- cairo_font_face_set_user_data (font_face,
- &hb_cairo_font_init_func_user_data_key,
- nullptr,
- nullptr);
- }
-}
-
-/**
- * hb_cairo_scaled_font_get_font:
- * @scaled_font: a #cairo_scaled_font_t
- *
- * Gets the #hb_font_t associated with @scaled_font.
- *
- * Returns: (nullable) (transfer none): the #hb_font_t associated with @scaled_font
- *
- * Since: 7.0.0
- */
-hb_font_t *
-hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
-{
- return (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font, &hb_cairo_font_user_data_key);
-}
-
-
-/**
- * hb_cairo_font_face_set_scale_factor:
- * @scale_factor: The scale factor to use. See below
- * @font_face: a #cairo_font_face_t
- *
- * Sets the scale factor of the @font_face. Default scale
- * factor is zero.
- *
- * When a #cairo_font_face_t is created from a #hb_face_t using
- * hb_cairo_font_face_create_for_face(), such face will create
- * #hb_font_t objects during scaled-font creation. The scale
- * factor defines how the scale set on such #hb_font_t objects
- * relates to the font-matrix (as such font size) of the cairo
- * scaled-font.
- *
- * If the scale-factor is zero (default), then the scale of the
- * #hb_font_t object will be left at default, which is the UPEM
- * value of the respective #hb_face_t.
- *
- * If the scale-factor is set to non-zero, then the X and Y scale
- * of the #hb_font_t object will be respectively set to the
- * @scale_factor times the xx and yy elements of the scale-matrix
- * of the cairo scaled-font being created.
- *
- * When using the hb_cairo_glyphs_from_buffer() API to convert the
- * HarfBuzz glyph buffer that resulted from shaping with such a #hb_font_t,
- * if the scale-factor was non-zero, you can pass it directly to
- * that API as both X and Y scale factors.
- *
- * If the scale-factor was zero however, or the cairo face was
- * created using the alternative constructor
- * hb_cairo_font_face_create_for_font(), you need to calculate the
- * correct X/Y scale-factors to pass to hb_cairo_glyphs_from_buffer()
- * by dividing the #hb_font_t X/Y scale-factors by the
- * cairo scaled-font's scale-matrix XX/YY components respectively
- * and use those values. Or if you know that relationship offhand
- * (because you set the scale of the #hb_font_t yourself), use
- * the conversion rate involved.
- *
- * Since: 7.0.0
- */
-void
-hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
- unsigned int scale_factor)
-{
- cairo_font_face_set_user_data (font_face,
- &hb_cairo_scale_factor_user_data_key,
- (void *) (uintptr_t) scale_factor,
- nullptr);
-}
-
-/**
- * hb_cairo_font_face_get_scale_factor:
- * @font_face: a #cairo_font_face_t
- *
- * Gets the scale factor set on the @font_face. Defaults to zero.
- * See hb_cairo_font_face_set_scale_factor() for details.
- *
- * Returns: the scale factor of @font_face
- *
- * Since: 7.0.0
- */
-unsigned int
-hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
-{
- return (unsigned int) (uintptr_t)
- cairo_font_face_get_user_data (font_face,
- &hb_cairo_scale_factor_user_data_key);
-}
-
-
-/**
- * hb_cairo_glyphs_from_buffer:
- * @buffer: a #hb_buffer_t containing glyphs
- * @utf8_clusters: `true` if @buffer clusters are in bytes, instead of characters
- * @x_scale_factor: scale factor to divide #hb_position_t Y values by
- * @y_scale_factor: scale factor to divide #hb_position_t X values by
- * @x: X position to place first glyph
- * @y: Y position to place first glyph
- * @utf8: (nullable): the text that was shaped in @buffer
- * @utf8_len: the length of @utf8 in bytes
- * @glyphs: (out): return location for an array of #cairo_glyph_t
- * @num_glyphs: (inout): return location for the length of @glyphs
- * @clusters: (out) (nullable): return location for an array of cluster positions
- * @num_clusters: (inout) (nullable): return location for the length of @clusters
- * @cluster_flags: (out) (nullable): return location for cluster flags
- *
- * Extracts information from @buffer in a form that can be
- * passed to cairo_show_text_glyphs() or cairo_show_glyphs().
- * This API is modeled after cairo_scaled_font_text_to_glyphs() and
- * cairo_user_scaled_font_text_to_glyphs_func_t.
- *
- * The @num_glyphs argument should be preset to the number of glyph entries available
- * in the @glyphs buffer. If the @glyphs buffer is `NULL`, the value of
- * @num_glyphs must be zero. If the provided glyph array is too short for
- * the conversion (or for convenience), a new glyph array may be allocated
- * using cairo_glyph_allocate() and placed in @glyphs. Upon return,
- * @num_glyphs should contain the number of generated glyphs. If the value
- * @glyphs points at has changed after the call, the caller will free the
- * allocated glyph array using cairo_glyph_free(). The caller will also free
- * the original value of @glyphs, so this function shouldn't do so.
- *
- * If @clusters is not `NULL`, then @num_clusters and @cluster_flags
- * should not be either, and @utf8 must be provided, and cluster
- * mapping will be computed. The semantics of how
- * cluster array allocation works is similar to the glyph array. That is,
- * if @clusters initially points to a non-`NULL` value, that array may be used
- * as a cluster buffer, and @num_clusters points to the number of cluster
- * entries available there. If the provided cluster array is too short for
- * the conversion (or for convenience), a new cluster array may be allocated
- * using cairo_text_cluster_allocate() and placed in @clusters. In this case,
- * the original value of @clusters will still be freed by the caller. Upon
- * return, @num_clusters will contain the number of generated clusters.
- * If the value @clusters points at has changed after the call, the caller
- * will free the allocated cluster array using cairo_text_cluster_free().
- *
- * See hb_cairo_font_face_set_scale_factor() for the details of
- * the @scale_factor argument.
- *
- * The returned @glyphs vector actually has `@num_glyphs + 1` entries in
- * it and the x,y values of the extra entry at the end add up the advance
- * x,y of all the glyphs in the @buffer.
- *
- * Since: 7.0.0
- */
-void
-hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
- hb_bool_t utf8_clusters,
- double x_scale_factor,
- double y_scale_factor,
- double x,
- double y,
- const char *utf8,
- int utf8_len,
- cairo_glyph_t **glyphs,
- unsigned int *num_glyphs,
- cairo_text_cluster_t **clusters,
- unsigned int *num_clusters,
- cairo_text_cluster_flags_t *cluster_flags)
-{
- if (utf8 && utf8_len < 0)
- utf8_len = strlen (utf8);
-
- unsigned orig_num_glyphs = *num_glyphs;
- *num_glyphs = hb_buffer_get_length (buffer);
- hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
- hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
- if (orig_num_glyphs < *num_glyphs + 1)
- *glyphs = cairo_glyph_allocate (*num_glyphs + 1);
-
- if (clusters && utf8)
- {
- unsigned orig_num_clusters = *num_clusters;
- *num_clusters = *num_glyphs ? 1 : 0;
- for (unsigned int i = 1; i < *num_glyphs; i++)
- if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
- (*num_clusters)++;
- if (orig_num_clusters < *num_clusters)
- *clusters = cairo_text_cluster_allocate (*num_clusters);
- }
-
- double x_scale = x_scale_factor ? 1. / x_scale_factor : 0.;
- double y_scale = y_scale_factor ? 1. / y_scale_factor : 0.;
- hb_position_t hx = 0, hy = 0;
- int i;
- for (i = 0; i < (int) *num_glyphs; i++)
- {
- (*glyphs)[i].index = hb_glyph[i].codepoint;
- (*glyphs)[i].x = x + (+hb_position->x_offset + hx) * x_scale;
- (*glyphs)[i].y = y + (-hb_position->y_offset + hy) * y_scale;
- hx += hb_position->x_advance;
- hy += -hb_position->y_advance;
-
- hb_position++;
- }
- (*glyphs)[i].index = -1;
- (*glyphs)[i].x = round (hx * x_scale);
- (*glyphs)[i].y = round (hy * y_scale);
-
- if (clusters && *num_clusters && utf8)
- {
- memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0]));
- hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
- *cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
- unsigned int cluster = 0;
- const char *start = utf8, *end;
- (*clusters)[cluster].num_glyphs++;
- if (backward)
- {
- for (i = *num_glyphs - 2; i >= 0; i--)
- {
- if (hb_glyph[i].cluster != hb_glyph[i+1].cluster)
- {
- assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster);
- if (utf8_clusters)
- end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster;
- else
- end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
- (signed) (hb_glyph[i].cluster - hb_glyph[i+1].cluster));
- (*clusters)[cluster].num_bytes = end - start;
- start = end;
- cluster++;
- }
- (*clusters)[cluster].num_glyphs++;
- }
- (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
- }
- else
- {
- for (i = 1; i < (int) *num_glyphs; i++)
- {
- if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
- {
- assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster);
- if (utf8_clusters)
- end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster;
- else
- end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
- (signed) (hb_glyph[i].cluster - hb_glyph[i-1].cluster));
- (*clusters)[cluster].num_bytes = end - start;
- start = end;
- cluster++;
- }
- (*clusters)[cluster].num_glyphs++;
- }
- (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
- }
- }
- else if (num_clusters)
- *num_clusters = 0;
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cairo.h b/src/3rdparty/harfbuzz-ng/src/hb-cairo.h
deleted file mode 100644
index 21e284c8f93..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cairo.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright © 2022 Red Hat, 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): Matthias Clasen
- */
-
-#ifndef HB_CAIRO_H
-#define HB_CAIRO_H
-
-#include "hb.h"
-
-#include <cairo.h>
-
-HB_BEGIN_DECLS
-
-HB_EXTERN cairo_font_face_t *
-hb_cairo_font_face_create_for_font (hb_font_t *font);
-
-HB_EXTERN hb_font_t *
-hb_cairo_font_face_get_font (cairo_font_face_t *font_face);
-
-HB_EXTERN cairo_font_face_t *
-hb_cairo_font_face_create_for_face (hb_face_t *face);
-
-HB_EXTERN hb_face_t *
-hb_cairo_font_face_get_face (cairo_font_face_t *font_face);
-
-/**
- * hb_cairo_font_init_func_t:
- * @font: The #hb_font_t being created
- * @scaled_font: The respective #cairo_scaled_font_t
- * @user_data: User data accompanying this method
- *
- * The type of a virtual method to be called when a cairo
- * face created using hb_cairo_font_face_create_for_face()
- * creates an #hb_font_t for a #cairo_scaled_font_t.
- *
- * Return value: the #hb_font_t value to use; in most cases same as @font
- *
- * Since: 7.0.0
- */
-typedef hb_font_t * (*hb_cairo_font_init_func_t) (hb_font_t *font,
- cairo_scaled_font_t *scaled_font,
- void *user_data);
-
-HB_EXTERN void
-hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
- hb_cairo_font_init_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-HB_EXTERN hb_font_t *
-hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font);
-
-HB_EXTERN void
-hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
- unsigned int scale_factor);
-
-HB_EXTERN unsigned int
-hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face);
-
-HB_EXTERN void
-hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
- hb_bool_t utf8_clusters,
- double x_scale_factor,
- double y_scale_factor,
- double x,
- double y,
- const char *utf8,
- int utf8_len,
- cairo_glyph_t **glyphs,
- unsigned int *num_glyphs,
- cairo_text_cluster_t **clusters,
- unsigned int *num_clusters,
- cairo_text_cluster_flags_t *cluster_flags);
-
-HB_END_DECLS
-
-#endif /* HB_CAIRO_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh
deleted file mode 100644
index 949bfebf9be..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-common.hh
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_CFF_INTERP_COMMON_HH
-#define HB_CFF_INTERP_COMMON_HH
-
-namespace CFF {
-
-using namespace OT;
-
-typedef unsigned int op_code_t;
-
-
-/* === Dict operators === */
-
-/* One byte operators (0-31) */
-#define OpCode_version 0 /* CFF Top */
-#define OpCode_Notice 1 /* CFF Top */
-#define OpCode_FullName 2 /* CFF Top */
-#define OpCode_FamilyName 3 /* CFF Top */
-#define OpCode_Weight 4 /* CFF Top */
-#define OpCode_FontBBox 5 /* CFF Top */
-#define OpCode_BlueValues 6 /* CFF Private, CFF2 Private */
-#define OpCode_OtherBlues 7 /* CFF Private, CFF2 Private */
-#define OpCode_FamilyBlues 8 /* CFF Private, CFF2 Private */
-#define OpCode_FamilyOtherBlues 9 /* CFF Private, CFF2 Private */
-#define OpCode_StdHW 10 /* CFF Private, CFF2 Private */
-#define OpCode_StdVW 11 /* CFF Private, CFF2 Private */
-#define OpCode_escape 12 /* All. Shared with CS */
-#define OpCode_UniqueID 13 /* CFF Top */
-#define OpCode_XUID 14 /* CFF Top */
-#define OpCode_charset 15 /* CFF Top (0) */
-#define OpCode_Encoding 16 /* CFF Top (0) */
-#define OpCode_CharStrings 17 /* CFF Top, CFF2 Top */
-#define OpCode_Private 18 /* CFF Top, CFF2 FD */
-#define OpCode_Subrs 19 /* CFF Private, CFF2 Private */
-#define OpCode_defaultWidthX 20 /* CFF Private (0) */
-#define OpCode_nominalWidthX 21 /* CFF Private (0) */
-#define OpCode_vsindexdict 22 /* CFF2 Private/CS */
-#define OpCode_blenddict 23 /* CFF2 Private/CS */
-#define OpCode_vstore 24 /* CFF2 Top */
-#define OpCode_reserved25 25
-#define OpCode_reserved26 26
-#define OpCode_reserved27 27
-
-/* Numbers */
-#define OpCode_shortint 28 /* 16-bit integer, All */
-#define OpCode_longintdict 29 /* 32-bit integer, All */
-#define OpCode_BCD 30 /* Real number, CFF2 Top/FD */
-#define OpCode_reserved31 31
-
-/* 1-byte integers */
-#define OpCode_OneByteIntFirst 32 /* All. beginning of the range of first byte ints */
-#define OpCode_OneByteIntLast 246 /* All. ending of the range of first byte int */
-
-/* 2-byte integers */
-#define OpCode_TwoBytePosInt0 247 /* All. first byte of two byte positive int (+108 to +1131) */
-#define OpCode_TwoBytePosInt1 248
-#define OpCode_TwoBytePosInt2 249
-#define OpCode_TwoBytePosInt3 250
-
-#define OpCode_TwoByteNegInt0 251 /* All. first byte of two byte negative int (-1131 to -108) */
-#define OpCode_TwoByteNegInt1 252
-#define OpCode_TwoByteNegInt2 253
-#define OpCode_TwoByteNegInt3 254
-
-/* Two byte escape operators 12, (0-41) */
-#define OpCode_ESC_Base 256
-#define Make_OpCode_ESC(byte2) ((op_code_t)(OpCode_ESC_Base + (byte2)))
-
-inline op_code_t Unmake_OpCode_ESC (op_code_t op) { return (op_code_t)(op - OpCode_ESC_Base); }
-inline bool Is_OpCode_ESC (op_code_t op) { return op >= OpCode_ESC_Base; }
-inline unsigned int OpCode_Size (op_code_t op) { return Is_OpCode_ESC (op) ? 2: 1; }
-
-#define OpCode_Copyright Make_OpCode_ESC(0) /* CFF Top */
-#define OpCode_isFixedPitch Make_OpCode_ESC(1) /* CFF Top (false) */
-#define OpCode_ItalicAngle Make_OpCode_ESC(2) /* CFF Top (0) */
-#define OpCode_UnderlinePosition Make_OpCode_ESC(3) /* CFF Top (-100) */
-#define OpCode_UnderlineThickness Make_OpCode_ESC(4) /* CFF Top (50) */
-#define OpCode_PaintType Make_OpCode_ESC(5) /* CFF Top (0) */
-#define OpCode_CharstringType Make_OpCode_ESC(6) /* CFF Top (2) */
-#define OpCode_FontMatrix Make_OpCode_ESC(7) /* CFF Top, CFF2 Top (.001 0 0 .001 0 0)*/
-#define OpCode_StrokeWidth Make_OpCode_ESC(8) /* CFF Top (0) */
-#define OpCode_BlueScale Make_OpCode_ESC(9) /* CFF Private, CFF2 Private (0.039625) */
-#define OpCode_BlueShift Make_OpCode_ESC(10) /* CFF Private, CFF2 Private (7) */
-#define OpCode_BlueFuzz Make_OpCode_ESC(11) /* CFF Private, CFF2 Private (1) */
-#define OpCode_StemSnapH Make_OpCode_ESC(12) /* CFF Private, CFF2 Private */
-#define OpCode_StemSnapV Make_OpCode_ESC(13) /* CFF Private, CFF2 Private */
-#define OpCode_ForceBold Make_OpCode_ESC(14) /* CFF Private (false) */
-#define OpCode_reservedESC15 Make_OpCode_ESC(15)
-#define OpCode_reservedESC16 Make_OpCode_ESC(16)
-#define OpCode_LanguageGroup Make_OpCode_ESC(17) /* CFF Private, CFF2 Private (0) */
-#define OpCode_ExpansionFactor Make_OpCode_ESC(18) /* CFF Private, CFF2 Private (0.06) */
-#define OpCode_initialRandomSeed Make_OpCode_ESC(19) /* CFF Private (0) */
-#define OpCode_SyntheticBase Make_OpCode_ESC(20) /* CFF Top */
-#define OpCode_PostScript Make_OpCode_ESC(21) /* CFF Top */
-#define OpCode_BaseFontName Make_OpCode_ESC(22) /* CFF Top */
-#define OpCode_BaseFontBlend Make_OpCode_ESC(23) /* CFF Top */
-#define OpCode_reservedESC24 Make_OpCode_ESC(24)
-#define OpCode_reservedESC25 Make_OpCode_ESC(25)
-#define OpCode_reservedESC26 Make_OpCode_ESC(26)
-#define OpCode_reservedESC27 Make_OpCode_ESC(27)
-#define OpCode_reservedESC28 Make_OpCode_ESC(28)
-#define OpCode_reservedESC29 Make_OpCode_ESC(29)
-#define OpCode_ROS Make_OpCode_ESC(30) /* CFF Top_CID */
-#define OpCode_CIDFontVersion Make_OpCode_ESC(31) /* CFF Top_CID (0) */
-#define OpCode_CIDFontRevision Make_OpCode_ESC(32) /* CFF Top_CID (0) */
-#define OpCode_CIDFontType Make_OpCode_ESC(33) /* CFF Top_CID (0) */
-#define OpCode_CIDCount Make_OpCode_ESC(34) /* CFF Top_CID (8720) */
-#define OpCode_UIDBase Make_OpCode_ESC(35) /* CFF Top_CID */
-#define OpCode_FDArray Make_OpCode_ESC(36) /* CFF Top_CID, CFF2 Top */
-#define OpCode_FDSelect Make_OpCode_ESC(37) /* CFF Top_CID, CFF2 Top */
-#define OpCode_FontName Make_OpCode_ESC(38) /* CFF Top_CID */
-
-
-/* === CharString operators === */
-
-#define OpCode_hstem 1 /* CFF, CFF2 */
-#define OpCode_Reserved2 2
-#define OpCode_vstem 3 /* CFF, CFF2 */
-#define OpCode_vmoveto 4 /* CFF, CFF2 */
-#define OpCode_rlineto 5 /* CFF, CFF2 */
-#define OpCode_hlineto 6 /* CFF, CFF2 */
-#define OpCode_vlineto 7 /* CFF, CFF2 */
-#define OpCode_rrcurveto 8 /* CFF, CFF2 */
-#define OpCode_Reserved9 9
-#define OpCode_callsubr 10 /* CFF, CFF2 */
-#define OpCode_return 11 /* CFF */
-//#define OpCode_escape 12 /* CFF, CFF2 */
-#define OpCode_Reserved13 13
-#define OpCode_endchar 14 /* CFF */
-#define OpCode_vsindexcs 15 /* CFF2 */
-#define OpCode_blendcs 16 /* CFF2 */
-#define OpCode_Reserved17 17
-#define OpCode_hstemhm 18 /* CFF, CFF2 */
-#define OpCode_hintmask 19 /* CFF, CFF2 */
-#define OpCode_cntrmask 20 /* CFF, CFF2 */
-#define OpCode_rmoveto 21 /* CFF, CFF2 */
-#define OpCode_hmoveto 22 /* CFF, CFF2 */
-#define OpCode_vstemhm 23 /* CFF, CFF2 */
-#define OpCode_rcurveline 24 /* CFF, CFF2 */
-#define OpCode_rlinecurve 25 /* CFF, CFF2 */
-#define OpCode_vvcurveto 26 /* CFF, CFF2 */
-#define OpCode_hhcurveto 27 /* CFF, CFF2 */
-//#define OpCode_shortint 28 /* CFF, CFF2 */
-#define OpCode_callgsubr 29 /* CFF, CFF2 */
-#define OpCode_vhcurveto 30 /* CFF, CFF2 */
-#define OpCode_hvcurveto 31 /* CFF, CFF2 */
-
-#define OpCode_fixedcs 255 /* 32-bit fixed */
-
-/* Two byte escape operators 12, (0-41) */
-#define OpCode_dotsection Make_OpCode_ESC(0) /* CFF (obsoleted) */
-#define OpCode_ReservedESC1 Make_OpCode_ESC(1)
-#define OpCode_ReservedESC2 Make_OpCode_ESC(2)
-#define OpCode_and Make_OpCode_ESC(3) /* CFF */
-#define OpCode_or Make_OpCode_ESC(4) /* CFF */
-#define OpCode_not Make_OpCode_ESC(5) /* CFF */
-#define OpCode_ReservedESC6 Make_OpCode_ESC(6)
-#define OpCode_ReservedESC7 Make_OpCode_ESC(7)
-#define OpCode_ReservedESC8 Make_OpCode_ESC(8)
-#define OpCode_abs Make_OpCode_ESC(9) /* CFF */
-#define OpCode_add Make_OpCode_ESC(10) /* CFF */
-#define OpCode_sub Make_OpCode_ESC(11) /* CFF */
-#define OpCode_div Make_OpCode_ESC(12) /* CFF */
-#define OpCode_ReservedESC13 Make_OpCode_ESC(13)
-#define OpCode_neg Make_OpCode_ESC(14) /* CFF */
-#define OpCode_eq Make_OpCode_ESC(15) /* CFF */
-#define OpCode_ReservedESC16 Make_OpCode_ESC(16)
-#define OpCode_ReservedESC17 Make_OpCode_ESC(17)
-#define OpCode_drop Make_OpCode_ESC(18) /* CFF */
-#define OpCode_ReservedESC19 Make_OpCode_ESC(19)
-#define OpCode_put Make_OpCode_ESC(20) /* CFF */
-#define OpCode_get Make_OpCode_ESC(21) /* CFF */
-#define OpCode_ifelse Make_OpCode_ESC(22) /* CFF */
-#define OpCode_random Make_OpCode_ESC(23) /* CFF */
-#define OpCode_mul Make_OpCode_ESC(24) /* CFF */
-//#define OpCode_reservedESC25 Make_OpCode_ESC(25)
-#define OpCode_sqrt Make_OpCode_ESC(26) /* CFF */
-#define OpCode_dup Make_OpCode_ESC(27) /* CFF */
-#define OpCode_exch Make_OpCode_ESC(28) /* CFF */
-#define OpCode_index Make_OpCode_ESC(29) /* CFF */
-#define OpCode_roll Make_OpCode_ESC(30) /* CFF */
-#define OpCode_reservedESC31 Make_OpCode_ESC(31)
-#define OpCode_reservedESC32 Make_OpCode_ESC(32)
-#define OpCode_reservedESC33 Make_OpCode_ESC(33)
-#define OpCode_hflex Make_OpCode_ESC(34) /* CFF, CFF2 */
-#define OpCode_flex Make_OpCode_ESC(35) /* CFF, CFF2 */
-#define OpCode_hflex1 Make_OpCode_ESC(36) /* CFF, CFF2 */
-#define OpCode_flex1 Make_OpCode_ESC(37) /* CFF, CFF2 */
-
-
-#define OpCode_Invalid 0xFFFFu
-
-
-struct number_t
-{
- void set_int (int v) { value = v; }
- int to_int () const { return value; }
-
- void set_fixed (int32_t v) { value = v / 65536.0; }
- int32_t to_fixed () const { return value * 65536.0; }
-
- void set_real (double v) { value = v; }
- double to_real () const { return value; }
-
- bool in_int_range () const
- { return ((double) (int16_t) to_int () == value); }
-
- bool operator > (const number_t &n) const { return value > n.to_real (); }
- bool operator < (const number_t &n) const { return n > *this; }
- bool operator >= (const number_t &n) const { return !(*this < n); }
- bool operator <= (const number_t &n) const { return !(*this > n); }
-
- const number_t &operator += (const number_t &n)
- {
- set_real (to_real () + n.to_real ());
-
- return *this;
- }
-
- protected:
- double value = 0.;
-};
-
-/* byte string */
-struct UnsizedByteStr : UnsizedArrayOf <HBUINT8>
-{
- hb_ubytes_t as_ubytes (unsigned l) const
- { return hb_ubytes_t ((const unsigned char *) this, l); }
-
- // encode 2-byte int (Dict/CharString) or 4-byte int (Dict)
- template <typename T, typename V>
- static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, V value)
- {
- TRACE_SERIALIZE (this);
-
- HBUINT8 *p = c->allocate_size<HBUINT8> (1);
- if (unlikely (!p)) return_trace (false);
- *p = intOp;
-
- T *ip = c->allocate_size<T> (T::static_size);
- if (unlikely (!ip)) return_trace (false);
- return_trace (c->check_assign (*ip, value, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- template <typename V>
- static bool serialize_int4 (hb_serialize_context_t *c, V value)
- { return serialize_int<HBINT32> (c, OpCode_longintdict, value); }
-
- template <typename V>
- static bool serialize_int2 (hb_serialize_context_t *c, V value)
- { return serialize_int<HBINT16> (c, OpCode_shortint, value); }
-
- /* Defining null_size allows a Null object may be created. Should be safe because:
- * A descendent struct Dict uses a Null pointer to indicate a missing table,
- * checked before access.
- */
- DEFINE_SIZE_MIN(0);
-};
-
-/* A byte string associated with the current offset and an error condition */
-struct byte_str_ref_t
-{
- byte_str_ref_t ()
- : str () {}
-
- byte_str_ref_t (const hb_ubytes_t &str_, unsigned int offset_ = 0)
- : str (str_) { set_offset (offset_); }
-
- void reset (const hb_ubytes_t &str_, unsigned int offset_ = 0)
- {
- str = str_;
- set_offset (offset_);
- }
-
- const unsigned char& operator [] (int i) {
- if (unlikely ((unsigned int) (get_offset () + i) >= str.length))
- {
- set_error ();
- return Null (unsigned char);
- }
- return str.arrayZ[get_offset () + i];
- }
-
- unsigned char head_unchecked () const { return str.arrayZ[get_offset ()]; }
-
- /* Conversion to hb_ubytes_t */
- operator hb_ubytes_t () const { return str.sub_array (get_offset ()); }
-
- hb_ubytes_t sub_array (unsigned int offset_, unsigned int len_) const
- { return str.sub_array (offset_, len_); }
-
- bool avail (unsigned int count=1) const
- { return get_offset () + count <= str.length; }
- void inc (unsigned int count=1)
- {
- /* Automatically puts us in error if count is out-of-range. */
- set_offset (get_offset () + count);
- }
-
- /* We (ab)use ubytes backwards_length as a cursor (called offset),
- * as well as to store error condition. */
-
- unsigned get_offset () const { return str.backwards_length; }
- void set_offset (unsigned offset) { str.backwards_length = offset; }
-
- void set_error () { str.backwards_length = str.length + 1; }
- bool in_error () const { return str.backwards_length > str.length; }
-
- unsigned total_size () const { return str.length; }
-
- protected:
- hb_ubytes_t str;
-};
-
-using byte_str_array_t = hb_vector_t<hb_ubytes_t>;
-
-/* stack */
-template <typename ELEM, int LIMIT>
-struct cff_stack_t
-{
- ELEM& operator [] (unsigned int i)
- {
- if (unlikely (i >= count))
- {
- set_error ();
- return Crap (ELEM);
- }
- return elements[i];
- }
-
- void push (const ELEM &v)
- {
- if (likely (count < LIMIT))
- elements[count++] = v;
- else
- set_error ();
- }
- ELEM &push ()
- {
- if (likely (count < LIMIT))
- return elements[count++];
- else
- {
- set_error ();
- return Crap (ELEM);
- }
- }
-
- ELEM& pop ()
- {
- if (likely (count > 0))
- return elements[--count];
- else
- {
- set_error ();
- return Crap (ELEM);
- }
- }
- void pop (unsigned int n)
- {
- if (likely (count >= n))
- count -= n;
- else
- set_error ();
- }
-
- const ELEM& peek ()
- {
- if (unlikely (count == 0))
- {
- set_error ();
- return Null (ELEM);
- }
- return elements[count - 1];
- }
-
- void unpop ()
- {
- if (likely (count < LIMIT))
- count++;
- else
- set_error ();
- }
-
- void clear () { count = 0; }
-
- bool in_error () const { return (error); }
- void set_error () { error = true; }
-
- unsigned int get_count () const { return count; }
- bool is_empty () const { return !count; }
-
- hb_array_t<const ELEM> sub_array (unsigned start, unsigned length) const
- { return hb_array_t<const ELEM> (elements).sub_array (start, length); }
-
- private:
- bool error = false;
- unsigned int count = 0;
- ELEM elements[LIMIT];
-};
-
-/* argument stack */
-template <typename ARG=number_t>
-struct arg_stack_t : cff_stack_t<ARG, 513>
-{
- void push_int (int v)
- {
- ARG &n = S::push ();
- n.set_int (v);
- }
-
- void push_fixed (int32_t v)
- {
- ARG &n = S::push ();
- n.set_fixed (v);
- }
-
- void push_real (double v)
- {
- ARG &n = S::push ();
- n.set_real (v);
- }
-
- ARG& pop_num () { return this->pop (); }
-
- int pop_int () { return this->pop ().to_int (); }
-
- unsigned int pop_uint ()
- {
- int i = pop_int ();
- if (unlikely (i < 0))
- {
- i = 0;
- S::set_error ();
- }
- return (unsigned) i;
- }
-
- void push_longint_from_substr (byte_str_ref_t& str_ref)
- {
- push_int ((str_ref[0] << 24) | (str_ref[1] << 16) | (str_ref[2] << 8) | (str_ref[3]));
- str_ref.inc (4);
- }
-
- bool push_fixed_from_substr (byte_str_ref_t& str_ref)
- {
- if (unlikely (!str_ref.avail (4)))
- return false;
- push_fixed ((int32_t)*(const HBUINT32*)&str_ref[0]);
- str_ref.inc (4);
- return true;
- }
-
- private:
- typedef cff_stack_t<ARG, 513> S;
-};
-
-/* an operator prefixed by its operands in a byte string */
-struct op_str_t
-{
- /* This used to have a hb_ubytes_t. Using a pointer and length
- * in a particular order, saves 8 bytes in this struct and more
- * in our parsed_cs_op_t subclass. */
-
- const unsigned char *ptr = nullptr;
-
- op_code_t op = OpCode_Invalid;
-
- uint8_t length = 0;
-};
-
-/* base of OP_SERIALIZER */
-struct op_serializer_t
-{
- protected:
- bool copy_opstr (hb_serialize_context_t *c, const op_str_t& opstr) const
- {
- TRACE_SERIALIZE (this);
-
- unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
- if (unlikely (!d)) return_trace (false);
- /* Faster than hb_memcpy for small strings. */
- for (unsigned i = 0; i < opstr.length; i++)
- d[i] = opstr.ptr[i];
- return_trace (true);
- }
-};
-
-template <typename VAL>
-struct parsed_values_t
-{
- void init ()
- {
- opStart = 0;
- values.init ();
- }
- void fini () { values.fini (); }
-
- void alloc (unsigned n)
- {
- values.alloc (n, true);
- }
-
- void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ())
- {
- VAL *val = values.push (v);
- val->op = op;
- auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
- val->ptr = arr.arrayZ;
- val->length = arr.length;
- opStart = str_ref.get_offset ();
- }
-
- bool has_op (op_code_t op) const
- {
- for (const auto& v : values)
- if (v.op == op) return true;
- return false;
- }
-
- unsigned get_count () const { return values.length; }
- const VAL &operator [] (unsigned int i) const { return values[i]; }
-
- unsigned int opStart;
- hb_vector_t<VAL> values;
-};
-
-template <typename ARG=number_t>
-struct interp_env_t
-{
- interp_env_t () {}
- interp_env_t (const hb_ubytes_t &str_)
- {
- str_ref.reset (str_);
- }
- bool in_error () const
- { return str_ref.in_error () || argStack.in_error (); }
-
- void set_error () { str_ref.set_error (); }
-
- op_code_t fetch_op ()
- {
- op_code_t op = OpCode_Invalid;
- if (unlikely (!str_ref.avail ()))
- return OpCode_Invalid;
- op = (op_code_t) str_ref.head_unchecked ();
- str_ref.inc ();
- if (op == OpCode_escape) {
- if (unlikely (!str_ref.avail ()))
- return OpCode_Invalid;
- op = Make_OpCode_ESC (str_ref.head_unchecked ());
- str_ref.inc ();
- }
- return op;
- }
-
- const ARG& eval_arg (unsigned int i) { return argStack[i]; }
-
- ARG& pop_arg () { return argStack.pop (); }
- void pop_n_args (unsigned int n) { argStack.pop (n); }
-
- void clear_args () { pop_n_args (argStack.get_count ()); }
-
- byte_str_ref_t
- str_ref;
- arg_stack_t<ARG>
- argStack;
-};
-
-using num_interp_env_t = interp_env_t<>;
-
-template <typename ARG=number_t>
-struct opset_t
-{
- static void process_op (op_code_t op, interp_env_t<ARG>& env)
- {
- switch (op) {
- case OpCode_shortint:
- env.argStack.push_int ((int16_t)((env.str_ref[0] << 8) | env.str_ref[1]));
- env.str_ref.inc (2);
- break;
-
- case OpCode_TwoBytePosInt0: case OpCode_TwoBytePosInt1:
- case OpCode_TwoBytePosInt2: case OpCode_TwoBytePosInt3:
- env.argStack.push_int ((int16_t)((op - OpCode_TwoBytePosInt0) * 256 + env.str_ref[0] + 108));
- env.str_ref.inc ();
- break;
-
- case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
- case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
- env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
- env.str_ref.inc ();
- break;
-
- default:
- /* 1-byte integer */
- if (likely ((OpCode_OneByteIntFirst <= op) && (op <= OpCode_OneByteIntLast)))
- {
- env.argStack.push_int ((int)op - 139);
- } else {
- /* invalid unknown operator */
- env.clear_args ();
- env.set_error ();
- }
- break;
- }
- }
-};
-
-template <typename ENV>
-struct interpreter_t
-{
- interpreter_t (ENV& env_) : env (env_) {}
- ENV& env;
-};
-
-} /* namespace CFF */
-
-#endif /* HB_CFF_INTERP_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh
deleted file mode 100644
index f40be51f0d7..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-cs-common.hh
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_CFF_INTERP_CS_COMMON_HH
-#define HB_CFF_INTERP_CS_COMMON_HH
-
-#include "hb.hh"
-#include "hb-cff-interp-common.hh"
-
-namespace CFF {
-
-using namespace OT;
-
-enum cs_type_t {
- CSType_CharString,
- CSType_GlobalSubr,
- CSType_LocalSubr
-};
-
-struct call_context_t
-{
- void init (const byte_str_ref_t substr_=byte_str_ref_t (), cs_type_t type_=CSType_CharString, unsigned int subr_num_=0)
- {
- str_ref = substr_;
- type = type_;
- subr_num = subr_num_;
- }
-
- void fini () {}
-
- byte_str_ref_t str_ref;
- cs_type_t type;
- unsigned int subr_num;
-};
-
-/* call stack */
-const unsigned int kMaxCallLimit = 10;
-struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
-
-template <typename SUBRS>
-struct biased_subrs_t
-{
- void init (const SUBRS *subrs_)
- {
- subrs = subrs_;
- unsigned int nSubrs = get_count ();
- if (nSubrs < 1240)
- bias = 107;
- else if (nSubrs < 33900)
- bias = 1131;
- else
- bias = 32768;
- }
-
- void fini () {}
-
- unsigned int get_count () const { return subrs ? subrs->count : 0; }
- unsigned int get_bias () const { return bias; }
-
- hb_ubytes_t operator [] (unsigned int index) const
- {
- if (unlikely (!subrs || index >= subrs->count))
- return hb_ubytes_t ();
- else
- return (*subrs)[index];
- }
-
- protected:
- unsigned int bias;
- const SUBRS *subrs;
-};
-
-struct point_t
-{
- void set_int (int _x, int _y)
- {
- x.set_int (_x);
- y.set_int (_y);
- }
-
- void move_x (const number_t &dx) { x += dx; }
- void move_y (const number_t &dy) { y += dy; }
- void move (const number_t &dx, const number_t &dy) { move_x (dx); move_y (dy); }
- void move (const point_t &d) { move_x (d.x); move_y (d.y); }
-
- number_t x;
- number_t y;
-};
-
-template <typename ARG, typename SUBRS>
-struct cs_interp_env_t : interp_env_t<ARG>
-{
- cs_interp_env_t (const hb_ubytes_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_) :
- interp_env_t<ARG> (str)
- {
- context.init (str, CSType_CharString);
- seen_moveto = true;
- seen_hintmask = false;
- hstem_count = 0;
- vstem_count = 0;
- hintmask_size = 0;
- pt.set_int (0, 0);
- globalSubrs.init (globalSubrs_);
- localSubrs.init (localSubrs_);
- }
- ~cs_interp_env_t ()
- {
- globalSubrs.fini ();
- localSubrs.fini ();
- }
-
- bool in_error () const
- {
- return callStack.in_error () || SUPER::in_error ();
- }
-
- bool pop_subr_num (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
- {
- subr_num = 0;
- int n = SUPER::argStack.pop_int ();
- n += biasedSubrs.get_bias ();
- if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ())))
- return false;
-
- subr_num = (unsigned int)n;
- return true;
- }
-
- void call_subr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
- {
- unsigned int subr_num = 0;
-
- if (unlikely (!pop_subr_num (biasedSubrs, subr_num)
- || callStack.get_count () >= kMaxCallLimit))
- {
- SUPER::set_error ();
- return;
- }
- context.str_ref = SUPER::str_ref;
- callStack.push (context);
-
- context.init ( biasedSubrs[subr_num], type, subr_num);
- SUPER::str_ref = context.str_ref;
- }
-
- void return_from_subr ()
- {
- if (unlikely (SUPER::str_ref.in_error ()))
- SUPER::set_error ();
- context = callStack.pop ();
- SUPER::str_ref = context.str_ref;
- }
-
- void determine_hintmask_size ()
- {
- if (!seen_hintmask)
- {
- vstem_count += SUPER::argStack.get_count() / 2;
- hintmask_size = (hstem_count + vstem_count + 7) >> 3;
- seen_hintmask = true;
- }
- }
-
- void set_endchar (bool endchar_flag_) { endchar_flag = endchar_flag_; }
- bool is_endchar () const { return endchar_flag; }
-
- const number_t &get_x () const { return pt.x; }
- const number_t &get_y () const { return pt.y; }
- const point_t &get_pt () const { return pt; }
-
- void moveto (const point_t &pt_ ) { pt = pt_; }
-
- public:
- call_context_t context;
- bool endchar_flag;
- bool seen_moveto;
- bool seen_hintmask;
-
- unsigned int hstem_count;
- unsigned int vstem_count;
- unsigned int hintmask_size;
- call_stack_t callStack;
- biased_subrs_t<SUBRS> globalSubrs;
- biased_subrs_t<SUBRS> localSubrs;
-
- private:
- point_t pt;
-
- typedef interp_env_t<ARG> SUPER;
-};
-
-template <typename ENV, typename PARAM>
-struct path_procs_null_t
-{
- static void rmoveto (ENV &env, PARAM& param) {}
- static void hmoveto (ENV &env, PARAM& param) {}
- static void vmoveto (ENV &env, PARAM& param) {}
- static void rlineto (ENV &env, PARAM& param) {}
- static void hlineto (ENV &env, PARAM& param) {}
- static void vlineto (ENV &env, PARAM& param) {}
- static void rrcurveto (ENV &env, PARAM& param) {}
- static void rcurveline (ENV &env, PARAM& param) {}
- static void rlinecurve (ENV &env, PARAM& param) {}
- static void vvcurveto (ENV &env, PARAM& param) {}
- static void hhcurveto (ENV &env, PARAM& param) {}
- static void vhcurveto (ENV &env, PARAM& param) {}
- static void hvcurveto (ENV &env, PARAM& param) {}
- static void moveto (ENV &env, PARAM& param, const point_t &pt) {}
- static void line (ENV &env, PARAM& param, const point_t &pt1) {}
- static void curve (ENV &env, PARAM& param, const point_t &pt1, const point_t &pt2, const point_t &pt3) {}
- static void hflex (ENV &env, PARAM& param) {}
- static void flex (ENV &env, PARAM& param) {}
- static void hflex1 (ENV &env, PARAM& param) {}
- static void flex1 (ENV &env, PARAM& param) {}
-};
-
-template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM>>
-struct cs_opset_t : opset_t<ARG>
-{
- static void process_op (op_code_t op, ENV &env, PARAM& param)
- {
- switch (op) {
-
- case OpCode_return:
- env.return_from_subr ();
- break;
- case OpCode_endchar:
- OPSET::check_width (op, env, param);
- env.set_endchar (true);
- OPSET::flush_args_and_op (op, env, param);
- break;
-
- case OpCode_fixedcs:
- env.argStack.push_fixed_from_substr (env.str_ref);
- break;
-
- case OpCode_callsubr:
- env.call_subr (env.localSubrs, CSType_LocalSubr);
- break;
-
- case OpCode_callgsubr:
- env.call_subr (env.globalSubrs, CSType_GlobalSubr);
- break;
-
- case OpCode_hstem:
- case OpCode_hstemhm:
- OPSET::check_width (op, env, param);
- OPSET::process_hstem (op, env, param);
- break;
- case OpCode_vstem:
- case OpCode_vstemhm:
- OPSET::check_width (op, env, param);
- OPSET::process_vstem (op, env, param);
- break;
- case OpCode_hintmask:
- case OpCode_cntrmask:
- OPSET::check_width (op, env, param);
- OPSET::process_hintmask (op, env, param);
- break;
- case OpCode_rmoveto:
- OPSET::check_width (op, env, param);
- PATH::rmoveto (env, param);
- OPSET::process_post_move (op, env, param);
- break;
- case OpCode_hmoveto:
- OPSET::check_width (op, env, param);
- PATH::hmoveto (env, param);
- OPSET::process_post_move (op, env, param);
- break;
- case OpCode_vmoveto:
- OPSET::check_width (op, env, param);
- PATH::vmoveto (env, param);
- OPSET::process_post_move (op, env, param);
- break;
- case OpCode_rlineto:
- PATH::rlineto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_hlineto:
- PATH::hlineto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_vlineto:
- PATH::vlineto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_rrcurveto:
- PATH::rrcurveto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_rcurveline:
- PATH::rcurveline (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_rlinecurve:
- PATH::rlinecurve (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_vvcurveto:
- PATH::vvcurveto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_hhcurveto:
- PATH::hhcurveto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_vhcurveto:
- PATH::vhcurveto (env, param);
- process_post_path (op, env, param);
- break;
- case OpCode_hvcurveto:
- PATH::hvcurveto (env, param);
- process_post_path (op, env, param);
- break;
-
- case OpCode_hflex:
- PATH::hflex (env, param);
- OPSET::process_post_flex (op, env, param);
- break;
-
- case OpCode_flex:
- PATH::flex (env, param);
- OPSET::process_post_flex (op, env, param);
- break;
-
- case OpCode_hflex1:
- PATH::hflex1 (env, param);
- OPSET::process_post_flex (op, env, param);
- break;
-
- case OpCode_flex1:
- PATH::flex1 (env, param);
- OPSET::process_post_flex (op, env, param);
- break;
-
- default:
- SUPER::process_op (op, env);
- break;
- }
- }
-
- static void process_hstem (op_code_t op, ENV &env, PARAM& param)
- {
- env.hstem_count += env.argStack.get_count () / 2;
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static void process_vstem (op_code_t op, ENV &env, PARAM& param)
- {
- env.vstem_count += env.argStack.get_count () / 2;
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static void process_hintmask (op_code_t op, ENV &env, PARAM& param)
- {
- env.determine_hintmask_size ();
- if (likely (env.str_ref.avail (env.hintmask_size)))
- {
- OPSET::flush_hintmask (op, env, param);
- env.str_ref.inc (env.hintmask_size);
- }
- }
-
- static void process_post_flex (op_code_t op, ENV &env, PARAM& param)
- {
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static void check_width (op_code_t op, ENV &env, PARAM& param)
- {}
-
- static void process_post_move (op_code_t op, ENV &env, PARAM& param)
- {
- if (!env.seen_moveto)
- {
- env.determine_hintmask_size ();
- env.seen_moveto = true;
- }
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static void process_post_path (op_code_t op, ENV &env, PARAM& param)
- {
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static void flush_args_and_op (op_code_t op, ENV &env, PARAM& param)
- {
- OPSET::flush_args (env, param);
- OPSET::flush_op (op, env, param);
- }
-
- static void flush_args (ENV &env, PARAM& param)
- {
- env.pop_n_args (env.argStack.get_count ());
- }
-
- static void flush_op (op_code_t op, ENV &env, PARAM& param)
- {
- }
-
- static void flush_hintmask (op_code_t op, ENV &env, PARAM& param)
- {
- OPSET::flush_args_and_op (op, env, param);
- }
-
- static bool is_number_op (op_code_t op)
- {
- switch (op)
- {
- case OpCode_shortint:
- case OpCode_fixedcs:
- case OpCode_TwoBytePosInt0: case OpCode_TwoBytePosInt1:
- case OpCode_TwoBytePosInt2: case OpCode_TwoBytePosInt3:
- case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
- case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
- return true;
-
- default:
- /* 1-byte integer */
- return (OpCode_OneByteIntFirst <= op) && (op <= OpCode_OneByteIntLast);
- }
- }
-
- protected:
- typedef opset_t<ARG> SUPER;
-};
-
-template <typename PATH, typename ENV, typename PARAM>
-struct path_procs_t
-{
- static void rmoveto (ENV &env, PARAM& param)
- {
- point_t pt1 = env.get_pt ();
- const number_t &dy = env.pop_arg ();
- const number_t &dx = env.pop_arg ();
- pt1.move (dx, dy);
- PATH::moveto (env, param, pt1);
- }
-
- static void hmoveto (ENV &env, PARAM& param)
- {
- point_t pt1 = env.get_pt ();
- pt1.move_x (env.pop_arg ());
- PATH::moveto (env, param, pt1);
- }
-
- static void vmoveto (ENV &env, PARAM& param)
- {
- point_t pt1 = env.get_pt ();
- pt1.move_y (env.pop_arg ());
- PATH::moveto (env, param, pt1);
- }
-
- static void rlineto (ENV &env, PARAM& param)
- {
- for (unsigned int i = 0; i + 2 <= env.argStack.get_count (); i += 2)
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- PATH::line (env, param, pt1);
- }
- }
-
- static void hlineto (ENV &env, PARAM& param)
- {
- point_t pt1;
- unsigned int i = 0;
- for (; i + 2 <= env.argStack.get_count (); i += 2)
- {
- pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (i));
- PATH::line (env, param, pt1);
- pt1.move_y (env.eval_arg (i+1));
- PATH::line (env, param, pt1);
- }
- if (i < env.argStack.get_count ())
- {
- pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (i));
- PATH::line (env, param, pt1);
- }
- }
-
- static void vlineto (ENV &env, PARAM& param)
- {
- point_t pt1;
- unsigned int i = 0;
- for (; i + 2 <= env.argStack.get_count (); i += 2)
- {
- pt1 = env.get_pt ();
- pt1.move_y (env.eval_arg (i));
- PATH::line (env, param, pt1);
- pt1.move_x (env.eval_arg (i+1));
- PATH::line (env, param, pt1);
- }
- if (i < env.argStack.get_count ())
- {
- pt1 = env.get_pt ();
- pt1.move_y (env.eval_arg (i));
- PATH::line (env, param, pt1);
- }
- }
-
- static void rrcurveto (ENV &env, PARAM& param)
- {
- for (unsigned int i = 0; i + 6 <= env.argStack.get_count (); i += 6)
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
- point_t pt3 = pt2;
- pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
- }
-
- static void rcurveline (ENV &env, PARAM& param)
- {
- unsigned int arg_count = env.argStack.get_count ();
- if (unlikely (arg_count < 8))
- return;
-
- unsigned int i = 0;
- unsigned int curve_limit = arg_count - 2;
- for (; i + 6 <= curve_limit; i += 6)
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
- point_t pt3 = pt2;
- pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
-
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- PATH::line (env, param, pt1);
- }
-
- static void rlinecurve (ENV &env, PARAM& param)
- {
- unsigned int arg_count = env.argStack.get_count ();
- if (unlikely (arg_count < 8))
- return;
-
- unsigned int i = 0;
- unsigned int line_limit = arg_count - 6;
- for (; i + 2 <= line_limit; i += 2)
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- PATH::line (env, param, pt1);
- }
-
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (i), env.eval_arg (i+1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
- point_t pt3 = pt2;
- pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
-
- static void vvcurveto (ENV &env, PARAM& param)
- {
- unsigned int i = 0;
- point_t pt1 = env.get_pt ();
- if ((env.argStack.get_count () & 1) != 0)
- pt1.move_x (env.eval_arg (i++));
- for (; i + 4 <= env.argStack.get_count (); i += 4)
- {
- pt1.move_y (env.eval_arg (i));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- point_t pt3 = pt2;
- pt3.move_y (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
- pt1 = env.get_pt ();
- }
- }
-
- static void hhcurveto (ENV &env, PARAM& param)
- {
- unsigned int i = 0;
- point_t pt1 = env.get_pt ();
- if ((env.argStack.get_count () & 1) != 0)
- pt1.move_y (env.eval_arg (i++));
- for (; i + 4 <= env.argStack.get_count (); i += 4)
- {
- pt1.move_x (env.eval_arg (i));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- point_t pt3 = pt2;
- pt3.move_x (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
- pt1 = env.get_pt ();
- }
- }
-
- static void vhcurveto (ENV &env, PARAM& param)
- {
- point_t pt1, pt2, pt3;
- unsigned int i = 0;
- if ((env.argStack.get_count () % 8) >= 4)
- {
- point_t pt1 = env.get_pt ();
- pt1.move_y (env.eval_arg (i));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- point_t pt3 = pt2;
- pt3.move_x (env.eval_arg (i+3));
- i += 4;
-
- for (; i + 8 <= env.argStack.get_count (); i += 8)
- {
- PATH::curve (env, param, pt1, pt2, pt3);
- pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (i));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- pt3 = pt2;
- pt3.move_y (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
-
- pt1 = pt3;
- pt1.move_y (env.eval_arg (i+4));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
- pt3 = pt2;
- pt3.move_x (env.eval_arg (i+7));
- }
- if (i < env.argStack.get_count ())
- pt3.move_y (env.eval_arg (i));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
- else
- {
- for (; i + 8 <= env.argStack.get_count (); i += 8)
- {
- pt1 = env.get_pt ();
- pt1.move_y (env.eval_arg (i));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- pt3 = pt2;
- pt3.move_x (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
-
- pt1 = pt3;
- pt1.move_x (env.eval_arg (i+4));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
- pt3 = pt2;
- pt3.move_y (env.eval_arg (i+7));
- if ((env.argStack.get_count () - i < 16) && ((env.argStack.get_count () & 1) != 0))
- pt3.move_x (env.eval_arg (i+8));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
- }
- }
-
- static void hvcurveto (ENV &env, PARAM& param)
- {
- point_t pt1, pt2, pt3;
- unsigned int i = 0;
- if ((env.argStack.get_count () % 8) >= 4)
- {
- point_t pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (i));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- point_t pt3 = pt2;
- pt3.move_y (env.eval_arg (i+3));
- i += 4;
-
- for (; i + 8 <= env.argStack.get_count (); i += 8)
- {
- PATH::curve (env, param, pt1, pt2, pt3);
- pt1 = env.get_pt ();
- pt1.move_y (env.eval_arg (i));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- pt3 = pt2;
- pt3.move_x (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
-
- pt1 = pt3;
- pt1.move_x (env.eval_arg (i+4));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
- pt3 = pt2;
- pt3.move_y (env.eval_arg (i+7));
- }
- if (i < env.argStack.get_count ())
- pt3.move_x (env.eval_arg (i));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
- else
- {
- for (; i + 8 <= env.argStack.get_count (); i += 8)
- {
- pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (i));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
- pt3 = pt2;
- pt3.move_y (env.eval_arg (i+3));
- PATH::curve (env, param, pt1, pt2, pt3);
-
- pt1 = pt3;
- pt1.move_y (env.eval_arg (i+4));
- pt2 = pt1;
- pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
- pt3 = pt2;
- pt3.move_x (env.eval_arg (i+7));
- if ((env.argStack.get_count () - i < 16) && ((env.argStack.get_count () & 1) != 0))
- pt3.move_y (env.eval_arg (i+8));
- PATH::curve (env, param, pt1, pt2, pt3);
- }
- }
- }
-
- /* default actions to be overridden */
- static void moveto (ENV &env, PARAM& param, const point_t &pt)
- { env.moveto (pt); }
-
- static void line (ENV &env, PARAM& param, const point_t &pt1)
- { PATH::moveto (env, param, pt1); }
-
- static void curve (ENV &env, PARAM& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
- { PATH::moveto (env, param, pt3); }
-
- static void hflex (ENV &env, PARAM& param)
- {
- if (likely (env.argStack.get_count () == 7))
- {
- point_t pt1 = env.get_pt ();
- pt1.move_x (env.eval_arg (0));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (1), env.eval_arg (2));
- point_t pt3 = pt2;
- pt3.move_x (env.eval_arg (3));
- point_t pt4 = pt3;
- pt4.move_x (env.eval_arg (4));
- point_t pt5 = pt4;
- pt5.move_x (env.eval_arg (5));
- pt5.y = pt1.y;
- point_t pt6 = pt5;
- pt6.move_x (env.eval_arg (6));
-
- curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
- }
- else
- env.set_error ();
- }
-
- static void flex (ENV &env, PARAM& param)
- {
- if (likely (env.argStack.get_count () == 13))
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (0), env.eval_arg (1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (2), env.eval_arg (3));
- point_t pt3 = pt2;
- pt3.move (env.eval_arg (4), env.eval_arg (5));
- point_t pt4 = pt3;
- pt4.move (env.eval_arg (6), env.eval_arg (7));
- point_t pt5 = pt4;
- pt5.move (env.eval_arg (8), env.eval_arg (9));
- point_t pt6 = pt5;
- pt6.move (env.eval_arg (10), env.eval_arg (11));
-
- curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
- }
- else
- env.set_error ();
- }
-
- static void hflex1 (ENV &env, PARAM& param)
- {
- if (likely (env.argStack.get_count () == 9))
- {
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (0), env.eval_arg (1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (2), env.eval_arg (3));
- point_t pt3 = pt2;
- pt3.move_x (env.eval_arg (4));
- point_t pt4 = pt3;
- pt4.move_x (env.eval_arg (5));
- point_t pt5 = pt4;
- pt5.move (env.eval_arg (6), env.eval_arg (7));
- point_t pt6 = pt5;
- pt6.move_x (env.eval_arg (8));
- pt6.y = env.get_pt ().y;
-
- curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
- }
- else
- env.set_error ();
- }
-
- static void flex1 (ENV &env, PARAM& param)
- {
- if (likely (env.argStack.get_count () == 11))
- {
- point_t d;
- for (unsigned int i = 0; i < 10; i += 2)
- d.move (env.eval_arg (i), env.eval_arg (i+1));
-
- point_t pt1 = env.get_pt ();
- pt1.move (env.eval_arg (0), env.eval_arg (1));
- point_t pt2 = pt1;
- pt2.move (env.eval_arg (2), env.eval_arg (3));
- point_t pt3 = pt2;
- pt3.move (env.eval_arg (4), env.eval_arg (5));
- point_t pt4 = pt3;
- pt4.move (env.eval_arg (6), env.eval_arg (7));
- point_t pt5 = pt4;
- pt5.move (env.eval_arg (8), env.eval_arg (9));
- point_t pt6 = pt5;
-
- if (fabs (d.x.to_real ()) > fabs (d.y.to_real ()))
- {
- pt6.move_x (env.eval_arg (10));
- pt6.y = env.get_pt ().y;
- }
- else
- {
- pt6.x = env.get_pt ().x;
- pt6.move_y (env.eval_arg (10));
- }
-
- curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
- }
- else
- env.set_error ();
- }
-
- protected:
- static void curve2 (ENV &env, PARAM& param,
- const point_t &pt1, const point_t &pt2, const point_t &pt3,
- const point_t &pt4, const point_t &pt5, const point_t &pt6)
- {
- PATH::curve (env, param, pt1, pt2, pt3);
- PATH::curve (env, param, pt4, pt5, pt6);
- }
-};
-
-template <typename ENV, typename OPSET, typename PARAM>
-struct cs_interpreter_t : interpreter_t<ENV>
-{
- cs_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
-
- bool interpret (PARAM& param)
- {
- SUPER::env.set_endchar (false);
-
- unsigned max_ops = HB_CFF_MAX_OPS;
- for (;;) {
- if (unlikely (!--max_ops))
- {
- SUPER::env.set_error ();
- break;
- }
- OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
- if (unlikely (SUPER::env.in_error ()))
- return false;
- if (SUPER::env.is_endchar ())
- break;
- }
-
- return true;
- }
-
- private:
- typedef interpreter_t<ENV> SUPER;
-};
-
-} /* namespace CFF */
-
-#endif /* HB_CFF_INTERP_CS_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh
deleted file mode 100644
index 53226b227e9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff-interp-dict-common.hh
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_CFF_INTERP_DICT_COMMON_HH
-#define HB_CFF_INTERP_DICT_COMMON_HH
-
-#include "hb-cff-interp-common.hh"
-
-namespace CFF {
-
-using namespace OT;
-
-/* an opstr and the parsed out dict value(s) */
-struct dict_val_t : op_str_t
-{
- void init () {}
- void fini () {}
-};
-
-typedef dict_val_t num_dict_val_t;
-
-template <typename VAL> struct dict_values_t : parsed_values_t<VAL> {};
-
-template <typename OPSTR=op_str_t>
-struct top_dict_values_t : dict_values_t<OPSTR>
-{
- void init ()
- {
- dict_values_t<OPSTR>::init ();
- charStringsOffset = 0;
- FDArrayOffset = 0;
- }
- void fini () { dict_values_t<OPSTR>::fini (); }
-
- unsigned int charStringsOffset;
- unsigned int FDArrayOffset;
-};
-
-struct dict_opset_t : opset_t<number_t>
-{
- static void process_op (op_code_t op, interp_env_t<number_t>& env)
- {
- switch (op) {
- case OpCode_longintdict: /* 5-byte integer */
- env.argStack.push_longint_from_substr (env.str_ref);
- break;
-
- case OpCode_BCD: /* real number */
- env.argStack.push_real (parse_bcd (env.str_ref));
- break;
-
- default:
- opset_t<number_t>::process_op (op, env);
- break;
- }
- }
-
- /* Turns CFF's BCD format into strtod understandable string */
- static double parse_bcd (byte_str_ref_t& str_ref)
- {
- if (unlikely (str_ref.in_error ())) return .0;
-
- enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
-
- char buf[32];
- unsigned char byte = 0;
- for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count)
- {
- unsigned nibble;
- if (!(i & 1))
- {
- if (unlikely (!str_ref.avail ())) break;
-
- byte = str_ref[0];
- str_ref.inc ();
- nibble = byte >> 4;
- }
- else
- nibble = byte & 0x0F;
-
- if (unlikely (nibble == RESERVED)) break;
- else if (nibble == END)
- {
- const char *p = buf;
- double pv;
- if (unlikely (!hb_parse_double (&p, p + count, &pv, true/* whole buffer */)))
- break;
- return pv;
- }
- else
- {
- buf[count] = "0123456789.EE?-?"[nibble];
- if (nibble == EXP_NEG)
- {
- ++count;
- if (unlikely (count == ARRAY_LENGTH (buf))) break;
- buf[count] = '-';
- }
- }
- }
-
- str_ref.set_error ();
- return .0;
- }
-
- static bool is_hint_op (op_code_t op)
- {
- switch (op)
- {
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_ForceBold:
- case OpCode_LanguageGroup:
- case OpCode_ExpansionFactor:
- return true;
- default:
- return false;
- }
- }
-};
-
-template <typename VAL=op_str_t>
-struct top_dict_opset_t : dict_opset_t
-{
- static void process_op (op_code_t op, interp_env_t<number_t>& env, top_dict_values_t<VAL> & dictval)
- {
- switch (op) {
- case OpCode_CharStrings:
- dictval.charStringsOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_FDArray:
- dictval.FDArrayOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_FontMatrix:
- env.clear_args ();
- break;
- default:
- dict_opset_t::process_op (op, env);
- break;
- }
- }
-};
-
-template <typename OPSET, typename PARAM, typename ENV=num_interp_env_t>
-struct dict_interpreter_t : interpreter_t<ENV>
-{
- dict_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
-
- bool interpret (PARAM& param)
- {
- param.init ();
- while (SUPER::env.str_ref.avail ())
- {
- OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
- if (unlikely (SUPER::env.in_error ()))
- return false;
- }
-
- return true;
- }
-
- private:
- typedef interpreter_t<ENV> SUPER;
-};
-
-} /* namespace CFF */
-
-#endif /* HB_CFF_INTERP_DICT_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff1-interp-cs.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff1-interp-cs.hh
deleted file mode 100644
index d8868efa53f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff1-interp-cs.hh
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_CFF1_INTERP_CS_HH
-#define HB_CFF1_INTERP_CS_HH
-
-#include "hb.hh"
-#include "hb-cff-interp-cs-common.hh"
-
-namespace CFF {
-
-using namespace OT;
-
-typedef biased_subrs_t<CFF1Subrs> cff1_biased_subrs_t;
-
-struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
-{
- template <typename ACC>
- cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
- const int *coords_=nullptr, unsigned int num_coords_=0)
- : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
- {
- processed_width = false;
- has_width = false;
- arg_start = 0;
- in_seac = false;
- }
-
- void set_width (bool has_width_)
- {
- if (likely (!processed_width && (SUPER::argStack.get_count () > 0)))
- {
- if (has_width_)
- {
- width = SUPER::argStack[0];
- has_width = true;
- arg_start = 1;
- }
- }
- processed_width = true;
- }
-
- void clear_args ()
- {
- arg_start = 0;
- SUPER::clear_args ();
- }
-
- void set_in_seac (bool _in_seac) { in_seac = _in_seac; }
-
- bool processed_width;
- bool has_width;
- unsigned int arg_start;
- number_t width;
- bool in_seac;
-
- private:
- typedef cs_interp_env_t<number_t, CFF1Subrs> SUPER;
-};
-
-template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff1_cs_interp_env_t, PARAM>>
-struct cff1_cs_opset_t : cs_opset_t<number_t, OPSET, cff1_cs_interp_env_t, PARAM, PATH>
-{
- /* PostScript-originated legacy opcodes (OpCode_add etc) are unsupported */
- /* Type 1-originated deprecated opcodes, seac behavior of endchar and dotsection are supported */
-
- static void process_op (op_code_t op, cff1_cs_interp_env_t &env, PARAM& param)
- {
- switch (op) {
- case OpCode_dotsection:
- SUPER::flush_args_and_op (op, env, param);
- break;
-
- case OpCode_endchar:
- OPSET::check_width (op, env, param);
- if (env.argStack.get_count () >= 4)
- {
- OPSET::process_seac (env, param);
- }
- OPSET::flush_args_and_op (op, env, param);
- env.set_endchar (true);
- break;
-
- default:
- SUPER::process_op (op, env, param);
- }
- }
-
- static void check_width (op_code_t op, cff1_cs_interp_env_t &env, PARAM& param)
- {
- if (!env.processed_width)
- {
- bool has_width = false;
- switch (op)
- {
- case OpCode_endchar:
- case OpCode_hstem:
- case OpCode_hstemhm:
- case OpCode_vstem:
- case OpCode_vstemhm:
- case OpCode_hintmask:
- case OpCode_cntrmask:
- has_width = ((env.argStack.get_count () & 1) != 0);
- break;
- case OpCode_hmoveto:
- case OpCode_vmoveto:
- has_width = (env.argStack.get_count () > 1);
- break;
- case OpCode_rmoveto:
- has_width = (env.argStack.get_count () > 2);
- break;
- default:
- return;
- }
- env.set_width (has_width);
- }
- }
-
- static void process_seac (cff1_cs_interp_env_t &env, PARAM& param)
- {
- }
-
- static void flush_args (cff1_cs_interp_env_t &env, PARAM& param)
- {
- SUPER::flush_args (env, param);
- env.clear_args (); /* pop off width */
- }
-
- private:
- typedef cs_opset_t<number_t, OPSET, cff1_cs_interp_env_t, PARAM, PATH> SUPER;
-};
-
-template <typename OPSET, typename PARAM>
-using cff1_cs_interpreter_t = cs_interpreter_t<cff1_cs_interp_env_t, OPSET, PARAM>;
-
-} /* namespace CFF */
-
-#endif /* HB_CFF1_INTERP_CS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh
deleted file mode 100644
index 915b10cf39a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_CFF2_INTERP_CS_HH
-#define HB_CFF2_INTERP_CS_HH
-
-#include "hb.hh"
-#include "hb-cff-interp-cs-common.hh"
-
-namespace CFF {
-
-using namespace OT;
-
-struct blend_arg_t : number_t
-{
- void set_int (int v) { reset_blends (); number_t::set_int (v); }
- void set_fixed (int32_t v) { reset_blends (); number_t::set_fixed (v); }
- void set_real (double v) { reset_blends (); number_t::set_real (v); }
-
- void set_blends (unsigned int numValues_, unsigned int valueIndex_,
- hb_array_t<const blend_arg_t> blends_)
- {
- numValues = numValues_;
- valueIndex = valueIndex_;
- unsigned numBlends = blends_.length;
- if (unlikely (!deltas.resize_exact (numBlends)))
- return;
- for (unsigned int i = 0; i < numBlends; i++)
- deltas.arrayZ[i] = blends_.arrayZ[i];
- }
-
- bool blending () const { return deltas.length > 0; }
- void reset_blends ()
- {
- numValues = valueIndex = 0;
- deltas.shrink (0);
- }
-
- unsigned int numValues;
- unsigned int valueIndex;
- hb_vector_t<number_t> deltas;
-};
-
-typedef biased_subrs_t<CFF2Subrs> cff2_biased_subrs_t;
-
-template <typename ELEM>
-struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs>
-{
- template <typename ACC>
- cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
- const int *coords_=nullptr, unsigned int num_coords_=0)
- : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
- {
- coords = coords_;
- num_coords = num_coords_;
- varStore = acc.varStore;
- seen_blend = false;
- seen_vsindex_ = false;
- scalars.init ();
- do_blend = num_coords && coords && varStore->size;
- set_ivs (acc.privateDicts[fd].ivs);
- }
-
- void fini ()
- {
- scalars.fini ();
- SUPER::fini ();
- }
-
- op_code_t fetch_op ()
- {
- if (this->str_ref.avail ())
- return SUPER::fetch_op ();
-
- /* make up return or endchar op */
- if (this->callStack.is_empty ())
- return OpCode_endchar;
- else
- return OpCode_return;
- }
-
- const ELEM& eval_arg (unsigned int i)
- {
- return SUPER::argStack[i];
- }
-
- const ELEM& pop_arg ()
- {
- return SUPER::argStack.pop ();
- }
-
- void process_blend ()
- {
- if (!seen_blend)
- {
- region_count = varStore->varStore.get_region_index_count (get_ivs ());
- if (do_blend)
- {
- if (unlikely (!scalars.resize_exact (region_count)))
- SUPER::set_error ();
- else
- varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords,
- &scalars[0], region_count);
- }
- seen_blend = true;
- }
- }
-
- void process_vsindex ()
- {
- unsigned int index = SUPER::argStack.pop_uint ();
- if (unlikely (seen_vsindex () || seen_blend))
- {
- SUPER::set_error ();
- }
- else
- {
- set_ivs (index);
- }
- seen_vsindex_ = true;
- }
-
- unsigned int get_region_count () const { return region_count; }
- void set_region_count (unsigned int region_count_) { region_count = region_count_; }
- unsigned int get_ivs () const { return ivs; }
- void set_ivs (unsigned int ivs_) { ivs = ivs_; }
- bool seen_vsindex () const { return seen_vsindex_; }
-
- double blend_deltas (hb_array_t<const ELEM> deltas) const
- {
- double v = 0;
- if (do_blend)
- {
- if (likely (scalars.length == deltas.length))
- {
- unsigned count = scalars.length;
- for (unsigned i = 0; i < count; i++)
- v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real ();
- }
- }
- return v;
- }
-
- bool have_coords () const { return num_coords; }
-
- protected:
- const int *coords;
- unsigned int num_coords;
- const CFF2VariationStore *varStore;
- unsigned int region_count;
- unsigned int ivs;
- hb_vector_t<float> scalars;
- bool do_blend;
- bool seen_vsindex_;
- bool seen_blend;
-
- typedef cs_interp_env_t<ELEM, CFF2Subrs> SUPER;
-};
-template <typename OPSET, typename PARAM, typename ELEM, typename PATH=path_procs_null_t<cff2_cs_interp_env_t<ELEM>, PARAM>>
-struct cff2_cs_opset_t : cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PARAM, PATH>
-{
- static void process_op (op_code_t op, cff2_cs_interp_env_t<ELEM> &env, PARAM& param)
- {
- switch (op) {
- case OpCode_callsubr:
- case OpCode_callgsubr:
- /* a subroutine number shouldn't be a blended value */
-#if 0
- if (unlikely (env.argStack.peek ().blending ()))
- {
- env.set_error ();
- break;
- }
-#endif
- SUPER::process_op (op, env, param);
- break;
-
- case OpCode_blendcs:
- OPSET::process_blend (env, param);
- break;
-
- case OpCode_vsindexcs:
-#if 0
- if (unlikely (env.argStack.peek ().blending ()))
- {
- env.set_error ();
- break;
- }
-#endif
- OPSET::process_vsindex (env, param);
- break;
-
- default:
- SUPER::process_op (op, env, param);
- }
- }
-
- template <typename T = ELEM,
- hb_enable_if (hb_is_same (T, blend_arg_t))>
- static void process_arg_blend (cff2_cs_interp_env_t<ELEM> &env,
- ELEM &arg,
- const hb_array_t<const ELEM> blends,
- unsigned n, unsigned i)
- {
- if (env.have_coords ())
- arg.set_int (round (arg.to_real () + env.blend_deltas (blends)));
- else
- arg.set_blends (n, i, blends);
- }
- template <typename T = ELEM,
- hb_enable_if (!hb_is_same (T, blend_arg_t))>
- static void process_arg_blend (cff2_cs_interp_env_t<ELEM> &env,
- ELEM &arg,
- const hb_array_t<const ELEM> blends,
- unsigned n, unsigned i)
- {
- arg.set_real (arg.to_real () + env.blend_deltas (blends));
- }
-
- static void process_blend (cff2_cs_interp_env_t<ELEM> &env, PARAM& param)
- {
- unsigned int n, k;
-
- env.process_blend ();
- k = env.get_region_count ();
- n = env.argStack.pop_uint ();
- /* copy the blend values into blend array of the default values */
- unsigned int start = env.argStack.get_count () - ((k+1) * n);
- /* let an obvious error case fail, but note CFF2 spec doesn't forbid n==0 */
- if (unlikely (start > env.argStack.get_count ()))
- {
- env.set_error ();
- return;
- }
- for (unsigned int i = 0; i < n; i++)
- {
- const hb_array_t<const ELEM> blends = env.argStack.sub_array (start + n + (i * k), k);
- process_arg_blend (env, env.argStack[start + i], blends, n, i);
- }
-
- /* pop off blend values leaving default values now adorned with blend values */
- env.argStack.pop (k * n);
- }
-
- static void process_vsindex (cff2_cs_interp_env_t<ELEM> &env, PARAM& param)
- {
- env.process_vsindex ();
- env.clear_args ();
- }
-
- private:
- typedef cs_opset_t<ELEM, OPSET, cff2_cs_interp_env_t<ELEM>, PARAM, PATH> SUPER;
-};
-
-template <typename OPSET, typename PARAM, typename ELEM>
-using cff2_cs_interpreter_t = cs_interpreter_t<cff2_cs_interp_env_t<ELEM>, OPSET, PARAM>;
-
-} /* namespace CFF */
-
-#endif /* HB_CFF2_INTERP_CS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
index 282a8e4d0f6..cb1fb43ffbb 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
@@ -26,54 +26,33 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-#include "hb-machinery.hh"
+#include "hb-private.hh"
+#include "hb-mutex-private.hh"
+#include "hb-object-private.hh"
-/**
- * SECTION:hb-common
- * @title: hb-common
- * @short_description: Common data types
- * @include: hb.h
- *
- * Common data types used across HarfBuzz are defined here.
- **/
+#include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
/* hb_options_t */
-hb_atomic_int_t _hb_options;
+hb_options_union_t _hb_options;
void
-_hb_options_init ()
+_hb_options_init (void)
{
hb_options_union_t u;
u.i = 0;
- u.opts.initialized = true;
-
- const char *c = getenv ("HB_OPTIONS");
- if (c)
- {
- while (*c)
- {
- const char *p = strchr (c, ':');
- if (!p)
- p = c + strlen (c);
-
-#define OPTION(name, symbol) \
- if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
-
- OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
-
-#undef OPTION
-
- c = *p ? p + 1 : p;
- }
+ u.opts.initialized = 1;
- }
+ char *c = getenv ("HB_OPTIONS");
+ u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
/* This is idempotent and threadsafe. */
- _hb_options = u.i;
+ _hb_options = u;
}
@@ -81,15 +60,12 @@ _hb_options_init ()
/**
* hb_tag_from_string:
- * @str: (array length=len) (element-type uint8_t): String to convert
- * @len: Length of @str, or -1 if it is `NULL`-terminated
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
*
- * Converts a string into an #hb_tag_t. Valid tags
- * are four characters. Shorter input strings will be
- * padded with spaces. Longer input strings will be
- * truncated.
+ *
*
- * Return value: The #hb_tag_t corresponding to @str
+ * Return value:
*
* Since: 0.9.2
**/
@@ -114,11 +90,10 @@ hb_tag_from_string (const char *str, int len)
/**
* hb_tag_to_string:
- * @tag: #hb_tag_t to convert
- * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
+ * @tag:
+ * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
*
- * Converts an #hb_tag_t to a string and returns it in @buf.
- * Strings will be four characters long.
+ *
*
* Since: 0.9.5
**/
@@ -134,7 +109,7 @@ hb_tag_to_string (hb_tag_t tag, char *buf)
/* hb_direction_t */
-static const char direction_strings[][4] = {
+const char direction_strings[][4] = {
"ltr",
"rtl",
"ttb",
@@ -143,17 +118,12 @@ static const char direction_strings[][4] = {
/**
* hb_direction_from_string:
- * @str: (array length=len) (element-type uint8_t): String to convert
- * @len: Length of @str, or -1 if it is `NULL`-terminated
- *
- * Converts a string to an #hb_direction_t.
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
*
- * Matching is loose and applies only to the first letter. For
- * examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
+ *
*
- * Unmatched strings will return #HB_DIRECTION_INVALID.
- *
- * Return value: The #hb_direction_t matching @str
+ * Return value:
*
* Since: 0.9.2
**/
@@ -176,11 +146,11 @@ hb_direction_from_string (const char *str, int len)
/**
* hb_direction_to_string:
- * @direction: The #hb_direction_t to convert
+ * @direction:
*
- * Converts an #hb_direction_t to a string.
+ *
*
- * Return value: (transfer none): The string corresponding to @direction
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
@@ -206,7 +176,7 @@ static const char canon_map[256] = {
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', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
- 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
@@ -249,17 +219,20 @@ struct hb_language_item_t {
struct hb_language_item_t *next;
hb_language_t lang;
- bool operator == (const char *s) const
- { return lang_equal (lang, s); }
+ inline bool operator == (const char *s) const {
+ return lang_equal (lang, s);
+ }
- hb_language_item_t & operator = (const char *s)
- {
- /* We can't call strdup(), because we allow custom allocators. */
+ inline hb_language_item_t & operator = (const char *s) {
+ /* 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) hb_malloc(len);
+ lang = (hb_language_t) malloc(len);
if (likely (lang))
{
- hb_memcpy((unsigned char *) lang, s, len);
+ memcpy((unsigned char *) lang, s, len);
for (unsigned char *p = (unsigned char *) lang; *p; p++)
*p = canon_map[*p];
}
@@ -267,61 +240,59 @@ struct hb_language_item_t {
return *this;
}
- void fini () { hb_free ((void *) lang); }
+ void finish (void) { free ((void *) lang); }
};
-/* Thread-safe lockfree language list */
+/* Thread-safe lock-free language list */
-static hb_atomic_ptr_t <hb_language_item_t> langs;
+static hb_language_item_t *langs;
-static inline void
-free_langs ()
+#ifdef HB_USE_ATEXIT
+static void
+free_langs (void)
{
-retry:
- hb_language_item_t *first_lang = langs;
- if (unlikely (!langs.cmpexch (first_lang, nullptr)))
- goto retry;
-
- while (first_lang) {
- hb_language_item_t *next = first_lang->next;
- first_lang->fini ();
- hb_free (first_lang);
- first_lang = next;
+ while (langs) {
+ hb_language_item_t *next = langs->next;
+ langs->finish ();
+ free (langs);
+ langs = next;
}
}
+#endif
static hb_language_item_t *
lang_find_or_insert (const char *key)
{
retry:
- hb_language_item_t *first_lang = langs;
+ hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
if (*lang == key)
return lang;
/* Not found; allocate one. */
- hb_language_item_t *lang = (hb_language_item_t *) hb_calloc (1, sizeof (hb_language_item_t));
+ hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
if (unlikely (!lang))
return nullptr;
lang->next = first_lang;
*lang = key;
if (unlikely (!lang->lang))
{
- hb_free (lang);
+ free (lang);
return nullptr;
}
- if (unlikely (!langs.cmpexch (first_lang, lang)))
- {
- lang->fini ();
- hb_free (lang);
+ if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
+ lang->finish ();
+ free (lang);
goto retry;
}
+#ifdef HB_USE_ATEXIT
if (!first_lang)
- hb_atexit (free_langs); /* First person registers atexit() callback. */
+ atexit (free_langs); /* First person registers atexit() callback. */
+#endif
return lang;
}
@@ -330,14 +301,14 @@ retry:
/**
* hb_language_from_string:
* @str: (array length=len) (element-type uint8_t): a string representing
- * a BCP 47 language tag
- * @len: length of the @str, or -1 if it is `NULL`-terminated.
+ * ISO 639 language code
+ * @len: length of the @str, or -1 if it is %NULL-terminated.
*
- * Converts @str representing a BCP 47 language tag to the corresponding
+ * Converts @str representing an ISO 639 language code to the corresponding
* #hb_language_t.
*
* Return value: (transfer none):
- * The #hb_language_t corresponding to the BCP 47 language tag.
+ * The #hb_language_t corresponding to the ISO 639 language code.
*
* Since: 0.9.2
**/
@@ -352,8 +323,8 @@ hb_language_from_string (const char *str, int len)
{
/* NUL-terminate it. */
char strbuf[64];
- len = hb_min (len, (int) sizeof (strbuf) - 1);
- hb_memcpy (strbuf, str, len);
+ len = MIN (len, (int) sizeof (strbuf) - 1);
+ memcpy (strbuf, str, len);
strbuf[len] = '\0';
item = lang_find_or_insert (strbuf);
}
@@ -365,12 +336,12 @@ hb_language_from_string (const char *str, int len)
/**
* hb_language_to_string:
- * @language: The #hb_language_t to convert
+ * @language: an #hb_language_t to convert.
*
- * Converts an #hb_language_t to a string.
+ * See hb_language_from_string().
*
* Return value: (transfer none):
- * A `NULL`-terminated string representing the @language. Must not be freed by
+ * A %NULL-terminated string representing the @language. Must not be freed by
* the caller.
*
* Since: 0.9.2
@@ -378,73 +349,31 @@ hb_language_from_string (const char *str, int len)
const char *
hb_language_to_string (hb_language_t language)
{
- if (unlikely (!language)) return nullptr;
-
+ /* This is actually nullptr-safe! */
return language->s;
}
/**
* hb_language_get_default:
*
- * Fetch the default language from current locale.
+ *
*
- * <note>Note that the first time this function is called, it calls
- * "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying
- * setlocale function is, in many implementations, NOT threadsafe. To avoid
- * problems, call this function once before multiple threads can call it.
- * This function is only used from hb_buffer_guess_segment_properties() by
- * HarfBuzz itself.</note>
- *
- * Return value: (transfer none): The default language of the locale as
- * an #hb_language_t
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
hb_language_t
-hb_language_get_default ()
+hb_language_get_default (void)
{
- static hb_atomic_ptr_t <hb_language_t> default_language;
+ static hb_language_t default_language = HB_LANGUAGE_INVALID;
- hb_language_t language = default_language;
- if (unlikely (language == HB_LANGUAGE_INVALID))
- {
- language = hb_language_from_string (hb_setlocale (LC_CTYPE, nullptr), -1);
- (void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
+ 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, nullptr), -1);
+ (void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
}
- return language;
-}
-
-/**
- * hb_language_matches:
- * @language: The #hb_language_t to work on
- * @specific: Another #hb_language_t
- *
- * Check whether a second language tag is the same or a more
- * specific version of the provided language tag. For example,
- * "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR".
- *
- * Return value: `true` if languages match, `false` otherwise.
- *
- * Since: 5.0.0
- **/
-hb_bool_t
-hb_language_matches (hb_language_t language,
- hb_language_t specific)
-{
- if (language == specific) return true;
- if (!language || !specific) return false;
-
- const char *l = language->s;
- const char *s = specific->s;
- unsigned ll = strlen (l);
- unsigned sl = strlen (s);
-
- if (ll > sl)
- return false;
-
- return strncmp (l, s, ll) == 0 &&
- (s[ll] == '\0' || s[ll] == '-');
+ return default_language;
}
@@ -452,12 +381,12 @@ hb_language_matches (hb_language_t language,
/**
* hb_script_from_iso15924_tag:
- * @tag: an #hb_tag_t representing an ISO 15924 tag.
+ * @tag: an #hb_tag_t representing an ISO 15924 tag.
*
- * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
+ * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
*
- * Return value:
- * An #hb_script_t corresponding to the ISO 15924 tag.
+ * Return value:
+ * An #hb_script_t corresponding to the ISO 15924 tag.
*
* Since: 0.9.2
**/
@@ -478,13 +407,8 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
- /* Script variants from https://unicode.org/iso15924/ */
- case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC;
+ /* Script variants from http://unicode.org/iso15924/ */
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
- case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN;
- case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN;
- case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN;
- case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL;
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
@@ -503,15 +427,15 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
/**
* hb_script_from_string:
* @str: (array length=len) (element-type uint8_t): a string representing an
- * ISO 15924 tag.
- * @len: length of the @str, or -1 if it is `NULL`-terminated.
+ * ISO 15924 tag.
+ * @len: length of the @str, or -1 if it is %NULL-terminated.
*
- * Converts a string @str representing an ISO 15924 script tag to a
+ * Converts a string @str representing an ISO 15924 script tag to a
* corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
* hb_script_from_iso15924_tag().
*
- * Return value:
- * An #hb_script_t corresponding to the ISO 15924 tag.
+ * Return value:
+ * An #hb_script_t corresponding to the ISO 15924 tag.
*
* Since: 0.9.2
**/
@@ -523,12 +447,12 @@ hb_script_from_string (const char *str, int len)
/**
* hb_script_to_iso15924_tag:
- * @script: an #hb_script_t to convert.
+ * @script: an #hb_script_ to convert.
*
- * Converts an #hb_script_t to a corresponding ISO 15924 script tag.
+ * See hb_script_from_iso15924_tag().
*
* Return value:
- * An #hb_tag_t representing an ISO 15924 script tag.
+ * An #hb_tag_t representing an ISO 15924 script tag.
*
* Since: 0.9.2
**/
@@ -540,23 +464,18 @@ hb_script_to_iso15924_tag (hb_script_t script)
/**
* hb_script_get_horizontal_direction:
- * @script: The #hb_script_t to query
+ * @script:
*
- * Fetches the #hb_direction_t of a script when it is
- * set horizontally. All right-to-left scripts will return
- * #HB_DIRECTION_RTL. All left-to-right scripts will return
- * #HB_DIRECTION_LTR. Scripts that can be written either
- * horizontally or vertically will return #HB_DIRECTION_INVALID.
- * Unknown scripts will return #HB_DIRECTION_LTR.
+ *
*
- * Return value: The horizontal #hb_direction_t of @script
+ * Return value:
*
* Since: 0.9.2
**/
hb_direction_t
hb_script_get_horizontal_direction (hb_script_t script)
{
- /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
+ /* http://goo.gl/x9ilM */
switch ((hb_tag_t) script)
{
/* Unicode-1.1 additions */
@@ -605,62 +524,57 @@ hb_script_get_horizontal_direction (hb_script_t script)
case HB_SCRIPT_PSALTER_PAHLAVI:
/* Unicode-8.0 additions */
- case HB_SCRIPT_HATRAN:
+ case HB_SCRIPT_OLD_HUNGARIAN:
/* Unicode-9.0 additions */
case HB_SCRIPT_ADLAM:
- /* Unicode-11.0 additions */
- case HB_SCRIPT_HANIFI_ROHINGYA:
- case HB_SCRIPT_OLD_SOGDIAN:
- case HB_SCRIPT_SOGDIAN:
-
- /* Unicode-12.0 additions */
- case HB_SCRIPT_ELYMAIC:
+ return HB_DIRECTION_RTL;
+ }
- /* Unicode-13.0 additions */
- case HB_SCRIPT_CHORASMIAN:
- case HB_SCRIPT_YEZIDI:
+ return HB_DIRECTION_LTR;
+}
- /* Unicode-14.0 additions */
- case HB_SCRIPT_OLD_UYGHUR:
- return HB_DIRECTION_RTL;
+/* hb_user_data_array_t */
+bool
+hb_user_data_array_t::set (hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ if (!key)
+ return false;
- /* https://github.com/harfbuzz/harfbuzz/issues/1000 */
- case HB_SCRIPT_OLD_HUNGARIAN:
- case HB_SCRIPT_OLD_ITALIC:
- case HB_SCRIPT_RUNIC:
- case HB_SCRIPT_TIFINAGH:
-
- return HB_DIRECTION_INVALID;
+ if (replace) {
+ if (!data && !destroy) {
+ items.remove (key, lock);
+ return true;
+ }
}
+ hb_user_data_item_t item = {key, data, destroy};
+ bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
- return HB_DIRECTION_LTR;
+ return ret;
}
+void *
+hb_user_data_array_t::get (hb_user_data_key_t *key)
+{
+ hb_user_data_item_t item = {nullptr, nullptr, nullptr};
-/* hb_version */
+ return items.find (key, &item, lock) ? item.data : nullptr;
+}
-/**
- * SECTION:hb-version
- * @title: hb-version
- * @short_description: Information about the version of HarfBuzz in use
- * @include: hb.h
- *
- * These functions and macros allow accessing version of the HarfBuzz
- * library used at compile- as well as run-time, and to direct code
- * conditionally based on those versions, again, at compile- or run-time.
- **/
-
+/* hb_version */
/**
* hb_version:
- * @major: (out): Library major version component
- * @minor: (out): Library minor version component
- * @micro: (out): Library micro version component
+ * @major: (out): Library major version component.
+ * @minor: (out): Library minor version component.
+ * @micro: (out): Library micro version component.
*
* Returns library version as three integer components.
*
@@ -681,27 +595,25 @@ hb_version (unsigned int *major,
*
* Returns library version as a string with three components.
*
- * Return value: Library version string
+ * Return value: library version string.
*
* Since: 0.9.2
**/
const char *
-hb_version_string ()
+hb_version_string (void)
{
return HB_VERSION_STRING;
}
/**
* hb_version_atleast:
- * @major: Library major version component
- * @minor: Library minor version component
- * @micro: Library micro version component
+ * @major:
+ * @minor:
+ * @micro:
*
- * Tests the library version against a minimum value,
- * as three integer components.
+ *
*
- * Return value: `true` if the library is equal to or greater than
- * the test value, `false` otherwise
+ * Return value:
*
* Since: 0.9.30
**/
@@ -740,24 +652,125 @@ parse_char (const char **pp, const char *end, char c)
static bool
parse_uint (const char **pp, const char *end, unsigned int *pv)
{
- /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
- * such that -1 turns into "big number"... */
- int v;
- if (unlikely (!hb_parse_int (pp, end, &v))) return false;
+ 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)
{
- /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
- * such that -1 turns into "big number"... */
- int v;
- if (unlikely (!hb_parse_int (pp, end, &v))) return false;
+ 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;
}
@@ -771,14 +784,9 @@ parse_bool (const char **pp, const char *end, uint32_t *pv)
(*pp)++;
/* CSS allows on/off as aliases 1/0. */
- if (*pp - p == 2
- && TOLOWER (p[0]) == 'o'
- && TOLOWER (p[1]) == 'n')
+ if (*pp - p == 2 && 0 == strncmp (p, "on", 2))
*pv = 1;
- else if (*pp - p == 3
- && TOLOWER (p[0]) == 'o'
- && TOLOWER (p[1]) == 'f'
- && TOLOWER (p[2]) == 'f')
+ else if (*pp - p == 3 && 0 == strncmp (p, "off", 3))
*pv = 0;
else
return false;
@@ -815,7 +823,7 @@ parse_tag (const char **pp, const char *end, hb_tag_t *tag)
}
const char *p = *pp;
- while (*pp < end && (ISALNUM(**pp) || **pp == '_'))
+ while (*pp < end && ISALNUM(**pp))
(*pp)++;
if (p == *pp || *pp - p > 4)
@@ -844,15 +852,15 @@ parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
bool has_start;
- feature->start = HB_FEATURE_GLOBAL_START;
- feature->end = HB_FEATURE_GLOBAL_END;
+ 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_char (pp, end, ';')) {
+ if (parse_char (pp, end, ':')) {
parse_uint (pp, end, &feature->end);
} else {
if (has_start)
@@ -867,10 +875,10 @@ parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *fea
{
bool had_equal = parse_char (pp, end, '=');
bool had_value = parse_uint32 (pp, end, &feature->value) ||
- parse_bool (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 equal-sign is ok, but not required. */
+ * A value without an eqaul-sign is ok, but not required. */
return !had_equal || had_value;
}
@@ -888,49 +896,15 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
/**
* 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
+ * @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.
*
- * The format for specifying feature strings follows. All valid CSS
- * font-feature-settings values other than 'normal' and the global values are
- * also accepted, though not documented below. CSS string escapes are not
- * supported.
- *
- * The range indices refer to the positions between Unicode characters. The
- * position before the first character is always 0.
- *
- * The format is Python-esque. Here is how it all works:
- *
- * <informaltable pgwide='1' align='left' frame='none'>
- * <tgroup cols='5'>
- * <thead>
- * <row><entry>Syntax</entry> <entry>Value</entry> <entry>Start</entry> <entry>End</entry></row>
- * </thead>
- * <tbody>
- * <row><entry>Setting value:</entry></row>
- * <row><entry>kern</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row>
- * <row><entry>+kern</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row>
- * <row><entry>-kern</entry> <entry>0</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature off</entry></row>
- * <row><entry>kern=0</entry> <entry>0</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature off</entry></row>
- * <row><entry>kern=1</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row>
- * <row><entry>aalt=2</entry> <entry>2</entry> <entry>0</entry> <entry>∞</entry> <entry>Choose 2nd alternate</entry></row>
- * <row><entry>Setting index:</entry></row>
- * <row><entry>kern[]</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row>
- * <row><entry>kern[:]</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row>
- * <row><entry>kern[5:]</entry> <entry>1</entry> <entry>5</entry> <entry>∞</entry> <entry>Turn feature on, partial</entry></row>
- * <row><entry>kern[:5]</entry> <entry>1</entry> <entry>0</entry> <entry>5</entry> <entry>Turn feature on, partial</entry></row>
- * <row><entry>kern[3:5]</entry> <entry>1</entry> <entry>3</entry> <entry>5</entry> <entry>Turn feature on, range</entry></row>
- * <row><entry>kern[3]</entry> <entry>1</entry> <entry>3</entry> <entry>3+1</entry> <entry>Turn feature on, single char</entry></row>
- * <row><entry>Mixing it all:</entry></row>
- * <row><entry>aalt[3:5]=2</entry> <entry>2</entry> <entry>3</entry> <entry>5</entry> <entry>Turn 2nd alternate on for range</entry></row>
- * </tbody>
- * </tgroup>
- * </informaltable>
+ * TODO: document the syntax here.
*
* Return value:
- * `true` if @str is successfully parsed, `false` otherwise
+ * %true if @str is successfully parsed, %false otherwise.
*
* Since: 0.9.5
**/
@@ -951,7 +925,7 @@ hb_feature_from_string (const char *str, int len,
}
if (feature)
- hb_memset (feature, 0, sizeof (*feature));
+ memset (feature, 0, sizeof (*feature));
return false;
}
@@ -961,7 +935,7 @@ hb_feature_from_string (const char *str, int len,
* @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
+ * 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.
*
@@ -981,26 +955,26 @@ hb_feature_to_string (hb_feature_t *feature,
len += 4;
while (len && s[len - 1] == ' ')
len--;
- if (feature->start != HB_FEATURE_GLOBAL_START || feature->end != HB_FEATURE_GLOBAL_END)
+ if (feature->start != 0 || feature->end != (unsigned int) -1)
{
s[len++] = '[';
if (feature->start)
- len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", 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 != HB_FEATURE_GLOBAL_END)
- len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
+ 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 += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
}
assert (len < ARRAY_LENGTH (s));
- len = hb_min (len, size - 1);
- hb_memcpy (buf, s, len);
+ len = MIN (len, size - 1);
+ memcpy (buf, s, len);
buf[len] = '\0';
}
@@ -1010,11 +984,7 @@ static bool
parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
{
parse_char (pp, end, '='); /* Optional. */
- double v;
- if (unlikely (!hb_parse_double (pp, end, &v))) return false;
-
- variation->value = v;
- return true;
+ return parse_float (pp, end, &variation->value);
}
static bool
@@ -1028,21 +998,6 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation
/**
* hb_variation_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
- * @variation: (out): the #hb_variation_t to initialize with the parsed values
- *
- * Parses a string into a #hb_variation_t.
- *
- * The format for specifying variation settings follows. All valid CSS
- * font-variation-settings values other than 'normal' and 'inherited' are also
- * accepted, though, not documented below.
- *
- * The format is a tag, optionally followed by an equals sign, followed by a
- * number. For example `wght=500`, or `slnt=-7.5`.
- *
- * Return value:
- * `true` if @str is successfully parsed, `false` otherwise
*
* Since: 1.4.2
*/
@@ -1063,60 +1018,12 @@ hb_variation_from_string (const char *str, int len,
}
if (variation)
- hb_memset (variation, 0, sizeof (*variation));
+ memset (variation, 0, sizeof (*variation));
return false;
}
-#ifndef HB_NO_SETLOCALE
-
-static inline void free_static_C_locale ();
-
-static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<hb_locale_t>,
- hb_C_locale_lazy_loader_t>
-{
- static hb_locale_t create ()
- {
- hb_locale_t l = newlocale (LC_ALL_MASK, "C", NULL);
- if (!l)
- return l;
-
- hb_atexit (free_static_C_locale);
-
- return l;
- }
- static void destroy (hb_locale_t l)
- {
- freelocale (l);
- }
- static hb_locale_t get_null ()
- {
- return (hb_locale_t) 0;
- }
-} static_C_locale;
-
-static inline
-void free_static_C_locale ()
-{
- static_C_locale.free_instance ();
-}
-
-static hb_locale_t
-get_C_locale ()
-{
- return static_C_locale.get_unconst ();
-}
-
-#endif
-
/**
* hb_variation_to_string:
- * @variation: an #hb_variation_t to convert
- * @buf: (array length=size) (out caller-allocates): output string
- * @size: the allocated size of @buf
- *
- * Converts an #hb_variation_t into a `NULL`-terminated string in the format
- * understood by hb_variation_from_string(). The client in responsible for
- * allocating big enough size for @buf, 128 bytes is more than enough.
*
* Since: 1.4.2
*/
@@ -1133,88 +1040,10 @@ hb_variation_to_string (hb_variation_t *variation,
while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
-
- hb_locale_t oldlocale HB_UNUSED;
- oldlocale = hb_uselocale (get_C_locale ());
- len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
- (void) hb_uselocale (oldlocale);
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value));
assert (len < ARRAY_LENGTH (s));
- len = hb_min (len, size - 1);
- hb_memcpy (buf, s, len);
+ len = MIN (len, size - 1);
+ memcpy (buf, s, len);
buf[len] = '\0';
}
-
-/**
- * hb_color_get_alpha:
- * @color: an #hb_color_t we are interested in its channels.
- *
- * Fetches the alpha channel of the given @color.
- *
- * Return value: Alpha channel value
- *
- * Since: 2.1.0
- */
-uint8_t
-(hb_color_get_alpha) (hb_color_t color)
-{
- return hb_color_get_alpha (color);
-}
-
-/**
- * hb_color_get_red:
- * @color: an #hb_color_t we are interested in its channels.
- *
- * Fetches the red channel of the given @color.
- *
- * Return value: Red channel value
- *
- * Since: 2.1.0
- */
-uint8_t
-(hb_color_get_red) (hb_color_t color)
-{
- return hb_color_get_red (color);
-}
-
-/**
- * hb_color_get_green:
- * @color: an #hb_color_t we are interested in its channels.
- *
- * Fetches the green channel of the given @color.
- *
- * Return value: Green channel value
- *
- * Since: 2.1.0
- */
-uint8_t
-(hb_color_get_green) (hb_color_t color)
-{
- return hb_color_get_green (color);
-}
-
-/**
- * hb_color_get_blue:
- * @color: an #hb_color_t we are interested in its channels.
- *
- * Fetches the blue channel of the given @color.
- *
- * Return value: Blue channel value
- *
- * Since: 2.1.0
- */
-uint8_t
-(hb_color_get_blue) (hb_color_t color)
-{
- return hb_color_get_blue (color);
-}
-
-
-/* If there is no visibility control, then hb-static.cc will NOT
- * define anything. Instead, we get it to define one set in here
- * only, so only libharfbuzz.so defines them, not other libs. */
-#ifdef HB_NO_VISIBILITY
-#undef HB_NO_VISIBILITY
-#include "hb-static.cc"
-#define HB_NO_VISIBILITY 1
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
index a5da4e76a32..26200ce125b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -26,17 +26,13 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
#ifndef HB_COMMON_H
#define HB_COMMON_H
-#ifndef HB_EXTERN
-#define HB_EXTERN extern
-#endif
-
#ifndef HB_BEGIN_DECLS
# ifdef __cplusplus
# define HB_BEGIN_DECLS extern "C" {
@@ -53,72 +49,17 @@
# include <inttypes.h>
#elif defined (_AIX)
# include <sys/inttypes.h>
-#elif defined (_MSC_VER) && _MSC_VER < 1600
-/* VS 2010 (_MSC_VER 1600) has stdint.h */
-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;
-#elif defined (__KERNEL__)
-# include <linux/types.h>
#else
# include <stdint.h>
#endif
-#if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-#define HB_DEPRECATED __attribute__((__deprecated__))
-#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
-#define HB_DEPRECATED __declspec(deprecated)
-#else
-#define HB_DEPRECATED
-#endif
-
-#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
-#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
-#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
-#else
-#define HB_DEPRECATED_FOR(f) HB_DEPRECATED
-#endif
-
-
HB_BEGIN_DECLS
-/**
- * hb_bool_t:
- *
- * Data type for booleans.
- *
- **/
+
typedef int hb_bool_t;
-/**
- * hb_codepoint_t:
- *
- * Data type for holding Unicode codepoints. Also
- * used to hold glyph IDs.
- *
- **/
typedef uint32_t hb_codepoint_t;
-/**
- * hb_position_t:
- *
- * Data type for holding a single coordinate value.
- * Contour points and other multi-dimensional data are
- * stored as tuples of #hb_position_t's.
- *
- **/
typedef int32_t hb_position_t;
-/**
- * hb_mask_t:
- *
- * Data type for bitmasks.
- *
- **/
typedef uint32_t hb_mask_t;
typedef union _hb_var_int_t {
@@ -130,76 +71,16 @@ typedef union _hb_var_int_t {
int8_t i8[4];
} hb_var_int_t;
-typedef union _hb_var_num_t {
- float f;
- uint32_t u32;
- int32_t i32;
- uint16_t u16[2];
- int16_t i16[2];
- uint8_t u8[4];
- int8_t i8[4];
-} hb_var_num_t;
-
/* hb_tag_t */
-/**
- * hb_tag_t:
- *
- * Data type for tag identifiers. Tags are four
- * byte integers, each byte representing a character.
- *
- * Tags are used to identify tables, design-variation axes,
- * scripts, languages, font features, and baselines with
- * human-readable names.
- *
- **/
typedef uint32_t hb_tag_t;
-/**
- * HB_TAG:
- * @c1: 1st character of the tag
- * @c2: 2nd character of the tag
- * @c3: 3rd character of the tag
- * @c4: 4th character of the tag
- *
- * Constructs an #hb_tag_t from four character literals.
- *
- **/
-#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF)))
-
-/**
- * HB_UNTAG:
- * @tag: an #hb_tag_t
- *
- * Extracts four character literals from an #hb_tag_t.
- *
- * Since: 0.6.0
- *
- **/
-#define HB_UNTAG(tag) (uint8_t)(((tag)>>24)&0xFF), (uint8_t)(((tag)>>16)&0xFF), (uint8_t)(((tag)>>8)&0xFF), (uint8_t)((tag)&0xFF)
+#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
+#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
-/**
- * HB_TAG_NONE:
- *
- * Unset #hb_tag_t.
- */
#define HB_TAG_NONE HB_TAG(0,0,0,0)
-/**
- * HB_TAG_MAX:
- *
- * Maximum possible unsigned #hb_tag_t.
- *
- * Since: 0.9.26
- */
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
-/**
- * HB_TAG_MAX_SIGNED:
- *
- * Maximum possible signed #hb_tag_t.
- *
- * Since: 0.9.33
- */
#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
/* len=-1 means str is NUL-terminated. */
@@ -218,13 +99,6 @@ hb_tag_to_string (hb_tag_t tag, char *buf);
* @HB_DIRECTION_RTL: Text is set horizontally from right to left.
* @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
* @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
- *
- * The direction of a text segment or buffer.
- *
- * A segment can also be tested for horizontal or vertical
- * orientation (irrespective of specific direction) with
- * HB_DIRECTION_IS_HORIZONTAL() or HB_DIRECTION_IS_VERTICAL().
- *
*/
typedef enum {
HB_DIRECTION_INVALID = 0,
@@ -241,71 +115,17 @@ hb_direction_from_string (const char *str, int len);
HB_EXTERN const char *
hb_direction_to_string (hb_direction_t direction);
-/**
- * HB_DIRECTION_IS_VALID:
- * @dir: #hb_direction_t to test
- *
- * Tests whether a text direction is valid.
- *
- **/
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
/* Direction must be valid for the following */
-/**
- * HB_DIRECTION_IS_HORIZONTAL:
- * @dir: #hb_direction_t to test
- *
- * Tests whether a text direction is horizontal. Requires
- * that the direction be valid.
- *
- **/
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
-/**
- * HB_DIRECTION_IS_VERTICAL:
- * @dir: #hb_direction_t to test
- *
- * Tests whether a text direction is vertical. Requires
- * that the direction be valid.
- *
- **/
#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
-/**
- * HB_DIRECTION_IS_FORWARD:
- * @dir: #hb_direction_t to test
- *
- * Tests whether a text direction moves forward (from left to right, or from
- * top to bottom). Requires that the direction be valid.
- *
- **/
#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
-/**
- * HB_DIRECTION_IS_BACKWARD:
- * @dir: #hb_direction_t to test
- *
- * Tests whether a text direction moves backward (from right to left, or from
- * bottom to top). Requires that the direction be valid.
- *
- **/
#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
-/**
- * HB_DIRECTION_REVERSE:
- * @dir: #hb_direction_t to reverse
- *
- * Reverses a text direction. Requires that the direction
- * be valid.
- *
- **/
#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
/* hb_language_t */
-/**
- * hb_language_t:
- *
- * Data type for languages. Each #hb_language_t corresponds to a BCP 47
- * language tag.
- *
- */
typedef const struct hb_language_impl_t *hb_language_t;
HB_EXTERN hb_language_t
@@ -314,431 +134,198 @@ hb_language_from_string (const char *str, int len);
HB_EXTERN const char *
hb_language_to_string (hb_language_t language);
-/**
- * HB_LANGUAGE_INVALID:
- *
- * An unset #hb_language_t.
- *
- * Since: 0.6.0
- */
#define HB_LANGUAGE_INVALID ((hb_language_t) 0)
HB_EXTERN hb_language_t
hb_language_get_default (void);
-HB_EXTERN hb_bool_t
-hb_language_matches (hb_language_t language,
- hb_language_t specific);
-/**
- * hb_script_t:
- * @HB_SCRIPT_COMMON: `Zyyy`
- * @HB_SCRIPT_INHERITED: `Zinh`
- * @HB_SCRIPT_UNKNOWN: `Zzzz`
- * @HB_SCRIPT_ARABIC: `Arab`
- * @HB_SCRIPT_ARMENIAN: `Armn`
- * @HB_SCRIPT_BENGALI: `Beng`
- * @HB_SCRIPT_CYRILLIC: `Cyrl`
- * @HB_SCRIPT_DEVANAGARI: `Deva`
- * @HB_SCRIPT_GEORGIAN: `Geor`
- * @HB_SCRIPT_GREEK: `Grek`
- * @HB_SCRIPT_GUJARATI: `Gujr`
- * @HB_SCRIPT_GURMUKHI: `Guru`
- * @HB_SCRIPT_HANGUL: `Hang`
- * @HB_SCRIPT_HAN: `Hani`
- * @HB_SCRIPT_HEBREW: `Hebr`
- * @HB_SCRIPT_HIRAGANA: `Hira`
- * @HB_SCRIPT_KANNADA: `Knda`
- * @HB_SCRIPT_KATAKANA: `Kana`
- * @HB_SCRIPT_LAO: `Laoo`
- * @HB_SCRIPT_LATIN: `Latn`
- * @HB_SCRIPT_MALAYALAM: `Mlym`
- * @HB_SCRIPT_ORIYA: `Orya`
- * @HB_SCRIPT_TAMIL: `Taml`
- * @HB_SCRIPT_TELUGU: `Telu`
- * @HB_SCRIPT_THAI: `Thai`
- * @HB_SCRIPT_TIBETAN: `Tibt`
- * @HB_SCRIPT_BOPOMOFO: `Bopo`
- * @HB_SCRIPT_BRAILLE: `Brai`
- * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans`
- * @HB_SCRIPT_CHEROKEE: `Cher`
- * @HB_SCRIPT_ETHIOPIC: `Ethi`
- * @HB_SCRIPT_KHMER: `Khmr`
- * @HB_SCRIPT_MONGOLIAN: `Mong`
- * @HB_SCRIPT_MYANMAR: `Mymr`
- * @HB_SCRIPT_OGHAM: `Ogam`
- * @HB_SCRIPT_RUNIC: `Runr`
- * @HB_SCRIPT_SINHALA: `Sinh`
- * @HB_SCRIPT_SYRIAC: `Syrc`
- * @HB_SCRIPT_THAANA: `Thaa`
- * @HB_SCRIPT_YI: `Yiii`
- * @HB_SCRIPT_DESERET: `Dsrt`
- * @HB_SCRIPT_GOTHIC: `Goth`
- * @HB_SCRIPT_OLD_ITALIC: `Ital`
- * @HB_SCRIPT_BUHID: `Buhd`
- * @HB_SCRIPT_HANUNOO: `Hano`
- * @HB_SCRIPT_TAGALOG: `Tglg`
- * @HB_SCRIPT_TAGBANWA: `Tagb`
- * @HB_SCRIPT_CYPRIOT: `Cprt`
- * @HB_SCRIPT_LIMBU: `Limb`
- * @HB_SCRIPT_LINEAR_B: `Linb`
- * @HB_SCRIPT_OSMANYA: `Osma`
- * @HB_SCRIPT_SHAVIAN: `Shaw`
- * @HB_SCRIPT_TAI_LE: `Tale`
- * @HB_SCRIPT_UGARITIC: `Ugar`
- * @HB_SCRIPT_BUGINESE: `Bugi`
- * @HB_SCRIPT_COPTIC: `Copt`
- * @HB_SCRIPT_GLAGOLITIC: `Glag`
- * @HB_SCRIPT_KHAROSHTHI: `Khar`
- * @HB_SCRIPT_NEW_TAI_LUE: `Talu`
- * @HB_SCRIPT_OLD_PERSIAN: `Xpeo`
- * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo`
- * @HB_SCRIPT_TIFINAGH: `Tfng`
- * @HB_SCRIPT_BALINESE: `Bali`
- * @HB_SCRIPT_CUNEIFORM: `Xsux`
- * @HB_SCRIPT_NKO: `Nkoo`
- * @HB_SCRIPT_PHAGS_PA: `Phag`
- * @HB_SCRIPT_PHOENICIAN: `Phnx`
- * @HB_SCRIPT_CARIAN: `Cari`
- * @HB_SCRIPT_CHAM: `Cham`
- * @HB_SCRIPT_KAYAH_LI: `Kali`
- * @HB_SCRIPT_LEPCHA: `Lepc`
- * @HB_SCRIPT_LYCIAN: `Lyci`
- * @HB_SCRIPT_LYDIAN: `Lydi`
- * @HB_SCRIPT_OL_CHIKI: `Olck`
- * @HB_SCRIPT_REJANG: `Rjng`
- * @HB_SCRIPT_SAURASHTRA: `Saur`
- * @HB_SCRIPT_SUNDANESE: `Sund`
- * @HB_SCRIPT_VAI: `Vaii`
- * @HB_SCRIPT_AVESTAN: `Avst`
- * @HB_SCRIPT_BAMUM: `Bamu`
- * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp`
- * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi`
- * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli`
- * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti`
- * @HB_SCRIPT_JAVANESE: `Java`
- * @HB_SCRIPT_KAITHI: `Kthi`
- * @HB_SCRIPT_LISU: `Lisu`
- * @HB_SCRIPT_MEETEI_MAYEK: `Mtei`
- * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb`
- * @HB_SCRIPT_OLD_TURKIC: `Orkh`
- * @HB_SCRIPT_SAMARITAN: `Samr`
- * @HB_SCRIPT_TAI_THAM: `Lana`
- * @HB_SCRIPT_TAI_VIET: `Tavt`
- * @HB_SCRIPT_BATAK: `Batk`
- * @HB_SCRIPT_BRAHMI: `Brah`
- * @HB_SCRIPT_MANDAIC: `Mand`
- * @HB_SCRIPT_CHAKMA: `Cakm`
- * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc`
- * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero`
- * @HB_SCRIPT_MIAO: `Plrd`
- * @HB_SCRIPT_SHARADA: `Shrd`
- * @HB_SCRIPT_SORA_SOMPENG: `Sora`
- * @HB_SCRIPT_TAKRI: `Takr`
- * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30
- * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30
- * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30
- * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30
- * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30
- * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30
- * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30
- * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30
- * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30
- * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30
- * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30
- * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30
- * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30
- * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30
- * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30
- * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30
- * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30
- * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30
- * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30
- * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30
- * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30
- * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30
- * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30
- * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30
- * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30
- * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30
- * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30
- * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30
- * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30
- * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0
- * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0
- * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0
- * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0
- * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0
- * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0
- * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0
- * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0
- * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0
- * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0
- * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0
- * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0
- * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0
- * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0
- * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0
- * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0
- * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0
- * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0
- * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0
- * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0
- * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0
- * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7
- * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7
- * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7
- * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7
- * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0
- * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0
- * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0
- * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0
- * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0
- * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0
- * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0
- * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0
- * @HB_SCRIPT_INVALID: No script set
- *
- * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding
- * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/).
- *
- * See also the Script (sc) property of the Unicode Character Database.
- *
- **/
+/* hb_script_t */
-/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
+/* http://unicode.org/iso15924/ */
+/* http://goo.gl/x9ilM */
+/* Unicode Character Database property: Script (sc) */
typedef enum
{
- HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/
- HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/
- HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/
-
- HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/
- HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/
- HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/
- HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/
- HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/
- HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/
- HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/
- HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/
- HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/
- HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/
- HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/
- HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/
- HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/
- HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/
- HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/
- HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/
- HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/
- HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/
- HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/
- HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/
- HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/
- HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/
-
- HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/
-
- HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/
- HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/
- HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/
- HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/
- HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/
- HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/
- HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/
- HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/
- HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/
- HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/
- HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/
- HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/
- HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/
- HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/
-
- HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/
- HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/
- HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/
-
- HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/
- HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/
- HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/
- HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/
-
- HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/
- HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/
- HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/
- HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/
- HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/
- HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/
- HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/
-
- HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/
- HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/
- HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/
- HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/
- HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/
- HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/
- HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/
- HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/
-
- HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/
- HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/
- HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/
- HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/
- HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/
-
- HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/
- HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/
- HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/
- HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/
- HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/
- HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/
- HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/
- HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/
- HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/
- HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/
- HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/
-
- HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/
- HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/
- HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/
- HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/
- HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/
- HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/
- HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/
- HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/
- HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/
- HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/
- HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/
- HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/
- HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/
- HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/
- HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/
-
- HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/
- HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/
- HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/
-
- HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/
- HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/
- HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/
- HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/
- HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/
- HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/
- HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/
+ /*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'),
+ /*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'),
+ /*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'),
+
+ /*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'),
+ /*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'),
+ /*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'),
+ /*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'),
+ /*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'),
+ /*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'),
+ /*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'),
+ /*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'),
+ /*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'),
+ /*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'),
+ /*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'),
+ /*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'),
+ /*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'),
+ /*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'),
+ /*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'),
+ /*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'),
+ /*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'),
+ /*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'),
+ /*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'),
+ /*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'),
+ /*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'),
+ /*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'),
+
+ /*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
+
+ /*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'),
+ /*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'),
+ /*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'),
+ /*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'),
+ /*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'),
+ /*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'),
+ /*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'),
+ /*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'),
+ /*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'),
+ /*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'),
+ /*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'),
+ /*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'),
+ /*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'),
+ /*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'),
+
+ /*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'),
+ /*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'),
+ /*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'),
+
+ /*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'),
+ /*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'),
+ /*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'),
+ /*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'),
+
+ /*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'),
+ /*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'),
+ /*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'),
+ /*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'),
+ /*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'),
+ /*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'),
+ /*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'),
+
+ /*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'),
+ /*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'),
+ /*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'),
+ /*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'),
+ /*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'),
+ /*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'),
+ /*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'),
+ /*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'),
+
+ /*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'),
+ /*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'),
+ /*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'),
+ /*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'),
+ /*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'),
+
+ /*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'),
+ /*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'),
+ /*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'),
+ /*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'),
+ /*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'),
+ /*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'),
+ /*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'),
+ /*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'),
+ /*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'),
+ /*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'),
+ /*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'),
+
+ /*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'),
+ /*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'),
+ /*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'),
+ /*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'),
+ /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'),
+ /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'),
+ /*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'),
+ /*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'),
+ /*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'),
+ /*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'),
+ /*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'),
+ /*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'),
+ /*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'),
+ /*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'),
+ /*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'),
+
+ /*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'),
+ /*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'),
+ /*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'),
+
+ /*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'),
+ /*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'),
+ /*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'),
+ /*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'),
+ /*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'),
+ /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
+ /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
/*
* Since: 0.9.30
*/
- HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/
- HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/
- HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/
- HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/
- HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/
- HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/
- HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/
- HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/
- HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/
- HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/
- HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/
- HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/
- HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/
- HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/
- HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/
- HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/
- HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/
- HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/
- HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/
- HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/
- HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/
- HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/
- HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/
-
- HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/
- HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/
- HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/
- HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/
- HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/
- HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/
+ /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
+ /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
+ /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
+ /*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'),
+ /*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'),
+ /*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'),
+ /*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'),
+ /*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'),
+ /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
+ /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
+ /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
+ /*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'),
+ /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
+ /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
+ /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
+ /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
+ /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
+ /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
+ /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'),
+ /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
+ /*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'),
+ /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
+ /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
+
+ /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'),
+ /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'),
+ /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'),
+ /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'),
+ /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'),
+ /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'),
/*
* Since 1.3.0
*/
- HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/
- HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/
- HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/
- HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/
- HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/
- HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/
+ /*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'),
+ /*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'),
+ /*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'),
+ /*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'),
+ /*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
*/
- 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'), /*10.0*/
-
- /*
- * Since 1.8.0
- */
- HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/
- HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/
- HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/
- HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/
- HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/
- HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/
- HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/
-
- /*
- * Since 2.4.0
- */
- HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/
- HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/
- HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/
- HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/
-
- /*
- * Since 2.6.7
- */
- HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/
- HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/
- HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/
- HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/
-
- /*
- * Since 3.0.0
- */
- HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/
- HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/
- HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/
- HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/
- HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/
-
- /*
- * Since 3.4.0
- */
- HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'),
-
- /*
- * Since 5.2.0
- */
- HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/
- HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.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,
-
- /*< private >*/
+ HB_SCRIPT_INVALID = HB_TAG_NONE,
/* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
- * without risking undefined behavior. We have two, for historical reasons.
- * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed
- * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well.
- *
+ * without risking undefined behavior. Include both a signed and unsigned max,
+ * since technically enums are int, and indeed, hb_script_t ends up being signed.
* See this thread for technicalities:
*
- * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
+ * http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
*/
- _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/
+ _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/
_HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_script_t;
@@ -761,64 +348,16 @@ hb_script_get_horizontal_direction (hb_script_t script);
/* User data */
-/**
- * hb_user_data_key_t:
- *
- * Data structure for holding user-data keys.
- *
- **/
typedef struct hb_user_data_key_t {
/*< private >*/
char unused;
} hb_user_data_key_t;
-/**
- * hb_destroy_func_t:
- * @user_data: the data to be destroyed
- *
- * A virtual method for destroy user-data callbacks.
- *
- */
typedef void (*hb_destroy_func_t) (void *user_data);
/* Font features and variations. */
-/**
- * HB_FEATURE_GLOBAL_START:
- *
- * Special setting for #hb_feature_t.start to apply the feature from the start
- * of the buffer.
- *
- * Since: 2.0.0
- */
-#define HB_FEATURE_GLOBAL_START 0
-
-/**
- * HB_FEATURE_GLOBAL_END:
- *
- * Special setting for #hb_feature_t.end to apply the feature from to the end
- * of the buffer.
- *
- * Since: 2.0.0
- */
-#define HB_FEATURE_GLOBAL_END ((unsigned int) -1)
-
-/**
- * hb_feature_t:
- * @tag: The #hb_tag_t tag of the feature
- * @value: The value of the feature. 0 disables the feature, non-zero (usually
- * 1) enables the feature. For features implemented as lookup type 3 (like
- * 'salt') the @value is a one based index into the alternates.
- * @start: the cluster to start applying this feature setting (inclusive).
- * @end: the cluster to end applying this feature setting (exclusive).
- *
- * The #hb_feature_t is the structure that holds information about requested
- * feature application. The feature will be applied with the given value to all
- * glyphs which are in clusters between @start (inclusive) and @end (exclusive).
- * Setting start to #HB_FEATURE_GLOBAL_START and end to #HB_FEATURE_GLOBAL_END
- * specifies that the feature always applies to the entire buffer.
- */
typedef struct hb_feature_t {
hb_tag_t tag;
uint32_t value;
@@ -836,13 +375,7 @@ hb_feature_to_string (hb_feature_t *feature,
/**
* hb_variation_t:
- * @tag: The #hb_tag_t tag of the variation-axis name
- * @value: The value of the variation axis
*
- * Data type for holding variation data. Registered OpenType
- * variation-axis tags are listed in
- * [OpenType Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg).
- *
* Since: 1.4.2
*/
typedef struct hb_variation_t {
@@ -858,70 +391,6 @@ HB_EXTERN void
hb_variation_to_string (hb_variation_t *variation,
char *buf, unsigned int size);
-/**
- * hb_color_t:
- *
- * Data type for holding color values. Colors are eight bits per
- * channel RGB plus alpha transparency.
- *
- * Since: 2.1.0
- */
-typedef uint32_t hb_color_t;
-
-/**
- * HB_COLOR:
- * @b: blue channel value
- * @g: green channel value
- * @r: red channel value
- * @a: alpha channel value
- *
- * Constructs an #hb_color_t from four integers.
- *
- * Since: 2.1.0
- */
-#define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a)))
-
-HB_EXTERN uint8_t
-hb_color_get_alpha (hb_color_t color);
-#define hb_color_get_alpha(color) ((color) & 0xFF)
-
-HB_EXTERN uint8_t
-hb_color_get_red (hb_color_t color);
-#define hb_color_get_red(color) (((color) >> 8) & 0xFF)
-
-HB_EXTERN uint8_t
-hb_color_get_green (hb_color_t color);
-#define hb_color_get_green(color) (((color) >> 16) & 0xFF)
-
-HB_EXTERN uint8_t
-hb_color_get_blue (hb_color_t color);
-#define hb_color_get_blue(color) (((color) >> 24) & 0xFF)
-
-/**
- * hb_glyph_extents_t:
- * @x_bearing: Distance from the x-origin to the left extremum of the glyph.
- * @y_bearing: Distance from the top extremum of the glyph to the y-origin.
- * @width: Distance from the left extremum of the glyph to the right extremum.
- * @height: Distance from the top extremum of the glyph to the bottom extremum.
- *
- * Glyph extent values, measured in font units.
- *
- * Note that @height is negative, in coordinate systems that grow up.
- **/
-typedef struct hb_glyph_extents_t {
- hb_position_t x_bearing;
- hb_position_t y_bearing;
- hb_position_t width;
- hb_position_t height;
-} hb_glyph_extents_t;
-
-/**
- * hb_font_t:
- *
- * Data type for holding fonts.
- *
- */
-typedef struct hb_font_t hb_font_t;
HB_END_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-config.hh b/src/3rdparty/harfbuzz-ng/src/hb-config.hh
deleted file mode 100644
index 52adaad4384..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-config.hh
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright © 2019 Facebook, 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.
- *
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_CONFIG_HH
-#define HB_CONFIG_HH
-
-#if 0 /* Make test happy. */
-#include "hb.hh"
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef HB_EXPERIMENTAL_API
-#define HB_NO_BEYOND_64K
-#define HB_NO_CUBIC_GLYF
-#define HB_NO_VAR_COMPOSITES
-#endif
-
-#ifdef HB_TINY
-#define HB_LEAN
-#define HB_MINI
-#define HB_NO_MT
-#define HB_NO_UCD_UNASSIGNED
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-#ifndef __OPTIMIZE_SIZE__
-#define __OPTIMIZE_SIZE__
-#endif
-#endif
-
-#ifdef HB_LEAN
-#define HB_DISABLE_DEPRECATED
-#define HB_NDEBUG
-#define HB_NO_ATEXIT
-#define HB_NO_BUFFER_MESSAGE
-#define HB_NO_BUFFER_SERIALIZE
-#define HB_NO_BUFFER_VERIFY
-#define HB_NO_BITMAP
-#define HB_NO_CFF
-#define HB_NO_COLOR
-#define HB_NO_DRAW
-#define HB_NO_ERRNO
-#define HB_NO_FACE_COLLECT_UNICODES
-#define HB_NO_GETENV
-#define HB_NO_HINTING
-#define HB_NO_LANGUAGE_LONG
-#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
-#define HB_NO_LAYOUT_FEATURE_PARAMS
-#define HB_NO_LAYOUT_COLLECT_GLYPHS
-#define HB_NO_LAYOUT_RARELY_USED
-#define HB_NO_LAYOUT_UNUSED
-#define HB_NO_MATH
-#define HB_NO_META
-#define HB_NO_METRICS
-#define HB_NO_MMAP
-#define HB_NO_NAME
-#define HB_NO_OPEN
-#define HB_NO_OT_FONT_GLYPH_NAMES
-#define HB_NO_OT_SHAPE_FRACTIONS
-#define HB_NO_PAINT
-#define HB_NO_SETLOCALE
-#define HB_NO_STYLE
-#define HB_NO_SUBSET_LAYOUT
-#define HB_NO_VERTICAL
-#define HB_NO_VAR
-#endif
-
-#ifdef HB_MINI
-#define HB_NO_AAT
-#define HB_NO_LEGACY
-#define HB_NO_BORING_EXPANSION
-#endif
-
-#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
-#ifndef HB_CONFIG_OVERRIDE_H
-#define HB_CONFIG_OVERRIDE_H "config-override.h"
-#endif
-#include HB_CONFIG_OVERRIDE_H
-#endif
-
-/* Closure of options. */
-
-#ifdef HB_NO_BORING_EXPANSION
-#define HB_NO_BEYOND_64K
-#define HB_NO_AVAR2
-#endif
-
-#ifdef HB_DISABLE_DEPRECATED
-#define HB_IF_NOT_DEPRECATED(x)
-#else
-#define HB_IF_NOT_DEPRECATED(x) x
-#endif
-
-#ifdef HB_NO_SHAPER
-#define HB_NO_OT_SHAPE
-#define HB_NO_AAT_SHAPE
-#endif
-
-#ifdef HB_NO_AAT
-#define HB_NO_OT_NAME_LANGUAGE_AAT
-#define HB_NO_AAT_SHAPE
-#endif
-
-#ifdef HB_NO_BITMAP
-#define HB_NO_OT_FONT_BITMAP
-#endif
-
-#ifdef HB_NO_CFF
-#define HB_NO_OT_FONT_CFF
-#define HB_NO_SUBSET_CFF
-#endif
-
-#ifdef HB_NO_DRAW
-#define HB_NO_OUTLINE
-#endif
-
-#ifdef HB_NO_GETENV
-#define HB_NO_UNISCRIBE_BUG_COMPATIBLE
-#endif
-
-#ifdef HB_NO_LEGACY
-#define HB_NO_CMAP_LEGACY_SUBTABLES
-#define HB_NO_FALLBACK_SHAPE
-#define HB_NO_OT_KERN
-#define HB_NO_OT_LAYOUT_BLOCKLIST
-#define HB_NO_OT_SHAPE_FALLBACK
-#endif
-
-#ifdef HB_NO_NAME
-#define HB_NO_OT_NAME_LANGUAGE
-#endif
-
-#ifdef HB_NO_OT
-#define HB_NO_OT_FONT
-#define HB_NO_OT_LAYOUT
-#define HB_NO_OT_TAG
-#define HB_NO_OT_SHAPE
-#endif
-
-#ifdef HB_NO_OT_SHAPE
-#define HB_NO_AAT_SHAPE
-#endif
-
-#ifdef HB_NO_OT_SHAPE_FALLBACK
-#define HB_NO_OT_SHAPER_ARABIC_FALLBACK
-#define HB_NO_OT_SHAPER_HEBREW_FALLBACK
-#define HB_NO_OT_SHAPER_THAI_FALLBACK
-#define HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
-#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
-#endif
-
-#ifdef NDEBUG
-#ifndef HB_NDEBUG
-#define HB_NDEBUG
-#endif
-#endif
-
-#ifdef __OPTIMIZE_SIZE__
-#ifndef HB_OPTIMIZE_SIZE
-#define HB_OPTIMIZE_SIZE
-#endif
-#endif
-
-#ifdef HB_OPTIMIZE_SIZE
-#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
-#endif
-
-
-#endif /* HB_CONFIG_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
index e53dbaf2c7f..12f7d2515bd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
@@ -40,42 +40,10 @@
HB_BEGIN_DECLS
-/**
- * HB_CORETEXT_TAG_MORT:
- *
- * The #hb_tag_t tag for the `mort` (glyph metamorphosis) table,
- * which holds AAT features.
- *
- * For more information, see
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html
- *
- **/
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
-
-/**
- * HB_CORETEXT_TAG_MORX:
- *
- * The #hb_tag_t tag for the `morx` (extended glyph metamorphosis)
- * table, which holds AAT features.
- *
- * For more information, see
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
- *
- **/
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
-
-/**
- * HB_CORETEXT_TAG_KERX:
- *
- * The #hb_tag_t tag for the `kerx` (extended kerning) table, which
- * holds AAT kerning information.
- *
- * For more information, see
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
- *
- **/
#define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x')
-
+#define HB_CORETEXT_TAG_TRAK HB_TAG('t','r','a','k')
HB_EXTERN hb_face_t *
hb_coretext_face_create (CGFontRef cg_font);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.mm
index a87cb5cd028..185f73cd681 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.mm
@@ -26,24 +26,29 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#define HB_SHAPER coretext
-#ifdef HAVE_CORETEXT
-
-#include "hb-shaper-impl.hh"
+#include "hb-private.hh"
+#include "hb-debug.hh"
+#include "hb-shaper-impl-private.hh"
#include "hb-coretext.h"
-#include "hb-aat-layout.hh"
+#include <math.h>
+#include <Foundation/Foundation.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;
+};
-/**
- * SECTION:hb-coretext
- * @title: hb-coretext
- * @short_description: CoreText integration
- * @include: hb-coretext.h
- *
- * Functions for using HarfBuzz with the CoreText fonts.
- **/
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
@@ -56,7 +61,7 @@ release_table_data (void *user_data)
}
static hb_blob_t *
-_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+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);
@@ -66,10 +71,7 @@ _hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data
const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
const size_t length = CFDataGetLength (cf_data);
if (!data || !length)
- {
- CFRelease (cf_data);
return nullptr;
- }
return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
@@ -83,8 +85,13 @@ _hb_cg_font_release (void *data)
}
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
+HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
+ fabs (CTFontGetSize ((CTFontRef) data) - font->ptem) <= .5
+)
+
static CTFontDescriptorRef
-get_last_resort_font_desc ()
+get_last_resort_font_desc (void)
{
// TODO Handle allocation failures?
CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0);
@@ -110,7 +117,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, nullptr) == data);
+ hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
hb_blob_destroy ((hb_blob_t *) info);
}
@@ -125,6 +132,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);
@@ -139,6 +147,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;
}
@@ -155,10 +168,6 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
{
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080
-# define kCTFontUIFontSystem kCTFontSystemFontType
-# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType
-#endif
CTFontUIFontType font_type = kCTFontUIFontSystem;
if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
font_type = kCTFontUIFontEmphasizedSystem;
@@ -189,10 +198,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
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) {
-#pragma GCC diagnostic pop
CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
CFRelease (fontName);
@@ -200,18 +206,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
return ct_font;
}
- CFURLRef original_url = nullptr;
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- ATSFontRef atsFont;
- FSRef fsref;
- OSStatus status;
- atsFont = CTFontGetPlatformFont (ct_font, NULL);
- status = ATSFontGetFileReference (atsFont, &fsref);
- if (status == noErr)
- original_url = CFURLCreateFromFSRef (NULL, &fsref);
-#else
- original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute);
-#endif
+ CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute);
/* Create font copy with cascade list that has LastResort first; this speeds up CoreText
* font fallback which we don't need anyway. */
@@ -230,26 +225,18 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
* system locations that we cannot access from the sandboxed renderer
* process in Blink. This can be detected by the new file URL location
* that the newly found font points to. */
- CFURLRef new_url = nullptr;
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
- status = ATSFontGetFileReference (atsFont, &fsref);
- if (status == noErr)
- new_url = CFURLCreateFromFSRef (NULL, &fsref);
-#else
- new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
-#endif
+ CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
// Keep reconfigured font if URL cannot be retrieved (seems to be the case
// on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
if (!original_url || !new_url || CFEqual (original_url, new_url)) {
- CFRelease (ct_font);
- ct_font = new_ct_font;
+ CFRelease (ct_font);
+ ct_font = new_ct_font;
} else {
- CFRelease (new_ct_font);
- DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
+ CFRelease (new_ct_font);
+ DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
}
if (new_url)
- CFRelease (new_url);
+ CFRelease (new_url);
}
else
DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
@@ -260,7 +247,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
return ct_font;
}
-hb_coretext_face_data_t *
+hb_coretext_shaper_face_data_t *
_hb_coretext_shaper_face_data_create (hb_face_t *face)
{
CGFontRef cg_font = create_cg_font (face);
@@ -271,59 +258,40 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
return nullptr;
}
- return (hb_coretext_face_data_t *) cg_font;
+ return (hb_coretext_shaper_face_data_t *) cg_font;
}
void
-_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
+_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
{
CFRelease ((CGFontRef) data);
}
-/**
- * hb_coretext_face_create:
- * @cg_font: The CGFontRef to work upon
- *
- * Creates an #hb_face_t face object from the specified
- * CGFontRef.
- *
- * Return value: the new #hb_face_t face object
- *
- * Since: 0.9.10
- */
hb_face_t *
hb_coretext_face_create (CGFontRef cg_font)
{
- return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
+ return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
}
-/**
- * hb_coretext_face_get_cg_font:
- * @face: The #hb_face_t to work upon
- *
- * Fetches the CGFontRef associated with an #hb_face_t
- * face object
- *
- * Return value: the CGFontRef found
- *
+/*
* Since: 0.9.10
*/
CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face)
{
- return (CGFontRef) (const void *) face->data.coretext;
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
+ return (CGFontRef) HB_SHAPER_DATA_GET (face);
}
-hb_coretext_font_data_t *
+hb_coretext_shaper_font_data_t *
_hb_coretext_shaper_font_data_create (hb_font_t *font)
{
hb_face_t *face = font->face;
- const hb_coretext_face_data_t *face_data = face->data.coretext;
- if (unlikely (!face_data)) return nullptr;
- CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
- CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem);
+ CGFloat font_size = font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem;
CTFontRef ct_font = create_ct_font (cg_font, font_size);
if (unlikely (!ct_font))
@@ -332,103 +300,66 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
return nullptr;
}
- if (font->num_coords)
- {
- CFMutableDictionaryRef variations =
- CFDictionaryCreateMutable (kCFAllocatorDefault,
- font->num_coords,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- for (unsigned i = 0; i < font->num_coords; i++)
- {
- if (font->coords[i] == 0.) continue;
-
- hb_ot_var_axis_info_t info;
- unsigned int c = 1;
- hb_ot_var_get_axis_infos (font->face, i, &c, &info);
- float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value);
-
- CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag);
- CFNumberRef value_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &v);
- CFDictionarySetValue (variations, tag_number, value_number);
- CFRelease (tag_number);
- CFRelease (value_number);
- }
-
- CFDictionaryRef attributes =
- CFDictionaryCreate (kCFAllocatorDefault,
- (const void **) &kCTFontVariationAttribute,
- (const void **) &variations,
- 1,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- CTFontDescriptorRef varDesc = CTFontDescriptorCreateWithAttributes (attributes);
- CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0, nullptr, varDesc);
-
- CFRelease (ct_font);
- CFRelease (attributes);
- CFRelease (variations);
- ct_font = new_ct_font;
- }
-
- return (hb_coretext_font_data_t *) ct_font;
+ return (hb_coretext_shaper_font_data_t *) ct_font;
}
void
-_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
+_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
{
CFRelease ((CTFontRef) data);
}
-/**
- * hb_coretext_font_create:
- * @ct_font: The CTFontRef to work upon
- *
- * Creates an #hb_font_t font object from the specified
- * CTFontRef.
- *
- * Return value: the new #hb_font_t font object
- *
+/*
* Since: 1.7.2
- **/
+ */
hb_font_t *
hb_coretext_font_create (CTFontRef ct_font)
{
- CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr);
+ 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_immutable (font)))
+ if (unlikely (hb_object_is_inert (font)))
return font;
hb_font_set_ptem (font, CTFontGetSize (ct_font));
/* Let there be dragons here... */
- font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
+ HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);
return font;
}
-/**
- * hb_coretext_font_get_ct_font:
- * @font: #hb_font_t to work upon
- *
- * Fetches the CTFontRef associated with the specified
- * #hb_font_t font object.
- *
- * Return value: the CTFontRef found
- *
- * Since: 0.9.10
- */
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
- CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
- return ct_font ? (CTFontRef) ct_font : nullptr;
+ if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
+ return (CTFontRef) HB_SHAPER_DATA_GET (font);
+}
+
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_coretext_shaper_shape_plan_data_t {};
+
+hb_coretext_shaper_shape_plan_data_t *
+_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED,
+ const int *coords HB_UNUSED,
+ unsigned int num_coords HB_UNUSED)
+{
+ return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
+{
}
@@ -445,7 +376,7 @@ struct active_feature_t {
feature_record_t rec;
unsigned int order;
- HB_INTERNAL static int cmp (const void *pa, const void *pb) {
+ 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 :
@@ -453,8 +384,8 @@ struct active_feature_t {
a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
0;
}
- bool operator== (const active_feature_t& f) const {
- return cmp (this, &f) == 0;
+ bool operator== (const active_feature_t *f) {
+ return cmp (this, f) == 0;
}
};
@@ -463,7 +394,7 @@ struct feature_event_t {
bool start;
active_feature_t feature;
- HB_INTERNAL static int cmp (const void *pa, const void *pb) {
+ 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 :
@@ -479,23 +410,200 @@ struct range_record_t {
};
+/* The following enum members are added in OS X 10.8. */
+#define kAltHalfWidthTextSelector 6
+#define kAltProportionalTextSelector 5
+#define kAlternateHorizKanaOffSelector 1
+#define kAlternateHorizKanaOnSelector 0
+#define kAlternateKanaType 34
+#define kAlternateVertKanaOffSelector 3
+#define kAlternateVertKanaOnSelector 2
+#define kCaseSensitiveLayoutOffSelector 1
+#define kCaseSensitiveLayoutOnSelector 0
+#define kCaseSensitiveLayoutType 33
+#define kCaseSensitiveSpacingOffSelector 3
+#define kCaseSensitiveSpacingOnSelector 2
+#define kContextualAlternatesOffSelector 1
+#define kContextualAlternatesOnSelector 0
+#define kContextualAlternatesType 36
+#define kContextualLigaturesOffSelector 19
+#define kContextualLigaturesOnSelector 18
+#define kContextualSwashAlternatesOffSelector 5
+#define kContextualSwashAlternatesOnSelector 4
+#define kDefaultLowerCaseSelector 0
+#define kDefaultUpperCaseSelector 0
+#define kHistoricalLigaturesOffSelector 21
+#define kHistoricalLigaturesOnSelector 20
+#define kHojoCharactersSelector 12
+#define kJIS2004CharactersSelector 11
+#define kLowerCasePetiteCapsSelector 2
+#define kLowerCaseSmallCapsSelector 1
+#define kLowerCaseType 37
+#define kMathematicalGreekOffSelector 11
+#define kMathematicalGreekOnSelector 10
+#define kNLCCharactersSelector 13
+#define kQuarterWidthTextSelector 4
+#define kScientificInferiorsSelector 4
+#define kStylisticAltEightOffSelector 17
+#define kStylisticAltEightOnSelector 16
+#define kStylisticAltEighteenOffSelector 37
+#define kStylisticAltEighteenOnSelector 36
+#define kStylisticAltElevenOffSelector 23
+#define kStylisticAltElevenOnSelector 22
+#define kStylisticAltFifteenOffSelector 31
+#define kStylisticAltFifteenOnSelector 30
+#define kStylisticAltFiveOffSelector 11
+#define kStylisticAltFiveOnSelector 10
+#define kStylisticAltFourOffSelector 9
+#define kStylisticAltFourOnSelector 8
+#define kStylisticAltFourteenOffSelector 29
+#define kStylisticAltFourteenOnSelector 28
+#define kStylisticAltNineOffSelector 19
+#define kStylisticAltNineOnSelector 18
+#define kStylisticAltNineteenOffSelector 39
+#define kStylisticAltNineteenOnSelector 38
+#define kStylisticAltOneOffSelector 3
+#define kStylisticAltOneOnSelector 2
+#define kStylisticAltSevenOffSelector 15
+#define kStylisticAltSevenOnSelector 14
+#define kStylisticAltSeventeenOffSelector 35
+#define kStylisticAltSeventeenOnSelector 34
+#define kStylisticAltSixOffSelector 13
+#define kStylisticAltSixOnSelector 12
+#define kStylisticAltSixteenOffSelector 33
+#define kStylisticAltSixteenOnSelector 32
+#define kStylisticAltTenOffSelector 21
+#define kStylisticAltTenOnSelector 20
+#define kStylisticAltThirteenOffSelector 27
+#define kStylisticAltThirteenOnSelector 26
+#define kStylisticAltThreeOffSelector 7
+#define kStylisticAltThreeOnSelector 6
+#define kStylisticAltTwelveOffSelector 25
+#define kStylisticAltTwelveOnSelector 24
+#define kStylisticAltTwentyOffSelector 41
+#define kStylisticAltTwentyOnSelector 40
+#define kStylisticAltTwoOffSelector 5
+#define kStylisticAltTwoOnSelector 4
+#define kStylisticAlternativesType 35
+#define kSwashAlternatesOffSelector 3
+#define kSwashAlternatesOnSelector 2
+#define kThirdWidthTextSelector 3
+#define kTraditionalNamesCharactersSelector 14
+#define kUpperCasePetiteCapsSelector 2
+#define kUpperCaseSmallCapsSelector 1
+#define kUpperCaseType 38
+
+/* Table data courtesy of Apple. */
+static const struct feature_mapping_t {
+ FourCharCode otFeatureTag;
+ uint16_t aatFeatureType;
+ uint16_t selectorToEnable;
+ uint16_t selectorToDisable;
+} feature_mappings[] = {
+ { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector },
+ { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector },
+ { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector },
+ { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector },
+ { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector },
+ { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector },
+ { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector },
+ { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector },
+ { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 },
+ { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector },
+ { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 },
+ { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 },
+ { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector },
+ { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, },
+ { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector },
+ { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector },
+ { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 },
+ { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 },
+ { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector },
+ { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 },
+ { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 },
+ { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 },
+ { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 },
+ { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector },
+ { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 },
+ { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector },
+ { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 },
+ { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 },
+ { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector },
+ { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector },
+ { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 },
+ { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 },
+ { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 },
+ { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 },
+ { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector },
+ { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector },
+ { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector },
+ { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 },
+ { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector },
+ { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector },
+ { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector },
+ { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector },
+ { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector },
+ { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector },
+ { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector },
+ { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector },
+ { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector },
+ { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector },
+ { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector },
+ { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector },
+ { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector },
+ { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector },
+ { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector },
+ { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector },
+ { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector },
+ { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector },
+ { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector },
+ { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector },
+ { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector },
+ { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector },
+ { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector },
+ { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector },
+ { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 },
+ { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 },
+ { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 },
+ { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 },
+ { 'unic', kLetterCaseType, 14, 15 },
+ { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector },
+ { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 },
+ { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector },
+ { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector },
+ { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector },
+};
+
+static int
+_hb_feature_mapping_cmp (const void *key_, const void *entry_)
+{
+ unsigned int key = * (unsigned int *) key_;
+ const feature_mapping_t * entry = (const feature_mapping_t *) entry_;
+ return key < entry->otFeatureTag ? -1 :
+ key > entry->otFeatureTag ? 1 :
+ 0;
+}
+
hb_bool_t
_hb_coretext_shape (hb_shape_plan_t *shape_plan,
hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
{
hb_face_t *face = font->face;
- CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
- CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+ CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (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;
/* Attach marks to their bases, to match the 'ot' shaper.
- * Adapted from a very old version of hb-ot-shape:hb_form_clusters().
+ * Adapted from hb-ot-shape:hb_form_clusters().
* Note that this only makes us be closer to the 'ot' shaper,
* but by no means the same. For example, if there's
* B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
@@ -511,7 +619,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
buffer->merge_clusters (i - 1, i + 1);
}
- hb_vector_t<range_record_t> range_records;
+ hb_auto_array_t<feature_record_t> feature_records;
+ hb_auto_array_t<range_record_t> range_records;
/*
* Set up features.
@@ -520,32 +629,34 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (num_features)
{
/* Sort features by start/end events. */
- hb_vector_t<feature_event_t> feature_events;
+ hb_auto_array_t<feature_event_t> feature_events;
for (unsigned int i = 0; i < num_features; i++)
{
- active_feature_t feature;
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
- const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
+ const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag,
+ feature_mappings,
+ ARRAY_LENGTH (feature_mappings),
+ sizeof (feature_mappings[0]),
+ _hb_feature_mapping_cmp);
if (!mapping)
- continue;
+ continue;
+ active_feature_t feature;
feature.rec.feature = mapping->aatFeatureType;
feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
-#else
- feature.rec.feature = features[i].tag;
- feature.rec.setting = features[i].value;
-#endif
feature.order = i;
feature_event_t *event;
event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
event->index = features[i].start;
event->start = true;
event->feature = feature;
event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
event->index = features[i].end;
event->start = false;
event->feature = feature;
@@ -559,32 +670,35 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
feature.order = num_features + 1;
feature_event_t *event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
event->index = 0; /* This value does magic. */
event->start = false;
event->feature = feature;
}
/* Scan events and save features for each range. */
- hb_vector_t<active_feature_t> active_features;
+ hb_auto_array_t<active_feature_t> active_features;
unsigned int last_index = 0;
- for (unsigned int i = 0; i < feature_events.length; i++)
+ for (unsigned int i = 0; i < feature_events.len; i++)
{
feature_event_t *event = &feature_events[i];
if (event->index != last_index)
{
- /* Save a snapshot of active features and the range. */
+ /* Save a snapshot of active features and the range. */
range_record_t *range = range_records.push ();
+ if (unlikely (!range))
+ goto fail_features;
- if (active_features.length)
+ if (active_features.len)
{
CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
/* TODO sort and resolve conflicting features? */
/* active_features.qsort (); */
- for (unsigned int j = 0; j < active_features.length; j++)
+ for (unsigned int j = 0; j < active_features.len; j++)
{
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
CFStringRef keys[] = {
kCTFontFeatureTypeIdentifierKey,
kCTFontFeatureSelectorIdentifierKey
@@ -593,17 +707,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
};
-#else
- char tag[5] = {HB_UNTAG (active_features[j].rec.feature)};
- CFTypeRef keys[] = {
- kCTFontOpenTypeFeatureTag,
- kCTFontOpenTypeFeatureValue
- };
- CFTypeRef values[] = {
- CFStringCreateWithCString (kCFAllocatorDefault, tag, kCFStringEncodingASCII),
- CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
- };
-#endif
static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), "");
CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
(const void **) keys,
@@ -644,23 +747,30 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
last_index = event->index;
}
- if (event->start)
- {
- active_features.push (event->feature);
+ if (event->start) {
+ active_feature_t *feature = active_features.push ();
+ if (unlikely (!feature))
+ goto fail_features;
+ *feature = event->feature;
} else {
- active_feature_t *feature = active_features.lsearch (event->feature);
+ active_feature_t *feature = active_features.find (&event->feature);
if (feature)
- active_features.remove_ordered (feature - active_features.arrayZ);
+ active_features.remove (feature - active_features.array);
}
}
}
+ else
+ {
+ fail_features:
+ num_features = 0;
+ }
unsigned int scratch_size;
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
Type *name = (Type *) scratch; \
- do { \
+ { \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
if (unlikely (_consumed > scratch_size)) \
{ \
@@ -669,9 +779,9 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} \
scratch += _consumed; \
scratch_size -= _consumed; \
- } while (0)
+ }
- ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, ((void)nullptr) /*nothing*/);
+ ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
unsigned int chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++) {
hb_codepoint_t c = buffer->info[i].codepoint;
@@ -685,7 +795,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
}
}
- ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, ((void)nullptr) /*nothing*/);
+ ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/);
chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++)
{
@@ -701,13 +811,13 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
ret = false; \
goto fail; \
- } HB_STMT_END
+ } HB_STMT_END;
bool ret = true;
CFStringRef string_ref = nullptr;
CTLineRef line = nullptr;
- if (false)
+ if (0)
{
resize_and_retry:
DEBUG_MSG (CORETEXT, buffer, "Buffer resize");
@@ -763,18 +873,15 @@ resize_and_retry:
/* What's the iOS equivalent of this check?
* The symbols was introduced in iOS 7.0.
* At any rate, our fallback is safe and works fine. */
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
# define kCTLanguageAttributeName CFSTR ("NSLanguage")
#endif
- CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
+ CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
hb_language_to_string (buffer->props.language),
kCFStringEncodingUTF8,
kCFAllocatorNull);
if (unlikely (!lang))
- {
- CFRelease (attr_string);
FAIL ("CFStringCreateWithCStringNoCopy failed");
- }
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
kCTLanguageAttributeName, lang);
CFRelease (lang);
@@ -782,7 +889,7 @@ resize_and_retry:
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
kCTFontAttributeName, ct_font);
- if (num_features && range_records.length)
+ if (num_features && range_records.len)
{
unsigned int start = 0;
range_record_t *last_range = &range_records[0];
@@ -823,7 +930,7 @@ resize_and_retry:
feature.start < chars_len && feature.start < feature.end)
{
CFRange feature_range = CFRangeMake (feature.start,
- hb_min (feature.end, chars_len) - feature.start);
+ MIN (feature.end, chars_len) - feature.start);
if (feature.value)
CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
else
@@ -835,9 +942,6 @@ resize_and_retry:
int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
-#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
- extern const CFStringRef kCTTypesetterOptionForcedEmbeddingLevel;
-#endif
CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault,
(const void **) &kCTTypesetterOptionForcedEmbeddingLevel,
(const void **) &level_number,
@@ -846,10 +950,7 @@ resize_and_retry:
&kCFTypeDictionaryValueCallBacks);
CFRelease (level_number);
if (unlikely (!options))
- {
- CFRelease (attr_string);
- FAIL ("CFDictionaryCreate failed");
- }
+ FAIL ("CFDictionaryCreate failed");
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
CFRelease (options);
@@ -868,12 +969,12 @@ resize_and_retry:
DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
buffer->len = 0;
- uint32_t status_or = 0;
- CGFloat advances_so_far = 0;
+ uint32_t status_and = ~0, status_or = 0;
+ double advances_so_far = 0;
/* For right-to-left runs, CoreText returns the glyphs positioned such that
* any trailing whitespace is to the left of (0,0). Adjust coordinate system
* to fix for that. Test with any RTL string with trailing spaces.
- * https://crbug.com/469028
+ * https://code.google.com/p/chromium/issues/detail?id=469028
*/
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
{
@@ -889,11 +990,12 @@ resize_and_retry:
CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
CTRunStatus run_status = CTRunGetStatus (run);
status_or |= run_status;
+ status_and &= run_status;
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
- CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
+ 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", (double) run_advance);
+ DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
/* CoreText does automatic font fallback (AKA "cascading") for characters
* not supported by the requested font, and provides no way to turn it off,
@@ -925,12 +1027,12 @@ 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: https://github.com/harfbuzz/harfbuzz/pull/36
+ * See: http://github.com/harfbuzz/harfbuzz/pull/36
*
* Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
*/
bool matched = false;
- for (unsigned int i = 0; i < range_records.length; i++)
+ for (unsigned int i = 0; i < range_records.len; i++)
if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
{
matched = true;
@@ -938,7 +1040,7 @@ resize_and_retry:
}
if (!matched)
{
- CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr);
+ CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
if (run_cg_font)
{
matched = CFEqual (run_cg_font, cg_font);
@@ -958,7 +1060,7 @@ resize_and_retry:
if (!matched)
{
CFRange range = CTRunGetStringRange (run);
- DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
+ DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
range.location, range.location + range.length);
if (!buffer->ensure_inplace (buffer->len + range.length))
goto resize_and_retry;
@@ -986,7 +1088,7 @@ resize_and_retry:
continue;
}
if (buffer->unicode->is_default_ignorable (ch))
- continue;
+ continue;
info->codepoint = notdef;
info->cluster = log_clusters[j];
@@ -1028,10 +1130,10 @@ resize_and_retry:
#define SCRATCH_RESTORE() \
scratch_size = scratch_size_saved; \
- scratch = scratch_saved
+ scratch = scratch_saved;
{ /* Setup glyphs */
- SCRATCH_SAVE();
+ SCRATCH_SAVE();
const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
if (!glyphs) {
ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
@@ -1054,12 +1156,12 @@ resize_and_retry:
SCRATCH_RESTORE();
}
{
- /* Setup positions.
+ /* Setup positions.
* Note that CoreText does not return advances for glyphs. As such,
* for all but last glyph, we use the delta position to next glyph as
* 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();
+ SCRATCH_SAVE();
const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
if (!positions) {
ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
@@ -1069,34 +1171,32 @@ resize_and_retry:
hb_glyph_info_t *info = run_info;
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
{
- hb_position_t x_offset = round ((positions[0].x - advances_so_far) * x_mult);
+ hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
for (unsigned int j = 0; j < num_glyphs; j++)
{
- CGFloat advance;
+ double advance;
if (likely (j + 1 < num_glyphs))
advance = positions[j + 1].x - positions[j].x;
else /* last glyph */
advance = run_advance - (positions[j].x - positions[0].x);
- /* int cast necessary to pass through negative values. */
- info->mask = (int) round (advance * x_mult);
+ info->mask = advance * x_mult;
info->var1.i32 = x_offset;
- info->var2.i32 = round (positions[j].y * y_mult);
+ info->var2.i32 = positions[j].y * y_mult;
info++;
}
}
else
{
- hb_position_t y_offset = round ((positions[0].y - advances_so_far) * y_mult);
+ hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
for (unsigned int j = 0; j < num_glyphs; j++)
{
- CGFloat advance;
+ double advance;
if (likely (j + 1 < num_glyphs))
advance = positions[j + 1].y - positions[j].y;
else /* last glyph */
advance = run_advance - (positions[j].y - positions[0].y);
- /* int cast necessary to pass through negative values. */
- info->mask = (int) round (advance * y_mult);
- info->var1.i32 = round (positions[j].x * x_mult);
+ info->mask = advance * y_mult;
+ info->var1.i32 = positions[j].x * x_mult;
info->var2.i32 = y_offset;
info++;
}
@@ -1112,6 +1212,21 @@ resize_and_retry:
buffer->len += num_glyphs;
}
+ /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
+ * or if it does, it doesn't resepct it. So we get runs with wrong
+ * directions. As such, disable the assert... It wouldn't crash, but
+ * cursoring will be off...
+ *
+ * http://crbug.com/419769
+ */
+ if (0)
+ {
+ /* Make sure all runs had the expected direction. */
+ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+ assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
+ assert (bool (status_or & kCTRunStatusRightToLeft) == backward);
+ }
+
buffer->clear_positions ();
unsigned int count = buffer->len;
@@ -1124,7 +1239,9 @@ resize_and_retry:
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
- info++; pos++;
+ info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+
+ info++, pos++;
}
else
for (unsigned int i = 0; i < count; i++)
@@ -1133,7 +1250,9 @@ resize_and_retry:
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
- info++; pos++;
+ info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+
+ info++, pos++;
}
/* Fix up clusters so that we never return out-of-order indices;
@@ -1146,8 +1265,7 @@ resize_and_retry:
* This does *not* mean we'll form the same clusters as Uniscribe
* or the native OT backend, only that the cluster indices will be
* monotonic in the output buffer. */
- if (count > 1 && (status_or & kCTRunStatusNonMonotonic) &&
- buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+ if (count > 1 && (status_or & kCTRunStatusNonMonotonic))
{
hb_glyph_info_t *info = buffer->info;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
@@ -1155,7 +1273,7 @@ resize_and_retry:
unsigned int cluster = info[count - 1].cluster;
for (unsigned int i = count - 1; i > 0; i--)
{
- cluster = hb_min (cluster, info[i - 1].cluster);
+ cluster = MIN (cluster, info[i - 1].cluster);
info[i - 1].cluster = cluster;
}
}
@@ -1164,19 +1282,14 @@ resize_and_retry:
unsigned int cluster = info[0].cluster;
for (unsigned int i = 1; i < count; i++)
{
- cluster = hb_min (cluster, info[i].cluster);
+ cluster = MIN (cluster, info[i].cluster);
info[i].cluster = cluster;
}
}
}
}
- /* TODO: Sometimes the above positioning code generates negative
- * advance values. Fix them up. Example, with NotoNastaliqUrdu
- * font and sequence ابهد. */
-
- buffer->clear_glyph_flags ();
- buffer->unsafe_to_break ();
+ buffer->unsafe_to_break_all ();
#undef FAIL
@@ -1186,7 +1299,7 @@ fail:
if (line)
CFRelease (line);
- for (unsigned int i = 0; i < range_records.length; i++)
+ for (unsigned int i = 0; i < range_records.len; i++)
if (range_records[i].font)
CFRelease (range_records[i].font);
@@ -1194,4 +1307,108 @@ fail:
}
+/*
+ * AAT shaper
+ */
+
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
+
+/*
+ * shaper face data
+ */
+
+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)
+{
+ static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX, HB_CORETEXT_TAG_TRAK};
+
+ // Disable macOS 11 / iOS 14 specific hotfix for Qt on older versions, since it caused a
+ // regression. (Note: This code should not been upstreamed and is only applicable to Qt 5.15.x).
+ NSInteger majorVersion = NSProcessInfo.processInfo.operatingSystemVersion.majorVersion;
+ NSInteger hotfixMinimumVersion;
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ hotfixMinimumVersion = 14;
+#else
+ hotfixMinimumVersion = 11;
#endif
+
+ unsigned int arrayLength = ARRAY_LENGTH (tags);
+ if (majorVersion < hotfixMinimumVersion)
+ arrayLength--;
+
+ for (unsigned int i = 0; i < arrayLength; i++)
+ {
+ hb_blob_t *blob = face->reference_table (tags[i]);
+ if (hb_blob_get_length (blob))
+ {
+ 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);
+ }
+
+ return nullptr;
+}
+
+void
+_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+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 : nullptr;
+}
+
+void
+_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_coretext_aat_shaper_shape_plan_data_t {};
+
+hb_coretext_aat_shaper_shape_plan_data_t *
+_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED,
+ const int *coords HB_UNUSED,
+ unsigned int num_coords HB_UNUSED)
+{
+ return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+hb_bool_t
+_hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh b/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh
deleted file mode 100644
index 531ef1b7c83..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-cplusplus.hh
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_CPLUSPLUS_HH
-#define HB_CPLUSPLUS_HH
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-HB_END_DECLS
-
-#ifdef __cplusplus
-
-#include <functional>
-#include <utility>
-
-#if 0
-#if !(__cplusplus >= 201103L)
-#error "HarfBuzz C++ helpers require C++11"
-#endif
-#endif
-
-namespace hb {
-
-
-template <typename T>
-struct vtable;
-
-template <typename T>
-struct shared_ptr
-{
- using element_type = T;
-
- using v = vtable<T>;
-
- explicit shared_ptr (T *p = nullptr) : p (p) {}
- shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
- shared_ptr (shared_ptr &&o) : p (o.p) { o.p = nullptr; }
- shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
- shared_ptr& operator = (shared_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
- ~shared_ptr () { v::destroy (p); p = nullptr; }
-
- T* get() const { return p; }
-
- void swap (shared_ptr &o) { std::swap (p, o.p); }
- friend void swap (shared_ptr &a, shared_ptr &b) { std::swap (a.p, b.p); }
-
- operator T * () const { return p; }
- T& operator * () const { return *get (); }
- T* operator -> () const { return get (); }
- operator bool () const { return p; }
- bool operator == (const shared_ptr &o) const { return p == o.p; }
- bool operator != (const shared_ptr &o) const { return p != o.p; }
-
- static T* get_empty() { return v::get_empty (); }
- T* reference() { return v::reference (p); }
- void destroy() { v::destroy (p); }
- void set_user_data (hb_user_data_key_t *key,
- void *value,
- hb_destroy_func_t destroy,
- hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); }
- void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }
-
- private:
- T *p;
-};
-
-template<typename T> struct is_shared_ptr : std::false_type {};
-template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};
-
-template <typename T>
-struct unique_ptr
-{
- using element_type = T;
-
- using v = vtable<T>;
-
- explicit unique_ptr (T *p = nullptr) : p (p) {}
- unique_ptr (const unique_ptr &o) = delete;
- unique_ptr (unique_ptr &&o) : p (o.p) { o.p = nullptr; }
- unique_ptr& operator = (const unique_ptr &o) = delete;
- unique_ptr& operator = (unique_ptr &&o) { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
- ~unique_ptr () { v::destroy (p); p = nullptr; }
-
- T* get() const { return p; }
- T* release () { T* v = p; p = nullptr; return v; }
-
- void swap (unique_ptr &o) { std::swap (p, o.p); }
- friend void swap (unique_ptr &a, unique_ptr &b) { std::swap (a.p, b.p); }
-
- operator T * () const { return p; }
- T& operator * () const { return *get (); }
- T* operator -> () const { return get (); }
- operator bool () { return p; }
-
- private:
- T *p;
-};
-
-template<typename T> struct is_unique_ptr : std::false_type {};
-template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};
-
-template <typename T,
- T * (*_get_empty) (void),
- T * (*_reference) (T *),
- void (*_destroy) (T *),
- hb_bool_t (*_set_user_data) (T *,
- hb_user_data_key_t *,
- void *,
- hb_destroy_func_t,
- hb_bool_t),
- void * (*_get_user_data) (const T *,
- hb_user_data_key_t *)>
-struct vtable_t
-{
- static constexpr auto get_empty = _get_empty;
- static constexpr auto reference = _reference;
- static constexpr auto destroy = _destroy;
- static constexpr auto set_user_data = _set_user_data;
- static constexpr auto get_user_data = _get_user_data;
-};
-
-#define HB_DEFINE_VTABLE(name) \
- template<> \
- struct vtable<hb_##name##_t> \
- : vtable_t<hb_##name##_t, \
- &hb_##name##_get_empty, \
- &hb_##name##_reference, \
- &hb_##name##_destroy, \
- &hb_##name##_set_user_data, \
- &hb_##name##_get_user_data> {}
-
-HB_DEFINE_VTABLE (buffer);
-HB_DEFINE_VTABLE (blob);
-HB_DEFINE_VTABLE (face);
-HB_DEFINE_VTABLE (font);
-HB_DEFINE_VTABLE (font_funcs);
-HB_DEFINE_VTABLE (map);
-HB_DEFINE_VTABLE (set);
-HB_DEFINE_VTABLE (shape_plan);
-HB_DEFINE_VTABLE (unicode_funcs);
-HB_DEFINE_VTABLE (draw_funcs);
-HB_DEFINE_VTABLE (paint_funcs);
-
-#undef HB_DEFINE_VTABLE
-
-
-#ifdef HB_SUBSET_H
-
-#define HB_DEFINE_VTABLE(name) \
- template<> \
- struct vtable<hb_##name##_t> \
- : vtable_t<hb_##name##_t, \
- nullptr, \
- &hb_##name##_reference, \
- &hb_##name##_destroy, \
- &hb_##name##_set_user_data, \
- &hb_##name##_get_user_data> {}
-
-
-HB_DEFINE_VTABLE (subset_input);
-HB_DEFINE_VTABLE (subset_plan);
-
-#undef HB_DEFINE_VTABLE
-
-#endif
-
-
-} // namespace hb
-
-/* Workaround for GCC < 7, see:
- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
- * https://stackoverflow.com/a/25594741 */
-namespace std {
-
-
-template<typename T>
-struct hash<hb::shared_ptr<T>>
-{
- std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
- {
- std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
- return h;
- }
-};
-
-template<typename T>
-struct hash<hb::unique_ptr<T>>
-{
- std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
- {
- std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
- return h;
- }
-};
-
-
-} // namespace std
-
-#endif /* __cplusplus */
-
-#endif /* HB_CPLUSPLUS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
index 0ac4515fa85..6c425f7b9dd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
@@ -27,62 +27,13 @@
#ifndef HB_DEBUG_HH
#define HB_DEBUG_HH
-#include "hb.hh"
-#include "hb-atomic.hh"
-#include "hb-algs.hh"
+#include "hb-private.hh"
#ifndef HB_DEBUG
#define HB_DEBUG 0
#endif
-
-/*
- * Global runtime options.
- */
-
-struct hb_options_t
-{
- bool unused : 1; /* In-case sign bit is here. */
- bool initialized : 1;
- bool uniscribe_bug_compatible : 1;
-};
-
-union hb_options_union_t {
- int i;
- hb_options_t opts;
-};
-static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), "");
-
-HB_INTERNAL void
-_hb_options_init ();
-
-extern HB_INTERNAL hb_atomic_int_t _hb_options;
-
-static inline hb_options_t
-hb_options ()
-{
-#ifdef HB_NO_GETENV
- return hb_options_t ();
-#endif
- /* Make a local copy, so we can access bitfield threadsafely. */
- hb_options_union_t u;
- u.i = _hb_options;
-
- if (unlikely (!u.i))
- {
- _hb_options_init ();
- u.i = _hb_options;
- }
-
- return u.opts;
-}
-
-
-/*
- * Debug output (needs enabling at compile time.)
- */
-
static inline bool
_hb_debug (unsigned int level,
unsigned int max_level)
@@ -113,7 +64,7 @@ _hb_print_func (const char *func)
const char *paren = strchr (func, '(');
if (paren)
func_len = paren - func;
- fprintf (stderr, "%.*s", (int) func_len, func);
+ fprintf (stderr, "%.*s", func_len, func);
}
}
@@ -142,9 +93,9 @@ _hb_debug_msg_va (const char *what,
fprintf (stderr, "%-10s", what ? what : "");
if (obj)
- fprintf (stderr, "(%*p) ", (int) (2 * sizeof (void *)), obj);
+ fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
else
- fprintf (stderr, " %*s ", (int) (2 * sizeof (void *)), "");
+ fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
if (indented) {
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
@@ -160,7 +111,7 @@ _hb_debug_msg_va (const char *what,
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
fprintf (stderr, "%2u %s" VRBAR "%s",
level,
- bars + sizeof (bars) - 1 - hb_min ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * 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);
@@ -175,7 +126,7 @@ _hb_debug_msg_va (const char *what,
fprintf (stderr, "\n");
}
-template <> inline void HB_PRINTF_FUNC(7, 0)
+template <> inline void
_hb_debug_msg_va<0> (const char *what HB_UNUSED,
const void *obj HB_UNUSED,
const char *func HB_UNUSED,
@@ -194,7 +145,7 @@ _hb_debug_msg (const char *what,
int level_dir,
const char *message,
...) HB_PRINTF_FUNC(7, 8);
-template <int max_level> static inline void HB_PRINTF_FUNC(7, 8)
+template <int max_level> static inline void
_hb_debug_msg (const char *what,
const void *obj,
const char *func,
@@ -218,7 +169,7 @@ _hb_debug_msg<0> (const char *what HB_UNUSED,
int level_dir HB_UNUSED,
const char *message HB_UNUSED,
...) HB_PRINTF_FUNC(7, 8);
-template <> inline void 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,
@@ -229,7 +180,7 @@ _hb_debug_msg<0> (const char *what 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(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__)
@@ -248,8 +199,8 @@ struct hb_printer_t<bool> {
};
template <>
-struct hb_printer_t<hb_empty_t> {
- const char *print (hb_empty_t) { return ""; }
+struct hb_printer_t<hb_void_t> {
+ const char *print (hb_void_t) { return ""; }
};
@@ -265,7 +216,7 @@ static inline void _hb_warn_no_return (bool returned)
}
}
template <>
-/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
+/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
{}
template <int max_level, typename ret_t>
@@ -286,7 +237,7 @@ struct hb_auto_trace_t
_hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
va_end (ap);
}
- ~hb_auto_trace_t ()
+ inline ~hb_auto_trace_t (void)
{
_hb_warn_no_return<ret_t> (returned);
if (!returned) {
@@ -295,23 +246,20 @@ struct hb_auto_trace_t
if (plevel) --*plevel;
}
- template <typename T>
- T ret (T&& v,
- const char *func = "",
- unsigned int line = 0)
+ 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 std::forward<T> (v);
+ return v;
}
- _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
- "return %s (line %u)",
- hb_printer_t<hb_decay<decltype (v)>>().print (v), line);
+ _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 std::forward<T> (v);
+ return v;
}
private:
@@ -330,23 +278,17 @@ struct hb_auto_trace_t<0, ret_t>
const char *message,
...) HB_PRINTF_FUNC(6, 7) {}
- template <typename T>
- T ret (T&& v,
- const char *func HB_UNUSED = nullptr,
- unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
+ 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 {
- template <typename T>
- T ret (T&& v,
- const char *func HB_UNUSED = nullptr,
- unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
};
-#define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__)
+#define return_trace(RET) return trace.ret (RET, __LINE__)
/*
@@ -373,8 +315,8 @@ struct hb_no_trace_t {
#define HB_DEBUG_FT (HB_DEBUG+0)
#endif
-#ifndef HB_DEBUG_JUSTIFY
-#define HB_DEBUG_JUSTIFY (HB_DEBUG+0)
+#ifndef HB_DEBUG_GET_COVERAGE
+#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
#endif
#ifndef HB_DEBUG_OBJECT
@@ -400,12 +342,36 @@ struct hb_no_trace_t {
#define TRACE_APPLY(this) \
hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "idx %u gid %u lookup %d", \
+ "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
@@ -413,7 +379,7 @@ struct hb_no_trace_t {
#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
@@ -425,48 +391,41 @@ struct hb_no_trace_t {
#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_SUBSET
-#define HB_DEBUG_SUBSET (HB_DEBUG+0)
+#ifndef HB_DEBUG_WOULD_APPLY
+#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
#endif
-#if HB_DEBUG_SUBSET
-#define TRACE_SUBSET(this) \
- hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- " ")
+#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_SUBSET(this) hb_no_trace_t<bool> trace
-#endif
-
-#ifndef HB_DEBUG_SUBSET_REPACK
-#define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0)
+#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_SUBSET + \
+ 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 %u", (unsigned) format)
+ "format %d", (int) format);
#else
#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
#endif
-#ifndef HB_BUFFER_MESSAGE_MORE
-#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1)
-#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 b032a941b28..eac7efb42f1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -36,228 +36,30 @@
#include "hb-font.h"
#include "hb-set.h"
-
-/**
- * SECTION:hb-deprecated
- * @title: hb-deprecated
- * @short_description: Deprecated API
- * @include: hb.h
- *
- * These API have been deprecated in favor of newer API, or because they
- * were deemed unnecessary.
- **/
-
-
HB_BEGIN_DECLS
#ifndef HB_DISABLE_DEPRECATED
-
-/**
- * HB_SCRIPT_CANADIAN_ABORIGINAL:
- *
- * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead:
- *
- * Deprecated: 0.9.20
- */
#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS
-/**
- * HB_BUFFER_FLAGS_DEFAULT:
- *
- * Use #HB_BUFFER_FLAG_DEFAULT instead.
- *
- * Deprecated: 0.9.20
- */
#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT
-/**
- * HB_BUFFER_SERIALIZE_FLAGS_DEFAULT:
- *
- * Use #HB_BUFFER_SERIALIZE_FLAG_DEFAULT instead.
- *
- * Deprecated: 0.9.20
- */
#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT
-/**
- * hb_font_get_glyph_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @unicode: The Unicode code point to query
- * @variation_selector: The variation-selector code point to query
- * @glyph: (out): The glyph ID retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the glyph ID for a specified Unicode code point
- * font, with an optional variation selector.
- *
- * Return value: `true` if data found, `false` otherwise
- * Deprecated: 1.2.3
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data);
-HB_DEPRECATED_FOR (hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func)
HB_EXTERN void
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);
-/* https://github.com/harfbuzz/harfbuzz/pull/4207 */
-/**
- * HB_UNICODE_COMBINING_CLASS_CCC133:
- *
- * [Tibetan]
- *
- * Deprecated: 7.2.0
- **/
-#define HB_UNICODE_COMBINING_CLASS_CCC133 133
-
-/**
- * hb_unicode_eastasian_width_func_t:
- * @ufuncs: A Unicode-functions structure
- * @unicode: The code point to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * Deprecated: 2.0.0
- */
-typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data);
-
-/**
- * hb_unicode_funcs_set_eastasian_width_func:
- * @ufuncs: a Unicode-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_unicode_eastasian_width_func_t.
- *
- * Since: 0.9.2
- * Deprecated: 2.0.0
- **/
-HB_EXTERN HB_DEPRECATED void
-hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_eastasian_width_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_unicode_eastasian_width:
- * @ufuncs: a Unicode-function structure
- * @unicode: The code point to query
- *
- * Don't use. Not used by HarfBuzz.
- *
- * Since: 0.9.2
- * Deprecated: 2.0.0
- **/
-HB_EXTERN HB_DEPRECATED unsigned int
-hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode);
-
-
-/**
- * hb_unicode_decompose_compatibility_func_t:
- * @ufuncs: a Unicode function structure
- * @u: codepoint to decompose
- * @decomposed: address of codepoint array (of length #HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
- * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
- *
- * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
- * The complete length of the decomposition will be returned.
- *
- * If @u has no compatibility decomposition, zero should be returned.
- *
- * The Unicode standard guarantees that a buffer of length #HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
- * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
- * of this function type must ensure that they do not write past the provided array.
- *
- * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
- *
- * Deprecated: 2.0.0
- */
-typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t u,
- hb_codepoint_t *decomposed,
- void *user_data);
-
-/**
- * HB_UNICODE_MAX_DECOMPOSITION_LEN:
- *
- * See Unicode 6.1 for details on the maximum decomposition length.
- *
- * Deprecated: 2.0.0
- */
-#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
-
-/**
- * hb_unicode_funcs_set_decompose_compatibility_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_unicode_decompose_compatibility_func_t.
- *
- *
- *
- * Since: 0.9.2
- * Deprecated: 2.0.0
- **/
-HB_EXTERN HB_DEPRECATED void
-hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_decompose_compatibility_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-HB_EXTERN HB_DEPRECATED unsigned int
-hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t u,
- hb_codepoint_t *decomposed);
-
-
-/**
- * hb_font_get_glyph_v_kerning_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the kerning-adjustment value for a glyph-pair in
- * the specified font, for vertical text segments.
- *
- **/
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
-
-/**
- * hb_font_funcs_set_glyph_v_kerning_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_v_kerning_func_t.
- *
- * Since: 0.9.2
- * Deprecated: 2.0.0
- **/
HB_EXTERN void
-hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_v_kerning_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-HB_EXTERN hb_position_t
-hb_font_get_glyph_v_kerning (hb_font_t *font,
- hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
+hb_set_invert (hb_set_t *set);
#endif
-
HB_END_DECLS
#endif /* HB_DEPRECATED_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc
deleted file mode 100644
index 42764a244b1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.cc
+++ /dev/null
@@ -1,884 +0,0 @@
-/*
- * Copyright © 2015-2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_DIRECTWRITE
-
-#include "hb-shaper-impl.hh"
-
-#include <dwrite_1.h>
-
-#include "hb-directwrite.h"
-
-#include "hb-ms-feature-ranges.hh"
-
-/**
- * SECTION:hb-directwrite
- * @title: hb-directwrite
- * @short_description: DirectWrite integration
- * @include: hb-directwrite.h
- *
- * Functions for using HarfBuzz with DirectWrite fonts.
- **/
-
-/* Declare object creator for dynamic support of DWRITE */
-typedef HRESULT (WINAPI *t_DWriteCreateFactory)(
- DWRITE_FACTORY_TYPE factoryType,
- REFIID iid,
- IUnknown **factory
-);
-
-
-/*
- * DirectWrite font stream helpers
- */
-
-// This is a font loader which provides only one font (unlike its original design).
-// For a better implementation which was also source of this
-// and DWriteFontFileStream, have a look at to NativeFontResourceDWrite.cpp in Mozilla
-class DWriteFontFileLoader : public IDWriteFontFileLoader
-{
-private:
- IDWriteFontFileStream *mFontFileStream;
-public:
- DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream)
- { mFontFileStream = fontFileStream; }
-
- // IUnknown interface
- IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject)
- { return S_OK; }
- IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
- IFACEMETHOD_ (ULONG, Release) () { return 1; }
-
- // IDWriteFontFileLoader methods
- virtual HRESULT STDMETHODCALLTYPE
- CreateStreamFromKey (void const* fontFileReferenceKey,
- uint32_t fontFileReferenceKeySize,
- OUT IDWriteFontFileStream** fontFileStream)
- {
- *fontFileStream = mFontFileStream;
- return S_OK;
- }
-
- virtual ~DWriteFontFileLoader() {}
-};
-
-class DWriteFontFileStream : public IDWriteFontFileStream
-{
-private:
- uint8_t *mData;
- uint32_t mSize;
-public:
- DWriteFontFileStream (uint8_t *aData, uint32_t aSize)
- {
- mData = aData;
- mSize = aSize;
- }
-
- // IUnknown interface
- IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject)
- { return S_OK; }
- IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
- IFACEMETHOD_ (ULONG, Release) () { return 1; }
-
- // IDWriteFontFileStream methods
- virtual HRESULT STDMETHODCALLTYPE
- ReadFileFragment (void const** fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void** fragmentContext)
- {
- // We are required to do bounds checking.
- if (fileOffset + fragmentSize > mSize) return E_FAIL;
-
- // truncate the 64 bit fileOffset to size_t sized index into mData
- size_t index = static_cast<size_t> (fileOffset);
-
- // We should be alive for the duration of this.
- *fragmentStart = &mData[index];
- *fragmentContext = nullptr;
- return S_OK;
- }
-
- virtual void STDMETHODCALLTYPE
- ReleaseFileFragment (void* fragmentContext) {}
-
- virtual HRESULT STDMETHODCALLTYPE
- GetFileSize (OUT UINT64* fileSize)
- {
- *fileSize = mSize;
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE
- GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; }
-
- virtual ~DWriteFontFileStream() {}
-};
-
-
-/*
-* shaper face data
-*/
-
-struct hb_directwrite_face_data_t
-{
- HMODULE dwrite_dll;
- IDWriteFactory *dwriteFactory;
- IDWriteFontFile *fontFile;
- DWriteFontFileStream *fontFileStream;
- DWriteFontFileLoader *fontFileLoader;
- IDWriteFontFace *fontFace;
- hb_blob_t *faceBlob;
-};
-
-hb_directwrite_face_data_t *
-_hb_directwrite_shaper_face_data_create (hb_face_t *face)
-{
- hb_directwrite_face_data_t *data = new hb_directwrite_face_data_t;
- if (unlikely (!data))
- return nullptr;
-
-#define FAIL(...) \
- HB_STMT_START { \
- DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
- return nullptr; \
- } HB_STMT_END
-
- data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
- if (unlikely (!data->dwrite_dll))
- FAIL ("Cannot find DWrite.DLL");
-
- t_DWriteCreateFactory p_DWriteCreateFactory;
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-
- p_DWriteCreateFactory = (t_DWriteCreateFactory)
- GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
- if (unlikely (!p_DWriteCreateFactory))
- FAIL ("Cannot find DWriteCreateFactory().");
-
- HRESULT hr;
-
- // TODO: factory and fontFileLoader should be cached separately
- IDWriteFactory* dwriteFactory;
- hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
- (IUnknown**) &dwriteFactory);
-
- if (unlikely (hr != S_OK))
- FAIL ("Failed to run DWriteCreateFactory().");
-
- hb_blob_t *blob = hb_face_reference_blob (face);
- DWriteFontFileStream *fontFileStream;
- fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr),
- hb_blob_get_length (blob));
-
- DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream);
- dwriteFactory->RegisterFontFileLoader (fontFileLoader);
-
- IDWriteFontFile *fontFile;
- uint64_t fontFileKey = 0;
- hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey),
- fontFileLoader, &fontFile);
-
- if (FAILED (hr))
- FAIL ("Failed to load font file from data!");
-
- BOOL isSupported;
- DWRITE_FONT_FILE_TYPE fileType;
- DWRITE_FONT_FACE_TYPE faceType;
- uint32_t numberOfFaces;
- hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces);
- if (FAILED (hr) || !isSupported)
- FAIL ("Font file is not supported.");
-
-#undef FAIL
-
- IDWriteFontFace *fontFace;
- dwriteFactory->CreateFontFace (faceType, 1, &fontFile, 0,
- DWRITE_FONT_SIMULATIONS_NONE, &fontFace);
-
- data->dwriteFactory = dwriteFactory;
- data->fontFile = fontFile;
- data->fontFileStream = fontFileStream;
- data->fontFileLoader = fontFileLoader;
- data->fontFace = fontFace;
- data->faceBlob = blob;
-
- return data;
-}
-
-void
-_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
-{
- if (data->fontFace)
- data->fontFace->Release ();
- if (data->fontFile)
- data->fontFile->Release ();
- if (data->dwriteFactory)
- {
- if (data->fontFileLoader)
- data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader);
- data->dwriteFactory->Release ();
- }
- delete data->fontFileLoader;
- delete data->fontFileStream;
- hb_blob_destroy (data->faceBlob);
- if (data->dwrite_dll)
- FreeLibrary (data->dwrite_dll);
- delete data;
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_directwrite_font_data_t {};
-
-hb_directwrite_font_data_t *
-_hb_directwrite_shaper_font_data_create (hb_font_t *font)
-{
- return (hb_directwrite_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data)
-{
-}
-
-
-// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project
-// but now is relicensed to MIT for HarfBuzz use
-class TextAnalysis : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink
-{
-public:
-
- IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject)
- { return S_OK; }
- IFACEMETHOD_ (ULONG, AddRef) () { return 1; }
- IFACEMETHOD_ (ULONG, Release) () { return 1; }
-
- // A single contiguous run of characters containing the same analysis
- // results.
- struct Run
- {
- uint32_t mTextStart; // starting text position of this run
- uint32_t mTextLength; // number of contiguous code units covered
- uint32_t mGlyphStart; // starting glyph in the glyphs array
- uint32_t mGlyphCount; // number of glyphs associated with this run
- // text
- DWRITE_SCRIPT_ANALYSIS mScript;
- uint8_t mBidiLevel;
- bool mIsSideways;
-
- bool ContainsTextPosition (uint32_t aTextPosition) const
- {
- return aTextPosition >= mTextStart &&
- aTextPosition < mTextStart + mTextLength;
- }
-
- Run *nextRun;
- };
-
-public:
- TextAnalysis (const wchar_t* text, uint32_t textLength,
- const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection)
- : mTextLength (textLength), mText (text), mLocaleName (localeName),
- mReadingDirection (readingDirection), mCurrentRun (nullptr) {}
- ~TextAnalysis ()
- {
- // delete runs, except mRunHead which is part of the TextAnalysis object
- for (Run *run = mRunHead.nextRun; run;)
- {
- Run *origRun = run;
- run = run->nextRun;
- delete origRun;
- }
- }
-
- STDMETHODIMP
- GenerateResults (IDWriteTextAnalyzer* textAnalyzer, Run **runHead)
- {
- // Analyzes the text using the script analyzer and returns
- // the result as a series of runs.
-
- HRESULT hr = S_OK;
-
- // Initially start out with one result that covers the entire range.
- // This result will be subdivided by the analysis processes.
- mRunHead.mTextStart = 0;
- mRunHead.mTextLength = mTextLength;
- mRunHead.mBidiLevel =
- (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
- mRunHead.nextRun = nullptr;
- mCurrentRun = &mRunHead;
-
- // Call each of the analyzers in sequence, recording their results.
- if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this)))
- *runHead = &mRunHead;
-
- return hr;
- }
-
- // IDWriteTextAnalysisSource implementation
-
- IFACEMETHODIMP
- GetTextAtPosition (uint32_t textPosition,
- OUT wchar_t const** textString,
- OUT uint32_t* textLength)
- {
- if (textPosition >= mTextLength)
- {
- // No text at this position, valid query though.
- *textString = nullptr;
- *textLength = 0;
- }
- else
- {
- *textString = mText + textPosition;
- *textLength = mTextLength - textPosition;
- }
- return S_OK;
- }
-
- IFACEMETHODIMP
- GetTextBeforePosition (uint32_t textPosition,
- OUT wchar_t const** textString,
- OUT uint32_t* textLength)
- {
- if (textPosition == 0 || textPosition > mTextLength)
- {
- // Either there is no text before here (== 0), or this
- // is an invalid position. The query is considered valid though.
- *textString = nullptr;
- *textLength = 0;
- }
- else
- {
- *textString = mText;
- *textLength = textPosition;
- }
- return S_OK;
- }
-
- IFACEMETHODIMP_ (DWRITE_READING_DIRECTION)
- GetParagraphReadingDirection () { return mReadingDirection; }
-
- IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength,
- wchar_t const** localeName)
- { return S_OK; }
-
- IFACEMETHODIMP
- GetNumberSubstitution (uint32_t textPosition,
- OUT uint32_t* textLength,
- OUT IDWriteNumberSubstitution** numberSubstitution)
- {
- // We do not support number substitution.
- *numberSubstitution = nullptr;
- *textLength = mTextLength - textPosition;
-
- return S_OK;
- }
-
- // IDWriteTextAnalysisSink implementation
-
- IFACEMETHODIMP
- SetScriptAnalysis (uint32_t textPosition, uint32_t textLength,
- DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
- {
- SetCurrentRun (textPosition);
- SplitCurrentRun (textPosition);
- while (textLength > 0)
- {
- Run *run = FetchNextRun (&textLength);
- run->mScript = *scriptAnalysis;
- }
-
- return S_OK;
- }
-
- IFACEMETHODIMP
- SetLineBreakpoints (uint32_t textPosition,
- uint32_t textLength,
- const DWRITE_LINE_BREAKPOINT* lineBreakpoints)
- { return S_OK; }
-
- IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength,
- uint8_t explicitLevel, uint8_t resolvedLevel)
- { return S_OK; }
-
- IFACEMETHODIMP
- SetNumberSubstitution (uint32_t textPosition, uint32_t textLength,
- IDWriteNumberSubstitution* numberSubstitution)
- { return S_OK; }
-
-protected:
- Run *FetchNextRun (IN OUT uint32_t* textLength)
- {
- // Used by the sink setters, this returns a reference to the next run.
- // Position and length are adjusted to now point after the current run
- // being returned.
-
- Run *origRun = mCurrentRun;
- // Split the tail if needed (the length remaining is less than the
- // current run's size).
- if (*textLength < mCurrentRun->mTextLength)
- SplitCurrentRun (mCurrentRun->mTextStart + *textLength);
- else
- // Just advance the current run.
- mCurrentRun = mCurrentRun->nextRun;
- *textLength -= origRun->mTextLength;
-
- // Return a reference to the run that was just current.
- return origRun;
- }
-
- void SetCurrentRun (uint32_t textPosition)
- {
- // Move the current run to the given position.
- // Since the analyzers generally return results in a forward manner,
- // this will usually just return early. If not, find the
- // corresponding run for the text position.
-
- if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition))
- return;
-
- for (Run *run = &mRunHead; run; run = run->nextRun)
- if (run->ContainsTextPosition (textPosition))
- {
- mCurrentRun = run;
- return;
- }
- assert (0); // We should always be able to find the text position in one of our runs
- }
-
- void SplitCurrentRun (uint32_t splitPosition)
- {
- if (!mCurrentRun)
- {
- assert (0); // SplitCurrentRun called without current run
- // Shouldn't be calling this when no current run is set!
- return;
- }
- // Split the current run.
- if (splitPosition <= mCurrentRun->mTextStart)
- {
- // No need to split, already the start of a run
- // or before it. Usually the first.
- return;
- }
- Run *newRun = new Run;
-
- *newRun = *mCurrentRun;
-
- // Insert the new run in our linked list.
- newRun->nextRun = mCurrentRun->nextRun;
- mCurrentRun->nextRun = newRun;
-
- // Adjust runs' text positions and lengths.
- uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart;
- newRun->mTextStart += splitPoint;
- newRun->mTextLength -= splitPoint;
- mCurrentRun->mTextLength = splitPoint;
- mCurrentRun = newRun;
- }
-
-protected:
- // Input
- // (weak references are fine here, since this class is a transient
- // stack-based helper that doesn't need to copy data)
- uint32_t mTextLength;
- const wchar_t* mText;
- const wchar_t* mLocaleName;
- DWRITE_READING_DIRECTION mReadingDirection;
-
- // Current processing state.
- Run *mCurrentRun;
-
- // Output is a list of runs starting here
- Run mRunHead;
-};
-
-/*
- * shaper
- */
-
-hb_bool_t
-_hb_directwrite_shape (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
-{
- hb_face_t *face = font->face;
- const hb_directwrite_face_data_t *face_data = face->data.directwrite;
- IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
- IDWriteFontFace *fontFace = face_data->fontFace;
-
- IDWriteTextAnalyzer* analyzer;
- dwriteFactory->CreateTextAnalyzer (&analyzer);
-
- unsigned int scratch_size;
- hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
-#define ALLOCATE_ARRAY(Type, name, len) \
- Type *name = (Type *) scratch; \
- do { \
- unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
- assert (_consumed <= scratch_size); \
- scratch += _consumed; \
- scratch_size -= _consumed; \
- } while (0)
-
-#define utf16_index() var1.u32
-
- ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2);
-
- unsigned int chars_len = 0;
- for (unsigned int i = 0; i < buffer->len; i++)
- {
- hb_codepoint_t c = buffer->info[i].codepoint;
- buffer->info[i].utf16_index () = chars_len;
- if (likely (c <= 0xFFFFu))
- textString[chars_len++] = c;
- else if (unlikely (c > 0x10FFFFu))
- textString[chars_len++] = 0xFFFDu;
- else
- {
- textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
- textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
- }
- }
-
- ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
- /* Need log_clusters to assign features. */
- chars_len = 0;
- for (unsigned int i = 0; i < buffer->len; i++)
- {
- hb_codepoint_t c = buffer->info[i].codepoint;
- unsigned int cluster = buffer->info[i].cluster;
- log_clusters[chars_len++] = cluster;
- if (hb_in_range (c, 0x10000u, 0x10FFFFu))
- log_clusters[chars_len++] = cluster; /* Surrogates. */
- }
-
- DWRITE_READING_DIRECTION readingDirection;
- readingDirection = buffer->props.direction ?
- DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
-
- /*
- * There's an internal 16-bit limit on some things inside the analyzer,
- * but we never attempt to shape a word longer than 64K characters
- * in a single gfxShapedWord, so we cannot exceed that limit.
- */
- uint32_t textLength = chars_len;
-
- TextAnalysis analysis (textString, textLength, nullptr, readingDirection);
- TextAnalysis::Run *runHead;
- HRESULT hr;
- hr = analysis.GenerateResults (analyzer, &runHead);
-
-#define FAIL(...) \
- HB_STMT_START { \
- DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
- return false; \
- } HB_STMT_END
-
- if (FAILED (hr))
- FAIL ("Analyzer failed to generate results.");
-
- uint32_t maxGlyphCount = 3 * textLength / 2 + 16;
- uint32_t glyphCount;
- bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
-
- const wchar_t localeName[20] = {0};
- if (buffer->props.language)
- mbstowcs ((wchar_t*) localeName,
- hb_language_to_string (buffer->props.language), 20);
-
- /*
- * Set up features.
- */
- static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), "");
- static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), "");
- hb_vector_t<hb_ms_features_t *> range_features;
- hb_vector_t<uint32_t> range_char_counts;
- if (num_features)
- {
- hb_vector_t<hb_ms_feature_t> feature_records;
- hb_vector_t<hb_ms_range_record_t> range_records;
- if (hb_ms_setup_features (features, num_features, feature_records, range_records))
- hb_ms_make_feature_ranges (feature_records,
- range_records,
- 0,
- chars_len,
- log_clusters,
- range_features,
- range_char_counts);
- }
-
- uint16_t* clusterMap;
- clusterMap = new uint16_t[textLength];
- DWRITE_SHAPING_TEXT_PROPERTIES* textProperties;
- textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength];
-
-retry_getglyphs:
- uint16_t* glyphIndices = new uint16_t[maxGlyphCount];
- DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties;
- glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount];
-
- hr = analyzer->GetGlyphs (textString,
- chars_len,
- fontFace,
- false,
- isRightToLeft,
- &runHead->mScript,
- localeName,
- nullptr,
- (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ,
- range_char_counts.arrayZ,
- range_features.length,
- maxGlyphCount,
- clusterMap,
- textProperties,
- glyphIndices,
- glyphProperties,
- &glyphCount);
-
- if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)))
- {
- delete [] glyphIndices;
- delete [] glyphProperties;
-
- maxGlyphCount *= 2;
-
- goto retry_getglyphs;
- }
- if (FAILED (hr))
- FAIL ("Analyzer failed to get glyphs.");
-
- float* glyphAdvances = new float[maxGlyphCount];
- DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount];
-
- /* The -2 in the following is to compensate for possible
- * alignment needed after the WORD array. sizeof (WORD) == 2. */
- unsigned int glyphs_size = (scratch_size * sizeof (int) - 2)
- / (sizeof (WORD) +
- sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) +
- sizeof (int) +
- sizeof (DWRITE_GLYPH_OFFSET) +
- sizeof (uint32_t));
- ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
-
-#undef ALLOCATE_ARRAY
-
- int fontEmSize = font->face->get_upem ();
- if (fontEmSize < 0) fontEmSize = -fontEmSize;
-
- if (fontEmSize < 0) fontEmSize = -fontEmSize;
- double x_mult = (double) font->x_scale / fontEmSize;
- double y_mult = (double) font->y_scale / fontEmSize;
-
- hr = analyzer->GetGlyphPlacements (textString,
- clusterMap,
- textProperties,
- chars_len,
- glyphIndices,
- glyphProperties,
- glyphCount,
- fontFace,
- fontEmSize,
- false,
- isRightToLeft,
- &runHead->mScript,
- localeName,
- (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ,
- range_char_counts.arrayZ,
- range_features.length,
- glyphAdvances,
- glyphOffsets);
-
- if (FAILED (hr))
- FAIL ("Analyzer failed to get glyph placements.");
-
- /* Ok, we've got everything we need, now compose output buffer,
- * very, *very*, carefully! */
-
- /* Calculate visual-clusters. That's what we ship. */
- for (unsigned int i = 0; i < glyphCount; i++)
- vis_clusters[i] = (uint32_t) -1;
- for (unsigned int i = 0; i < buffer->len; i++)
- {
- uint32_t *p =
- &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]];
- *p = hb_min (*p, buffer->info[i].cluster);
- }
- for (unsigned int i = 1; i < glyphCount; i++)
- if (vis_clusters[i] == (uint32_t) -1)
- vis_clusters[i] = vis_clusters[i - 1];
-
-#undef utf16_index
-
- if (unlikely (!buffer->ensure (glyphCount)))
- FAIL ("Buffer in error");
-
-#undef FAIL
-
- /* Set glyph infos */
- buffer->len = 0;
- for (unsigned int i = 0; i < glyphCount; i++)
- {
- hb_glyph_info_t *info = &buffer->info[buffer->len++];
-
- info->codepoint = glyphIndices[i];
- info->cluster = vis_clusters[i];
-
- /* The rest is crap. Let's store position info there for now. */
- info->mask = glyphAdvances[i];
- info->var1.i32 = glyphOffsets[i].advanceOffset;
- info->var2.i32 = glyphOffsets[i].ascenderOffset;
- }
-
- /* Set glyph positions */
- buffer->clear_positions ();
- for (unsigned int i = 0; i < glyphCount; i++)
- {
- hb_glyph_info_t *info = &buffer->info[i];
- hb_glyph_position_t *pos = &buffer->pos[i];
-
- /* TODO vertical */
- pos->x_advance = x_mult * (int32_t) info->mask;
- pos->x_offset = x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32);
- pos->y_offset = y_mult * info->var2.i32;
- }
-
- if (isRightToLeft) hb_buffer_reverse (buffer);
-
- buffer->clear_glyph_flags ();
- buffer->unsafe_to_break ();
-
- delete [] clusterMap;
- delete [] glyphIndices;
- delete [] textProperties;
- delete [] glyphProperties;
- delete [] glyphAdvances;
- delete [] glyphOffsets;
-
- /* Wow, done! */
- return true;
-}
-
-struct _hb_directwrite_font_table_context {
- IDWriteFontFace *face;
- void *table_context;
-};
-
-static void
-_hb_directwrite_table_data_release (void *data)
-{
- _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) data;
- context->face->ReleaseFontTable (context->table_context);
- hb_free (context);
-}
-
-static hb_blob_t *
-_hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
- IDWriteFontFace *dw_face = ((IDWriteFontFace *) user_data);
- const void *data;
- uint32_t length;
- void *table_context;
- BOOL exists;
- if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data,
- &length, &table_context, &exists)))
- return nullptr;
-
- if (!data || !exists || !length)
- {
- dw_face->ReleaseFontTable (table_context);
- return nullptr;
- }
-
- _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) hb_malloc (sizeof (_hb_directwrite_font_table_context));
- context->face = dw_face;
- context->table_context = table_context;
-
- return hb_blob_create ((const char *) data, length, HB_MEMORY_MODE_READONLY,
- context, _hb_directwrite_table_data_release);
-}
-
-static void
-_hb_directwrite_font_release (void *data)
-{
- if (data)
- ((IDWriteFontFace *) data)->Release ();
-}
-
-/**
- * hb_directwrite_face_create:
- * @font_face: a DirectWrite IDWriteFontFace object.
- *
- * Constructs a new face object from the specified DirectWrite IDWriteFontFace.
- *
- * Return value: #hb_face_t object corresponding to the given input
- *
- * Since: 2.4.0
- **/
-hb_face_t *
-hb_directwrite_face_create (IDWriteFontFace *font_face)
-{
- if (font_face)
- font_face->AddRef ();
- return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face,
- _hb_directwrite_font_release);
-}
-
-/**
-* hb_directwrite_face_get_font_face:
-* @face: a #hb_face_t object
-*
-* Gets the DirectWrite IDWriteFontFace associated with @face.
-*
-* Return value: DirectWrite IDWriteFontFace object corresponding to the given input
-*
-* Since: 2.5.0
-**/
-IDWriteFontFace *
-hb_directwrite_face_get_font_face (hb_face_t *face)
-{
- return face->data.directwrite->fontFace;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.h b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.h
deleted file mode 100644
index f837627a286..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2015-2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_DIRECTWRITE_H
-#define HB_DIRECTWRITE_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-HB_EXTERN hb_face_t *
-hb_directwrite_face_create (IDWriteFontFace *font_face);
-
-HB_EXTERN IDWriteFontFace *
-hb_directwrite_face_get_font_face (hb_face_t *face);
-
-HB_END_DECLS
-
-#endif /* HB_DIRECTWRITE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh b/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh
deleted file mode 100644
index 37ca6814653..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-dispatch.hh
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2012,2018 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_DISPATCH_HH
-#define HB_DISPATCH_HH
-
-#include "hb.hh"
-
-/*
- * Dispatch
- */
-
-template <typename Context, typename Return=hb_empty_t, unsigned int MaxDebugDepth=0>
-struct hb_dispatch_context_t
-{
- private:
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- const Context* thiz () const { return static_cast<const Context *> (this); }
- Context* thiz () { return static_cast< Context *> (this); }
- public:
- const char *get_name () { return "UNKNOWN"; }
- static constexpr unsigned max_debug_depth = MaxDebugDepth;
- typedef Return return_t;
- template <typename T, typename F>
- bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
- template <typename T, typename ...Ts>
- return_t dispatch (const T &obj, Ts&&... ds)
- { return obj.dispatch (thiz (), std::forward<Ts> (ds)...); }
- static return_t no_dispatch_return_value () { return Context::default_return_value (); }
- static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
- unsigned debug_depth = 0;
-};
-
-
-#endif /* HB_DISPATCH_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.cc b/src/3rdparty/harfbuzz-ng/src/hb-draw.cc
deleted file mode 100644
index f204f56bc7a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-draw.cc
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright © 2019-2020 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_DRAW
-
-#include "hb-draw.hh"
-
-/**
- * SECTION:hb-draw
- * @title: hb-draw
- * @short_description: Glyph drawing
- * @include: hb.h
- *
- * Functions for drawing (extracting) glyph shapes.
- *
- * The #hb_draw_funcs_t struct can be used with hb_font_draw_glyph().
- **/
-
-static void
-hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
- hb_draw_state_t *st HB_UNUSED,
- float to_x HB_UNUSED, float to_y HB_UNUSED,
- void *user_data HB_UNUSED) {}
-
-static void
-hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
- hb_draw_state_t *st HB_UNUSED,
- float to_x HB_UNUSED, float to_y HB_UNUSED,
- void *user_data HB_UNUSED) {}
-
-static void
-hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
-#define HB_ONE_THIRD 0.33333333f
- dfuncs->emit_cubic_to (draw_data, *st,
- (st->current_x + 2.f * control_x) * HB_ONE_THIRD,
- (st->current_y + 2.f * control_y) * HB_ONE_THIRD,
- (to_x + 2.f * control_x) * HB_ONE_THIRD,
- (to_y + 2.f * control_y) * HB_ONE_THIRD,
- to_x, to_y);
-#undef HB_ONE_THIRD
-}
-
-static void
-hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
- hb_draw_state_t *st HB_UNUSED,
- float control1_x HB_UNUSED, float control1_y HB_UNUSED,
- float control2_x HB_UNUSED, float control2_y HB_UNUSED,
- float to_x HB_UNUSED, float to_y HB_UNUSED,
- void *user_data HB_UNUSED) {}
-
-static void
-hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
- hb_draw_state_t *st HB_UNUSED,
- void *user_data HB_UNUSED) {}
-
-
-static bool
-_hb_draw_funcs_set_preamble (hb_draw_funcs_t *dfuncs,
- bool func_is_null,
- void **user_data,
- hb_destroy_func_t *destroy)
-{
- if (hb_object_is_immutable (dfuncs))
- {
- if (*destroy)
- (*destroy) (*user_data);
- return false;
- }
-
- if (func_is_null)
- {
- if (*destroy)
- (*destroy) (*user_data);
- *destroy = nullptr;
- *user_data = nullptr;
- }
-
- return true;
-}
-
-static bool
-_hb_draw_funcs_set_middle (hb_draw_funcs_t *dfuncs,
- void *user_data,
- hb_destroy_func_t destroy)
-{
- if (user_data && !dfuncs->user_data)
- {
- dfuncs->user_data = (decltype (dfuncs->user_data)) hb_calloc (1, sizeof (*dfuncs->user_data));
- if (unlikely (!dfuncs->user_data))
- goto fail;
- }
- if (destroy && !dfuncs->destroy)
- {
- dfuncs->destroy = (decltype (dfuncs->destroy)) hb_calloc (1, sizeof (*dfuncs->destroy));
- if (unlikely (!dfuncs->destroy))
- goto fail;
- }
-
- return true;
-
-fail:
- if (destroy)
- (destroy) (user_data);
- return false;
-}
-
-#define HB_DRAW_FUNC_IMPLEMENT(name) \
- \
-void \
-hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
- hb_draw_##name##_func_t func, \
- void *user_data, \
- hb_destroy_func_t destroy) \
-{ \
- if (!_hb_draw_funcs_set_preamble (dfuncs, !func, &user_data, &destroy))\
- return; \
- \
- if (dfuncs->destroy && dfuncs->destroy->name) \
- dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name); \
- \
- if (!_hb_draw_funcs_set_middle (dfuncs, user_data, destroy)) \
- return; \
- \
- if (func) \
- dfuncs->func.name = func; \
- else \
- dfuncs->func.name = hb_draw_##name##_nil; \
- \
- if (dfuncs->user_data) \
- dfuncs->user_data->name = user_data; \
- if (dfuncs->destroy) \
- dfuncs->destroy->name = destroy; \
-}
-
-HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
-
-/**
- * hb_draw_funcs_create:
- *
- * Creates a new draw callbacks object.
- *
- * Return value: (transfer full):
- * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial
- * reference count should be released with hb_draw_funcs_destroy when you are
- * done using the #hb_draw_funcs_t. This function never returns `NULL`. If
- * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will
- * be returned.
- *
- * Since: 4.0.0
- **/
-hb_draw_funcs_t *
-hb_draw_funcs_create ()
-{
- hb_draw_funcs_t *dfuncs;
- if (unlikely (!(dfuncs = hb_object_create<hb_draw_funcs_t> ())))
- return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
-
- dfuncs->func = Null (hb_draw_funcs_t).func;
-
- return dfuncs;
-}
-
-DEFINE_NULL_INSTANCE (hb_draw_funcs_t) =
-{
- HB_OBJECT_HEADER_STATIC,
-
- {
-#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil,
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- }
-};
-
-/**
- * hb_draw_funcs_get_empty:
- *
- * Fetches the singleton empty draw-functions structure.
- *
- * Return value: (transfer full): The empty draw-functions structure
- *
- * Since: 7.0.0
- **/
-hb_draw_funcs_t *
-hb_draw_funcs_get_empty ()
-{
- return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
-}
-
-/**
- * hb_draw_funcs_reference: (skip)
- * @dfuncs: draw functions
- *
- * Increases the reference count on @dfuncs by one.
- *
- * This prevents @dfuncs from being destroyed until a matching
- * call to hb_draw_funcs_destroy() is made.
- *
- * Return value: (transfer full):
- * The referenced #hb_draw_funcs_t.
- *
- * Since: 4.0.0
- **/
-hb_draw_funcs_t *
-hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs)
-{
- return hb_object_reference (dfuncs);
-}
-
-/**
- * hb_draw_funcs_destroy: (skip)
- * @dfuncs: draw functions
- *
- * Deallocate the @dfuncs.
- * Decreases the reference count on @dfuncs by one. If the result is zero, then
- * @dfuncs and all associated resources are freed. See hb_draw_funcs_reference().
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
-{
- if (!hb_object_destroy (dfuncs)) return;
-
- if (dfuncs->destroy)
- {
-#define HB_DRAW_FUNC_IMPLEMENT(name) \
- if (dfuncs->destroy->name) dfuncs->destroy->name (!dfuncs->user_data ? nullptr : dfuncs->user_data->name);
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- }
-
- hb_free (dfuncs->destroy);
- hb_free (dfuncs->user_data);
-
- hb_free (dfuncs);
-}
-
-/**
- * hb_draw_funcs_set_user_data: (skip)
- * @dfuncs: The draw-functions structure
- * @key: The user-data key
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the specified draw-functions structure.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 7.0.0
- **/
-hb_bool_t
-hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- return hb_object_set_user_data (dfuncs, key, data, destroy, replace);
-}
-
-/**
- * hb_draw_funcs_get_user_data: (skip)
- * @dfuncs: The draw-functions structure
- * @key: The user-data key to query
- *
- * Fetches the user-data associated with the specified key,
- * attached to the specified draw-functions structure.
- *
- * Return value: (transfer none): A pointer to the user data
- *
- * Since: 7.0.0
- **/
-void *
-hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,
- hb_user_data_key_t *key)
-{
- return hb_object_get_user_data (dfuncs, key);
-}
-
-/**
- * hb_draw_funcs_make_immutable:
- * @dfuncs: draw functions
- *
- * Makes @dfuncs object immutable.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs)
-{
- if (hb_object_is_immutable (dfuncs))
- return;
-
- hb_object_make_immutable (dfuncs);
-}
-
-/**
- * hb_draw_funcs_is_immutable:
- * @dfuncs: draw functions
- *
- * Checks whether @dfuncs is immutable.
- *
- * Return value: `true` if @dfuncs is immutable, `false` otherwise
- *
- * Since: 4.0.0
- **/
-hb_bool_t
-hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs)
-{
- return hb_object_is_immutable (dfuncs);
-}
-
-
-/**
- * hb_draw_move_to:
- * @dfuncs: draw functions
- * @draw_data: associated draw data passed by the caller
- * @st: current draw state
- * @to_x: X component of target point
- * @to_y: Y component of target point
- *
- * Perform a "move-to" draw operation.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y)
-{
- dfuncs->move_to (draw_data, *st,
- to_x, to_y);
-}
-
-/**
- * hb_draw_line_to:
- * @dfuncs: draw functions
- * @draw_data: associated draw data passed by the caller
- * @st: current draw state
- * @to_x: X component of target point
- * @to_y: Y component of target point
- *
- * Perform a "line-to" draw operation.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y)
-{
- dfuncs->line_to (draw_data, *st,
- to_x, to_y);
-}
-
-/**
- * hb_draw_quadratic_to:
- * @dfuncs: draw functions
- * @draw_data: associated draw data passed by the caller
- * @st: current draw state
- * @control_x: X component of control point
- * @control_y: Y component of control point
- * @to_x: X component of target point
- * @to_y: Y component of target point
- *
- * Perform a "quadratic-to" draw operation.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y)
-{
- dfuncs->quadratic_to (draw_data, *st,
- control_x, control_y,
- to_x, to_y);
-}
-
-/**
- * hb_draw_cubic_to:
- * @dfuncs: draw functions
- * @draw_data: associated draw data passed by the caller
- * @st: current draw state
- * @control1_x: X component of first control point
- * @control1_y: Y component of first control point
- * @control2_x: X component of second control point
- * @control2_y: Y component of second control point
- * @to_x: X component of target point
- * @to_y: Y component of target point
- *
- * Perform a "cubic-to" draw operation.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y)
-{
- dfuncs->cubic_to (draw_data, *st,
- control1_x, control1_y,
- control2_x, control2_y,
- to_x, to_y);
-}
-
-/**
- * hb_draw_close_path:
- * @dfuncs: draw functions
- * @draw_data: associated draw data passed by the caller
- * @st: current draw state
- *
- * Perform a "close-path" draw operation.
- *
- * Since: 4.0.0
- **/
-void
-hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st)
-{
- dfuncs->close_path (draw_data, *st);
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.h b/src/3rdparty/harfbuzz-ng/src/hb-draw.h
deleted file mode 100644
index 9ca0b4006e4..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-draw.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright © 2019-2020 Ebrahim Byagowi
- *
- * 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.
- */
-
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb.h> instead."
-#endif
-
-#ifndef HB_DRAW_H
-#define HB_DRAW_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-
-/**
- * hb_draw_state_t
- * @path_open: Whether there is an open path
- * @path_start_x: X component of the start of current path
- * @path_start_y: Y component of the start of current path
- * @current_x: X component of current point
- * @current_y: Y component of current point
- *
- * Current drawing state.
- *
- * Since: 4.0.0
- **/
-typedef struct hb_draw_state_t {
- hb_bool_t path_open;
-
- float path_start_x;
- float path_start_y;
-
- float current_x;
- float current_y;
-
- /*< private >*/
- hb_var_num_t reserved1;
- hb_var_num_t reserved2;
- hb_var_num_t reserved3;
- hb_var_num_t reserved4;
- hb_var_num_t reserved5;
- hb_var_num_t reserved6;
- hb_var_num_t reserved7;
-} hb_draw_state_t;
-
-/**
- * HB_DRAW_STATE_DEFAULT:
- *
- * The default #hb_draw_state_t at the start of glyph drawing.
- */
-#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}}
-
-
-/**
- * hb_draw_funcs_t:
- *
- * Glyph draw callbacks.
- *
- * #hb_draw_move_to_func_t, #hb_draw_line_to_func_t and
- * #hb_draw_cubic_to_func_t calls are necessary to be defined but we translate
- * #hb_draw_quadratic_to_func_t calls to #hb_draw_cubic_to_func_t if the
- * callback isn't defined.
- *
- * Since: 4.0.0
- **/
-
-typedef struct hb_draw_funcs_t hb_draw_funcs_t;
-
-
-/**
- * hb_draw_move_to_func_t:
- * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
- * @st: current draw state
- * @to_x: X component of target point
- * @to_y: Y component of target point
- * @user_data: User data pointer passed to hb_draw_funcs_set_move_to_func()
- *
- * A virtual method for the #hb_draw_funcs_t to perform a "move-to" draw
- * operation.
- *
- * Since: 4.0.0
- *
- **/
-typedef void (*hb_draw_move_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data);
-
-/**
- * hb_draw_line_to_func_t:
- * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
- * @st: current draw state
- * @to_x: X component of target point
- * @to_y: Y component of target point
- * @user_data: User data pointer passed to hb_draw_funcs_set_line_to_func()
- *
- * A virtual method for the #hb_draw_funcs_t to perform a "line-to" draw
- * operation.
- *
- * Since: 4.0.0
- *
- **/
-typedef void (*hb_draw_line_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data);
-
-/**
- * hb_draw_quadratic_to_func_t:
- * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
- * @st: current draw state
- * @control_x: X component of control point
- * @control_y: Y component of control point
- * @to_x: X component of target point
- * @to_y: Y component of target point
- * @user_data: User data pointer passed to hb_draw_funcs_set_quadratic_to_func()
- *
- * A virtual method for the #hb_draw_funcs_t to perform a "quadratic-to" draw
- * operation.
- *
- * Since: 4.0.0
- *
- **/
-typedef void (*hb_draw_quadratic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y,
- void *user_data);
-
-/**
- * hb_draw_cubic_to_func_t:
- * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
- * @st: current draw state
- * @control1_x: X component of first control point
- * @control1_y: Y component of first control point
- * @control2_x: X component of second control point
- * @control2_y: Y component of second control point
- * @to_x: X component of target point
- * @to_y: Y component of target point
- * @user_data: User data pointer passed to hb_draw_funcs_set_cubic_to_func()
- *
- * A virtual method for the #hb_draw_funcs_t to perform a "cubic-to" draw
- * operation.
- *
- * Since: 4.0.0
- *
- **/
-typedef void (*hb_draw_cubic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *user_data);
-
-/**
- * hb_draw_close_path_func_t:
- * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
- * @st: current draw state
- * @user_data: User data pointer passed to hb_draw_funcs_set_close_path_func()
- *
- * A virtual method for the #hb_draw_funcs_t to perform a "close-path" draw
- * operation.
- *
- * Since: 4.0.0
- *
- **/
-typedef void (*hb_draw_close_path_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- void *user_data);
-
-/**
- * hb_draw_funcs_set_move_to_func:
- * @dfuncs: draw functions object
- * @func: (closure user_data) (destroy destroy) (scope notified): move-to callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets move-to callback to the draw functions object.
- *
- * Since: 4.0.0
- **/
-HB_EXTERN void
-hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *dfuncs,
- hb_draw_move_to_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_draw_funcs_set_line_to_func:
- * @dfuncs: draw functions object
- * @func: (closure user_data) (destroy destroy) (scope notified): line-to callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets line-to callback to the draw functions object.
- *
- * Since: 4.0.0
- **/
-HB_EXTERN void
-hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *dfuncs,
- hb_draw_line_to_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_draw_funcs_set_quadratic_to_func:
- * @dfuncs: draw functions object
- * @func: (closure user_data) (destroy destroy) (scope notified): quadratic-to callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets quadratic-to callback to the draw functions object.
- *
- * Since: 4.0.0
- **/
-HB_EXTERN void
-hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *dfuncs,
- hb_draw_quadratic_to_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_draw_funcs_set_cubic_to_func:
- * @dfuncs: draw functions
- * @func: (closure user_data) (destroy destroy) (scope notified): cubic-to callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets cubic-to callback to the draw functions object.
- *
- * Since: 4.0.0
- **/
-HB_EXTERN void
-hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *dfuncs,
- hb_draw_cubic_to_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_draw_funcs_set_close_path_func:
- * @dfuncs: draw functions object
- * @func: (closure user_data) (destroy destroy) (scope notified): close-path callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets close-path callback to the draw functions object.
- *
- * Since: 4.0.0
- **/
-HB_EXTERN void
-hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *dfuncs,
- hb_draw_close_path_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-
-HB_EXTERN hb_draw_funcs_t *
-hb_draw_funcs_create (void);
-
-HB_EXTERN hb_draw_funcs_t *
-hb_draw_funcs_get_empty (void);
-
-HB_EXTERN hb_draw_funcs_t *
-hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs);
-
-HB_EXTERN void
-hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs);
-
-HB_EXTERN hb_bool_t
-hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace);
-
-
-HB_EXTERN void *
-hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,
- hb_user_data_key_t *key);
-
-HB_EXTERN void
-hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs);
-
-HB_EXTERN hb_bool_t
-hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs);
-
-
-HB_EXTERN void
-hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y);
-
-HB_EXTERN void
-hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y);
-
-HB_EXTERN void
-hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y);
-
-HB_EXTERN void
-hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y);
-
-HB_EXTERN void
-hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
- hb_draw_state_t *st);
-
-
-HB_END_DECLS
-
-#endif /* HB_DRAW_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.hh b/src/3rdparty/harfbuzz-ng/src/hb-draw.hh
deleted file mode 100644
index 768f51a8756..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-draw.hh
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright © 2020 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_DRAW_HH
-#define HB_DRAW_HH
-
-#include "hb.hh"
-
-
-/*
- * hb_draw_funcs_t
- */
-
-#define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \
- HB_DRAW_FUNC_IMPLEMENT (move_to) \
- HB_DRAW_FUNC_IMPLEMENT (line_to) \
- HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \
- HB_DRAW_FUNC_IMPLEMENT (cubic_to) \
- HB_DRAW_FUNC_IMPLEMENT (close_path) \
- /* ^--- Add new callbacks here */
-
-struct hb_draw_funcs_t
-{
- hb_object_header_t header;
-
- struct {
-#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name;
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- } func;
-
- struct {
-#define HB_DRAW_FUNC_IMPLEMENT(name) void *name;
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- } *user_data;
-
- struct {
-#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- } *destroy;
-
- void emit_move_to (void *draw_data, hb_draw_state_t &st,
- float to_x, float to_y)
- { func.move_to (this, draw_data, &st,
- to_x, to_y,
- !user_data ? nullptr : user_data->move_to); }
- void emit_line_to (void *draw_data, hb_draw_state_t &st,
- float to_x, float to_y)
- { func.line_to (this, draw_data, &st,
- to_x, to_y,
- !user_data ? nullptr : user_data->line_to); }
- void emit_quadratic_to (void *draw_data, hb_draw_state_t &st,
- float control_x, float control_y,
- float to_x, float to_y)
- { func.quadratic_to (this, draw_data, &st,
- control_x, control_y,
- to_x, to_y,
- !user_data ? nullptr : user_data->quadratic_to); }
- void emit_cubic_to (void *draw_data, hb_draw_state_t &st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y)
- { func.cubic_to (this, draw_data, &st,
- control1_x, control1_y,
- control2_x, control2_y,
- to_x, to_y,
- !user_data ? nullptr : user_data->cubic_to); }
- void emit_close_path (void *draw_data, hb_draw_state_t &st)
- { func.close_path (this, draw_data, &st,
- !user_data ? nullptr : user_data->close_path); }
-
-
- void move_to (void *draw_data, hb_draw_state_t &st,
- float to_x, float to_y)
- {
- if (st.path_open) close_path (draw_data, st);
- st.current_x = to_x;
- st.current_y = to_y;
- }
-
- void line_to (void *draw_data, hb_draw_state_t &st,
- float to_x, float to_y)
- {
- if (!st.path_open) start_path (draw_data, st);
- emit_line_to (draw_data, st, to_x, to_y);
- st.current_x = to_x;
- st.current_y = to_y;
- }
-
- void
- quadratic_to (void *draw_data, hb_draw_state_t &st,
- float control_x, float control_y,
- float to_x, float to_y)
- {
- if (!st.path_open) start_path (draw_data, st);
- emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
- st.current_x = to_x;
- st.current_y = to_y;
- }
-
- void
- cubic_to (void *draw_data, hb_draw_state_t &st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y)
- {
- if (!st.path_open) start_path (draw_data, st);
- emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
- st.current_x = to_x;
- st.current_y = to_y;
- }
-
- void
- close_path (void *draw_data, hb_draw_state_t &st)
- {
- if (st.path_open)
- {
- if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
- emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
- emit_close_path (draw_data, st);
- }
- st.path_open = false;
- st.path_start_x = st.current_x = st.path_start_y = st.current_y = 0;
- }
-
- protected:
-
- void start_path (void *draw_data, hb_draw_state_t &st)
- {
- assert (!st.path_open);
- emit_move_to (draw_data, st, st.current_x, st.current_y);
- st.path_open = true;
- st.path_start_x = st.current_x;
- st.path_start_y = st.current_y;
- }
-};
-DECLARE_NULL_INSTANCE (hb_draw_funcs_t);
-
-struct hb_draw_session_t
-{
- hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f)
- : slant {slant_}, not_slanted {slant == 0.f},
- funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT
- {}
-
- ~hb_draw_session_t () { close_path (); }
-
- void move_to (float to_x, float to_y)
- {
- if (likely (not_slanted))
- funcs->move_to (draw_data, st,
- to_x, to_y);
- else
- funcs->move_to (draw_data, st,
- to_x + to_y * slant, to_y);
- }
- void line_to (float to_x, float to_y)
- {
- if (likely (not_slanted))
- funcs->line_to (draw_data, st,
- to_x, to_y);
- else
- funcs->line_to (draw_data, st,
- to_x + to_y * slant, to_y);
- }
- void
- quadratic_to (float control_x, float control_y,
- float to_x, float to_y)
- {
- if (likely (not_slanted))
- funcs->quadratic_to (draw_data, st,
- control_x, control_y,
- to_x, to_y);
- else
- funcs->quadratic_to (draw_data, st,
- control_x + control_y * slant, control_y,
- to_x + to_y * slant, to_y);
- }
- void
- cubic_to (float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y)
- {
- if (likely (not_slanted))
- funcs->cubic_to (draw_data, st,
- control1_x, control1_y,
- control2_x, control2_y,
- to_x, to_y);
- else
- funcs->cubic_to (draw_data, st,
- control1_x + control1_y * slant, control1_y,
- control2_x + control2_y * slant, control2_y,
- to_x + to_y * slant, to_y);
- }
- void close_path ()
- {
- funcs->close_path (draw_data, st);
- }
-
- protected:
- float slant;
- bool not_slanted;
- hb_draw_funcs_t *funcs;
- void *draw_data;
- hb_draw_state_t st;
-};
-
-#endif /* HB_DRAW_HH */
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 00000000000..4e8f0431c6a
--- /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-builder.cc b/src/3rdparty/harfbuzz-ng/src/hb-face-builder.cc
deleted file mode 100644
index 84b14d28d60..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-face-builder.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#include "hb-face.hh"
-
-#include "hb-map.hh"
-#include "hb-open-file.hh"
-#include "hb-serialize.hh"
-
-
-/*
- * face-builder: A face that has add_table().
- */
-
-struct face_table_info_t
-{
- hb_blob_t* data;
- signed order;
-};
-
-struct hb_face_builder_data_t
-{
- hb_hashmap_t<hb_tag_t, face_table_info_t> tables;
-};
-
-static int compare_entries (const void* pa, const void* pb)
-{
- const auto& a = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pa;
- const auto& b = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pb;
-
- /* Order by blob size first (smallest to largest) and then table tag */
-
- if (a.second.order != b.second.order)
- return a.second.order < b.second.order ? -1 : +1;
-
- if (a.second.data->length != b.second.data->length)
- return a.second.data->length < b.second.data->length ? -1 : +1;
-
- return a.first < b.first ? -1 : a.first == b.first ? 0 : +1;
-}
-
-static hb_face_builder_data_t *
-_hb_face_builder_data_create ()
-{
- hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t));
- if (unlikely (!data))
- return nullptr;
-
- data->tables.init ();
-
- return data;
-}
-
-static void
-_hb_face_builder_data_destroy (void *user_data)
-{
- hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
-
- for (auto info : data->tables.values())
- hb_blob_destroy (info.data);
-
- data->tables.fini ();
-
- hb_free (data);
-}
-
-static hb_blob_t *
-_hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
-{
-
- unsigned int table_count = data->tables.get_population ();
- unsigned int face_length = table_count * 16 + 12;
-
- for (auto info : data->tables.values())
- face_length += hb_ceil_to_4 (hb_blob_get_length (info.data));
-
- char *buf = (char *) hb_malloc (face_length);
- if (unlikely (!buf))
- return nullptr;
-
- hb_serialize_context_t c (buf, face_length);
- c.propagate_error (data->tables);
- OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
-
- bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' '))
- || data->tables.has (HB_TAG ('C','F','F','2')));
- hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
-
- // Sort the tags so that produced face is deterministic.
- hb_vector_t<hb_pair_t <hb_tag_t, face_table_info_t>> sorted_entries;
- data->tables.iter () | hb_sink (sorted_entries);
- if (unlikely (sorted_entries.in_error ()))
- {
- hb_free (buf);
- return nullptr;
- }
-
- sorted_entries.qsort (compare_entries);
-
- bool ret = f->serialize_single (&c,
- sfnt_tag,
- + sorted_entries.iter()
- | hb_map ([&] (hb_pair_t<hb_tag_t, face_table_info_t> _) {
- return hb_pair_t<hb_tag_t, hb_blob_t*> (_.first, _.second.data);
- }));
-
- c.end_serialize ();
-
- if (unlikely (!ret))
- {
- hb_free (buf);
- return nullptr;
- }
-
- return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free);
-}
-
-static hb_blob_t *
-_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
- hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
-
- if (!tag)
- return _hb_face_builder_data_reference_blob (data);
-
- return hb_blob_reference (data->tables[tag].data);
-}
-
-
-/**
- * hb_face_builder_create:
- *
- * Creates a #hb_face_t that can be used with hb_face_builder_add_table().
- * After tables are added to the face, it can be compiled to a binary
- * font file by calling hb_face_reference_blob().
- *
- * Return value: (transfer full): New face.
- *
- * Since: 1.9.0
- **/
-hb_face_t *
-hb_face_builder_create ()
-{
- hb_face_builder_data_t *data = _hb_face_builder_data_create ();
- if (unlikely (!data)) return hb_face_get_empty ();
-
- return hb_face_create_for_tables (_hb_face_builder_reference_table,
- data,
- _hb_face_builder_data_destroy);
-}
-
-/**
- * hb_face_builder_add_table:
- * @face: A face object created with hb_face_builder_create()
- * @tag: The #hb_tag_t of the table to add
- * @blob: The blob containing the table data to add
- *
- * Add table for @tag with data provided by @blob to the face. @face must
- * be created using hb_face_builder_create().
- *
- * Since: 1.9.0
- **/
-hb_bool_t
-hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
-{
- if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
- return false;
-
- if (tag == HB_MAP_VALUE_INVALID)
- return false;
-
- hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
-
- hb_blob_t* previous = data->tables.get (tag).data;
- if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1}))
- {
- hb_blob_destroy (blob);
- return false;
- }
-
- hb_blob_destroy (previous);
- return true;
-}
-
-/**
- * hb_face_builder_sort_tables:
- * @face: A face object created with hb_face_builder_create()
- * @tags: (array zero-terminated=1): ordered list of table tags terminated by
- * %HB_TAG_NONE
- *
- * Set the ordering of tables for serialization. Any tables not
- * specified in the tags list will be ordered after the tables in
- * tags, ordered by the default sort ordering.
- *
- * Since: 5.3.0
- **/
-void
-hb_face_builder_sort_tables (hb_face_t *face,
- const hb_tag_t *tags)
-{
- if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
- return;
-
- hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
-
- // Sort all unspecified tables after any specified tables.
- for (auto& info : data->tables.values_ref())
- info.order = (unsigned) -1;
-
- signed order = 0;
- for (const hb_tag_t* tag = tags;
- *tag;
- tag++)
- {
- face_table_info_t* info;
- if (!data->tables.has (*tag, &info)) continue;
- info->order = order++;
- }
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
index aff3ff0d07c..43e7b1cb3ff 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
@@ -26,86 +26,86 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_FACE_HH
-#define HB_FACE_HH
+#ifndef HB_FACE_PRIVATE_HH
+#define HB_FACE_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-shaper.hh"
-#include "hb-shape-plan.hh"
-#include "hb-ot-face.hh"
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
/*
* hb_face_t
*/
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, face);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-
-struct hb_face_t
-{
+struct hb_face_t {
hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
hb_reference_table_func_t reference_table_func;
void *user_data;
hb_destroy_func_t destroy;
unsigned int index; /* Face index in a collection, zero-based. */
- mutable hb_atomic_int_t upem; /* Units-per-EM. */
- mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */
+ mutable unsigned int upem; /* Units-per-EM. */
+ mutable unsigned int num_glyphs; /* Number of glyphs. */
+
+ struct hb_shaper_data_t shaper_data; /* Various shaper data. */
- hb_shaper_object_dataset_t<hb_face_t> data;/* Various shaper data. */
- hb_ot_face_t table; /* All the face's tables. */
+ /* Various non-shaping data. */
+ /* ... */
/* Cache */
- struct plan_node_t
- {
+ struct plan_node_t {
hb_shape_plan_t *shape_plan;
plan_node_t *next;
- };
-#ifndef HB_NO_SHAPER
- hb_atomic_ptr_t<plan_node_t> shape_plans;
-#endif
+ } *shape_plans;
- hb_blob_t *reference_table (hb_tag_t tag) const
+
+ inline hb_blob_t *reference_table (hb_tag_t tag) const
{
hb_blob_t *blob;
if (unlikely (!reference_table_func))
return hb_blob_get_empty ();
- blob = reference_table_func (/*Oh, well.*/const_cast<hb_face_t *> (this), tag, user_data);
+ blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
if (unlikely (!blob))
return hb_blob_get_empty ();
return blob;
}
- unsigned int get_upem () const
+ inline HB_PURE_FUNC unsigned int get_upem (void) const
{
- unsigned int ret = upem;
- if (unlikely (!ret))
- {
- return load_upem ();
- }
- return ret;
+ if (unlikely (!upem))
+ load_upem ();
+ return upem;
}
- unsigned int get_num_glyphs () const
+ inline unsigned int get_num_glyphs (void) const
{
- unsigned int ret = num_glyphs;
- if (unlikely (ret == UINT_MAX))
- return load_num_glyphs ();
- return ret;
+ if (unlikely (num_glyphs == (unsigned int) -1))
+ load_num_glyphs ();
+ return num_glyphs;
}
private:
- HB_INTERNAL unsigned int load_upem () const;
- HB_INTERNAL unsigned int load_num_glyphs () const;
+ HB_INTERNAL void load_upem (void) const;
+ HB_INTERNAL void load_num_glyphs (void) const;
};
-DECLARE_NULL_INSTANCE (hb_face_t);
+
+extern HB_INTERNAL const hb_face_t _hb_face_nil;
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
-#endif /* HB_FACE_HH */
+#endif /* HB_FACE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
index e340710586c..26fddbe5292 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -26,70 +26,23 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-face.hh"
-#include "hb-blob.hh"
-#include "hb-open-file.hh"
-#include "hb-ot-face.hh"
-#include "hb-ot-cmap-table.hh"
+#include "hb-face-private.hh"
+#include "hb-open-file-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
-/**
- * SECTION:hb-face
- * @title: hb-face
- * @short_description: Font face objects
- * @include: hb.h
- *
- * A font face is an object that represents a single face from within a
- * font family.
- *
- * More precisely, a font face represents a single face in a binary font file.
- * Font faces are typically built from a binary blob and a face index.
- * Font faces are used to create fonts.
- *
- * A font face can be created from a binary blob using hb_face_create().
- * The face index is used to select a face from a binary blob that contains
- * multiple faces. For example, a binary blob that contains both a regular
- * and a bold face can be used to create two font faces, one for each face
- * index.
- **/
-
-
-/**
- * hb_face_count:
- * @blob: a blob.
- *
- * Fetches the number of faces in a blob.
- *
- * Return value: Number of faces in @blob
- *
- * Since: 1.7.7
- **/
-unsigned int
-hb_face_count (hb_blob_t *blob)
-{
- if (unlikely (!blob))
- return 0;
-
- /* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */
- /* Make API signature const after. */
- hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
- const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
- unsigned int ret = ot.get_face_count ();
- hb_blob_destroy (sanitized);
-
- return ret;
-}
-
/*
* hb_face_t
*/
-DEFINE_NULL_INSTANCE (hb_face_t) =
-{
+const hb_face_t _hb_face_nil = {
HB_OBJECT_HEADER_STATIC,
+ true, /* immutable */
+
nullptr, /* reference_table_func */
nullptr, /* user_data */
nullptr, /* destroy */
@@ -98,25 +51,25 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
1000, /* upem */
0, /* num_glyphs */
- /* Zero for the rest is fine. */
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ },
+
+ nullptr, /* shape_plans */
};
/**
* hb_face_create_for_tables:
- * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function
- * @user_data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- *
- * Variant of hb_face_create(), built for those cases where it is more
- * convenient to provide data for individual tables instead of the whole font
- * data. With the caveat that hb_face_get_table_tags() does not currently work
- * with faces created this way.
+ * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Creates a new face object from the specified @user_data and @reference_table_func,
- * with the @destroy callback.
+ *
*
- * Return value: (transfer full): The new face object
+ * Return value: (transfer full)
*
* Since: 0.9.2
**/
@@ -137,10 +90,8 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
face->user_data = user_data;
face->destroy = destroy;
- face->num_glyphs = -1;
-
- face->data.init0 (face);
- face->table.init0 (face);
+ face->upem = 0;
+ face->num_glyphs = (unsigned int) -1;
return face;
}
@@ -148,7 +99,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
typedef struct hb_face_for_data_closure_t {
hb_blob_t *blob;
- uint16_t index;
+ unsigned int index;
} hb_face_for_data_closure_t;
static hb_face_for_data_closure_t *
@@ -156,12 +107,12 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
{
hb_face_for_data_closure_t *closure;
- closure = (hb_face_for_data_closure_t *) hb_calloc (1, sizeof (hb_face_for_data_closure_t));
+ closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t));
if (unlikely (!closure))
return nullptr;
closure->blob = blob;
- closure->index = (uint16_t) (index & 0xFFFFu);
+ closure->index = index;
return closure;
}
@@ -172,7 +123,7 @@ _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);
- hb_free (closure);
+ free (closure);
}
static hb_blob_t *
@@ -183,38 +134,24 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
if (tag == HB_TAG_NONE)
return hb_blob_reference (data->blob);
- const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
- unsigned int base_offset;
- const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index, &base_offset);
+ const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+ const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
- hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, base_offset + table.offset, table.length);
+ hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
return blob;
}
/**
- * hb_face_create:
- * @blob: #hb_blob_t to work upon
- * @index: The index of the face within @blob
- *
- * Constructs a new face object from the specified blob and
- * a face index into that blob.
+ * hb_face_create: (Xconstructor)
+ * @blob:
+ * @index:
*
- * The face index is used for blobs of file formats such as TTC and
- * DFont that can contain more than one face. Face indices within
- * such collections are zero-based.
+ *
*
- * <note>Note: If the blob font format is not a collection, @index
- * is ignored. Otherwise, only the lower 16-bits of @index are used.
- * The unmodified @index can be accessed via hb_face_get_index().</note>
- *
- * <note>Note: The high 16-bits of @index, if non-zero, are used by
- * hb_font_create() to load named-instances in variable fonts. See
- * hb_font_create() for details.</note>
- *
- * Return value: (transfer full): The new face object
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -227,15 +164,10 @@ hb_face_create (hb_blob_t *blob,
if (unlikely (!blob))
blob = hb_blob_get_empty ();
- blob = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
-
- hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (blob, index);
+ hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
if (unlikely (!closure))
- {
- hb_blob_destroy (blob);
return hb_face_get_empty ();
- }
face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
closure,
@@ -249,26 +181,26 @@ hb_face_create (hb_blob_t *blob,
/**
* hb_face_get_empty:
*
- * Fetches the singleton empty face object.
+ *
*
- * Return value: (transfer full): The empty face object
+ * Return value: (transfer full)
*
* Since: 0.9.2
**/
hb_face_t *
-hb_face_get_empty ()
+hb_face_get_empty (void)
{
- return const_cast<hb_face_t *> (&Null (hb_face_t));
+ return const_cast<hb_face_t *> (&_hb_face_nil);
}
/**
* hb_face_reference: (skip)
- * @face: A face object
+ * @face: a face.
*
- * Increases the reference count on a face object.
+ *
*
- * Return value: The @face object
+ * Return value:
*
* Since: 0.9.2
**/
@@ -280,11 +212,9 @@ hb_face_reference (hb_face_t *face)
/**
* hb_face_destroy: (skip)
- * @face: A face object
+ * @face: a face.
*
- * Decreases the reference count on a face object. When the
- * reference count reaches zero, the face is destroyed,
- * freeing all memory.
+ *
*
* Since: 0.9.2
**/
@@ -293,36 +223,35 @@ hb_face_destroy (hb_face_t *face)
{
if (!hb_object_destroy (face)) return;
-#ifndef HB_NO_SHAPER
for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
{
hb_face_t::plan_node_t *next = node->next;
hb_shape_plan_destroy (node->shape_plan);
- hb_free (node);
+ free (node);
node = next;
}
-#endif
- face->data.fini ();
- face->table.fini ();
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
if (face->destroy)
face->destroy (face->user_data);
- hb_free (face);
+ free (face);
}
/**
* hb_face_set_user_data: (skip)
- * @face: A face object
- * @key: The user-data key to set
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @face: a face.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the given face object.
+ *
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -338,18 +267,17 @@ hb_face_set_user_data (hb_face_t *face,
/**
* hb_face_get_user_data: (skip)
- * @face: A face object
- * @key: The user-data key to query
+ * @face: a face.
+ * @key:
*
- * Fetches the user data associated with the specified key,
- * attached to the specified face object.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_face_get_user_data (const hb_face_t *face,
+hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (face, key);
@@ -357,69 +285,63 @@ hb_face_get_user_data (const hb_face_t *face,
/**
* hb_face_make_immutable:
- * @face: A face object
+ * @face: a face.
*
- * Makes the given face object immutable.
+ *
*
* Since: 0.9.2
**/
void
hb_face_make_immutable (hb_face_t *face)
{
- if (hb_object_is_immutable (face))
+ if (unlikely (hb_object_is_inert (face)))
return;
- hb_object_make_immutable (face);
+ face->immutable = true;
}
/**
* hb_face_is_immutable:
- * @face: A face object
+ * @face: a face.
*
- * Tests whether the given face object is immutable.
+ *
*
- * Return value: `true` is @face is immutable, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_face_is_immutable (const hb_face_t *face)
+hb_face_is_immutable (hb_face_t *face)
{
- return hb_object_is_immutable (face);
+ return face->immutable;
}
/**
* hb_face_reference_table:
- * @face: A face object
- * @tag: The #hb_tag_t of the table to query
+ * @face: a face.
+ * @tag:
*
- * Fetches a reference to the specified table within
- * the specified face.
+ *
*
- * Return value: (transfer full): A pointer to the @tag table within @face
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_blob_t *
-hb_face_reference_table (const hb_face_t *face,
- hb_tag_t tag)
+hb_face_reference_table (hb_face_t *face,
+ hb_tag_t tag)
{
- if (unlikely (tag == HB_TAG_NONE))
- return hb_blob_get_empty ();
-
return face->reference_table (tag);
}
/**
* hb_face_reference_blob:
- * @face: A face object
+ * @face: a face.
*
- * Fetches a pointer to the binary blob that contains the
- * specified face. Returns an empty blob if referencing face data is not
- * possible.
+ *
*
- * Return value: (transfer full): A pointer to the blob for @face
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -431,14 +353,10 @@ hb_face_reference_blob (hb_face_t *face)
/**
* hb_face_set_index:
- * @face: A face object
- * @index: The index to assign
- *
- * Assigns the specified face-index to @face. Fails if the
- * face is immutable.
+ * @face: a face.
+ * @index:
*
- * <note>Note: changing the index has no effect on the face itself
- * This only changes the value returned by hb_face_get_index().</note>
+ *
*
* Since: 0.9.2
**/
@@ -446,7 +364,7 @@ void
hb_face_set_index (hb_face_t *face,
unsigned int index)
{
- if (hb_object_is_immutable (face))
+ if (face->immutable)
return;
face->index = index;
@@ -454,30 +372,26 @@ hb_face_set_index (hb_face_t *face,
/**
* hb_face_get_index:
- * @face: A face object
- *
- * Fetches the face-index corresponding to the given face.
+ * @face: a face.
*
- * <note>Note: face indices within a collection are zero-based.</note>
+ *
*
- * Return value: The index of @face.
+ * Return value:
*
* Since: 0.9.2
**/
unsigned int
-hb_face_get_index (const hb_face_t *face)
+hb_face_get_index (hb_face_t *face)
{
return face->index;
}
/**
* hb_face_set_upem:
- * @face: A face object
- * @upem: The units-per-em value to assign
+ * @face: a face.
+ * @upem:
*
- * Sets the units-per-em (upem) for a face object to the specified value.
- *
- * This API is used in rare circumstances.
+ *
*
* Since: 0.9.2
**/
@@ -485,7 +399,7 @@ void
hb_face_set_upem (hb_face_t *face,
unsigned int upem)
{
- if (hb_object_is_immutable (face))
+ if (face->immutable)
return;
face->upem = upem;
@@ -493,31 +407,35 @@ hb_face_set_upem (hb_face_t *face,
/**
* hb_face_get_upem:
- * @face: A face object
- *
- * Fetches the units-per-em (UPEM) value of the specified face object.
+ * @face: a face.
*
- * Typical UPEM values for fonts are 1000, or 2048, but any value
- * in between 16 and 16,384 is allowed for OpenType fonts.
+ *
*
- * Return value: The upem value of @face
+ * Return value:
*
* Since: 0.9.2
**/
unsigned int
-hb_face_get_upem (const hb_face_t *face)
+hb_face_get_upem (hb_face_t *face)
{
return face->get_upem ();
}
+void
+hb_face_t::load_upem (void) const
+{
+ hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
+ const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
+ upem = head_table->get_upem ();
+ hb_blob_destroy (head_blob);
+}
+
/**
* hb_face_set_glyph_count:
- * @face: A face object
- * @glyph_count: The glyph-count value to assign
+ * @face: a face.
+ * @glyph_count:
*
- * Sets the glyph count for a face object to the specified value.
- *
- * This API is used in rare circumstances.
+ *
*
* Since: 0.9.7
**/
@@ -525,7 +443,7 @@ void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count)
{
- if (hb_object_is_immutable (face))
+ if (face->immutable)
return;
face->num_glyphs = glyph_count;
@@ -533,42 +451,46 @@ hb_face_set_glyph_count (hb_face_t *face,
/**
* hb_face_get_glyph_count:
- * @face: A face object
+ * @face: a face.
*
- * Fetches the glyph-count value of the specified face object.
+ *
*
- * Return value: The glyph-count value of @face
+ * Return value:
*
* Since: 0.9.7
**/
unsigned int
-hb_face_get_glyph_count (const hb_face_t *face)
+hb_face_get_glyph_count (hb_face_t *face)
{
return face->get_num_glyphs ();
}
+void
+hb_face_t::load_num_glyphs (void) const
+{
+ hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
+ const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
+ num_glyphs = maxp_table->get_num_glyphs ();
+ hb_blob_destroy (maxp_blob);
+}
+
/**
* hb_face_get_table_tags:
- * @face: A face object
- * @start_offset: The index of first table tag to retrieve
- * @table_count: (inout): Input = the maximum number of table tags to return;
- * Output = the actual number of table tags returned (may be zero)
- * @table_tags: (out) (array length=table_count): The array of table tags found
+ * @face: a face.
*
- * Fetches a list of all table tags for a face, if possible. The list returned will
- * begin at the offset provided
+ * Retrieves table tags for a face, if possible.
*
- * Return value: Total number of tables, or zero if it is not possible to list
+ * Return value: total number of tables, or 0 if not possible to list.
*
* Since: 1.6.0
**/
unsigned int
-hb_face_get_table_tags (const hb_face_t *face,
+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_destroy_func_t) _hb_face_for_data_closure_destroy)
+ if (face->destroy != _hb_face_for_data_closure_destroy)
{
if (table_count)
*table_count = 0;
@@ -577,88 +499,8 @@ hb_face_get_table_tags (const hb_face_t *face,
hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
- const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
+ 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);
}
-
-
-/*
- * Character set.
- */
-
-
-#ifndef HB_NO_FACE_COLLECT_UNICODES
-/**
- * hb_face_collect_unicodes:
- * @face: A face object
- * @out: (out): The set to add Unicode characters to
- *
- * Collects all of the Unicode characters covered by @face and adds
- * them to the #hb_set_t set @out.
- *
- * Since: 1.9.0
- */
-void
-hb_face_collect_unicodes (hb_face_t *face,
- hb_set_t *out)
-{
- face->table.cmap->collect_unicodes (out, face->get_num_glyphs ());
-}
-/**
- * hb_face_collect_nominal_glyph_mapping:
- * @face: A face object
- * @mapping: (out): The map to add Unicode-to-glyph mapping to
- * @unicodes: (nullable) (out): The set to add Unicode characters to, or `NULL`
- *
- * Collects the mapping from Unicode characters to nominal glyphs of the @face,
- * and optionally all of the Unicode characters covered by @face.
- *
- * Since: 7.0.0
- */
-void
-hb_face_collect_nominal_glyph_mapping (hb_face_t *face,
- hb_map_t *mapping,
- hb_set_t *unicodes)
-{
- hb_set_t stack_unicodes;
- if (!unicodes)
- unicodes = &stack_unicodes;
- face->table.cmap->collect_mapping (unicodes, mapping, face->get_num_glyphs ());
-}
-/**
- * hb_face_collect_variation_selectors:
- * @face: A face object
- * @out: (out): The set to add Variation Selector characters to
- *
- * Collects all Unicode "Variation Selector" characters covered by @face and adds
- * them to the #hb_set_t set @out.
- *
- * Since: 1.9.0
- */
-void
-hb_face_collect_variation_selectors (hb_face_t *face,
- hb_set_t *out)
-{
- face->table.cmap->collect_variation_selectors (out);
-}
-/**
- * hb_face_collect_variation_unicodes:
- * @face: A face object
- * @variation_selector: The Variation Selector to query
- * @out: (out): The set to add Unicode characters to
- *
- * Collects all Unicode characters for @variation_selector covered by @face and adds
- * them to the #hb_set_t set @out.
- *
- * Since: 1.9.0
- */
-void
-hb_face_collect_variation_unicodes (hb_face_t *face,
- hb_codepoint_t variation_selector,
- hb_set_t *out)
-{
- face->table.cmap->collect_variation_unicodes (variation_selector, out);
-}
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h
index 2e54ccf13b7..9842d52b650 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -33,45 +33,20 @@
#include "hb-common.h"
#include "hb-blob.h"
-#include "hb-map.h"
-#include "hb-set.h"
HB_BEGIN_DECLS
-HB_EXTERN unsigned int
-hb_face_count (hb_blob_t *blob);
-
-
/*
* hb_face_t
*/
-/**
- * hb_face_t:
- *
- * Data type for holding font faces.
- *
- **/
typedef struct hb_face_t hb_face_t;
HB_EXTERN hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index);
-/**
- * hb_reference_table_func_t:
- * @face: an #hb_face_t to reference table for
- * @tag: the tag of the table to reference
- * @user_data: User data pointer passed by the caller
- *
- * Callback function for hb_face_create_for_tables().
- *
- * Return value: (transfer full): A pointer to the @tag table within @face
- *
- * Since: 0.9.2
- */
-
typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
/* calls destroy() when not needing user_data anymore */
@@ -96,20 +71,21 @@ hb_face_set_user_data (hb_face_t *face,
hb_destroy_func_t destroy,
hb_bool_t replace);
+
HB_EXTERN void *
-hb_face_get_user_data (const hb_face_t *face,
+hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key);
HB_EXTERN void
hb_face_make_immutable (hb_face_t *face);
HB_EXTERN hb_bool_t
-hb_face_is_immutable (const hb_face_t *face);
+hb_face_is_immutable (hb_face_t *face);
HB_EXTERN hb_blob_t *
-hb_face_reference_table (const hb_face_t *face,
- hb_tag_t tag);
+hb_face_reference_table (hb_face_t *face,
+ hb_tag_t tag);
HB_EXTERN hb_blob_t *
hb_face_reference_blob (hb_face_t *face);
@@ -119,69 +95,28 @@ hb_face_set_index (hb_face_t *face,
unsigned int index);
HB_EXTERN unsigned int
-hb_face_get_index (const hb_face_t *face);
+hb_face_get_index (hb_face_t *face);
HB_EXTERN void
hb_face_set_upem (hb_face_t *face,
unsigned int upem);
HB_EXTERN unsigned int
-hb_face_get_upem (const hb_face_t *face);
+hb_face_get_upem (hb_face_t *face);
HB_EXTERN void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count);
HB_EXTERN unsigned int
-hb_face_get_glyph_count (const hb_face_t *face);
+hb_face_get_glyph_count (hb_face_t *face);
HB_EXTERN unsigned int
-hb_face_get_table_tags (const hb_face_t *face,
+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 */);
-
-/*
- * Character set.
- */
-
-HB_EXTERN void
-hb_face_collect_unicodes (hb_face_t *face,
- hb_set_t *out);
-
-HB_EXTERN void
-hb_face_collect_nominal_glyph_mapping (hb_face_t *face,
- hb_map_t *mapping,
- hb_set_t *unicodes);
-
-HB_EXTERN void
-hb_face_collect_variation_selectors (hb_face_t *face,
- hb_set_t *out);
-
-HB_EXTERN void
-hb_face_collect_variation_unicodes (hb_face_t *face,
- hb_codepoint_t variation_selector,
- hb_set_t *out);
-
-
-/*
- * Builder face.
- */
-
-HB_EXTERN hb_face_t *
-hb_face_builder_create (void);
-
-HB_EXTERN hb_bool_t
-hb_face_builder_add_table (hb_face_t *face,
- hb_tag_t tag,
- hb_blob_t *blob);
-
-HB_EXTERN void
-hb_face_builder_sort_tables (hb_face_t *face,
- const hb_tag_t *tags);
-
-
HB_END_DECLS
#endif /* HB_FACE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
index c54ad8764bc..3f09c3f5306 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -24,24 +24,28 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-shaper-impl.hh"
+#define HB_SHAPER fallback
+#include "hb-shaper-impl-private.hh"
+
+
+HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font)
-#ifndef HB_NO_FALLBACK_SHAPE
/*
* shaper face data
*/
-struct hb_fallback_face_data_t {};
+struct hb_fallback_shaper_face_data_t {};
-hb_fallback_face_data_t *
+hb_fallback_shaper_face_data_t *
_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
{
- return (hb_fallback_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_fallback_shaper_face_data_destroy (hb_fallback_face_data_t *data HB_UNUSED)
+_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
{
}
@@ -50,16 +54,38 @@ _hb_fallback_shaper_face_data_destroy (hb_fallback_face_data_t *data HB_UNUSED)
* shaper font data
*/
-struct hb_fallback_font_data_t {};
+struct hb_fallback_shaper_font_data_t {};
-hb_fallback_font_data_t *
+hb_fallback_shaper_font_data_t *
_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
{
- return (hb_fallback_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_fallback_shaper_shape_plan_data_t {};
+
+hb_fallback_shaper_shape_plan_data_t *
+_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED,
+ const int *coords HB_UNUSED,
+ unsigned int num_coords HB_UNUSED)
+{
+ return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_fallback_shaper_font_data_destroy (hb_fallback_font_data_t *data HB_UNUSED)
+_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
{
}
@@ -75,6 +101,16 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
+ /* TODO
+ *
+ * - Apply fallback kern.
+ * - Handle Variation Selectors?
+ * - Apply normalization?
+ *
+ * This will make the fallback shaper into a dumb "TrueType"
+ * shaper which many people unfortunately still request.
+ */
+
hb_codepoint_t space;
bool has_space = (bool) font->get_nominal_glyph (' ', &space);
@@ -107,9 +143,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
if (HB_DIRECTION_IS_BACKWARD (direction))
hb_buffer_reverse (buffer);
- buffer->clear_glyph_flags ();
+ buffer->safe_to_break_all ();
return true;
}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
new file mode 100644
index 00000000000..d2801fb86ec
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -0,0 +1,555 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2011 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
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FONT_PRIVATE_HH
+#define HB_FONT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-object-private.hh"
+#include "hb-face-private.hh"
+#include "hb-shaper-private.hh"
+
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
+ HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
+ HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
+ HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
+ HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_name) \
+ HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
+ /* ^--- Add new callbacks here */
+
+struct hb_font_funcs_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
+
+ struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } user_data;
+
+ struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } destroy;
+
+ /* Don't access these directly. Call font->get_*() instead. */
+ union get_t {
+ struct get_funcs_t {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ } f;
+ void (*array[VAR]) (void);
+ } get;
+};
+
+
+
+/*
+ * hb_font_t
+ */
+
+struct hb_font_t {
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_bool_t immutable;
+
+ hb_font_t *parent;
+ hb_face_t *face;
+
+ int x_scale;
+ int y_scale;
+
+ unsigned int x_ppem;
+ unsigned int y_ppem;
+
+ float ptem;
+
+ /* Font variation coordinates. */
+ unsigned int num_coords;
+ int *coords;
+
+ hb_font_funcs_t *klass;
+ void *user_data;
+ hb_destroy_func_t destroy;
+
+ struct hb_shaper_data_t shaper_data;
+
+
+ /* Convert from font-space to user-space */
+ inline int dir_scale (hb_direction_t direction)
+ { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
+ inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
+ inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
+ inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
+ inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
+ inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
+ { return em_scale (v, dir_scale (direction)); }
+
+ /* Convert from parent-font user-space to our user-space */
+ inline hb_position_t parent_scale_x_distance (hb_position_t v) {
+ if (unlikely (parent && parent->x_scale != x_scale))
+ return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
+ return v;
+ }
+ inline hb_position_t parent_scale_y_distance (hb_position_t v) {
+ if (unlikely (parent && parent->y_scale != y_scale))
+ return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
+ return v;
+ }
+ inline hb_position_t parent_scale_x_position (hb_position_t v) {
+ return parent_scale_x_distance (v);
+ }
+ inline hb_position_t parent_scale_y_position (hb_position_t v) {
+ return parent_scale_y_distance (v);
+ }
+
+ inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
+ *x = parent_scale_x_distance (*x);
+ *y = parent_scale_y_distance (*y);
+ }
+ inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
+ *x = parent_scale_x_position (*x);
+ *y = parent_scale_y_position (*y);
+ }
+
+
+ /* Public getters */
+
+ HB_INTERNAL bool has_func (unsigned int i);
+
+ /* has_* ... */
+#define HB_FONT_FUNC_IMPLEMENT(name) \
+ bool \
+ has_##name##_func (void) \
+ { \
+ hb_font_funcs_t *funcs = this->klass; \
+ unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
+ return has_func (i); \
+ }
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+
+ inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
+ {
+ memset (extents, 0, sizeof (*extents));
+ return klass->get.f.font_h_extents (this, user_data,
+ extents,
+ klass->user_data.font_h_extents);
+ }
+ inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
+ {
+ memset (extents, 0, sizeof (*extents));
+ return klass->get.f.font_v_extents (this, user_data,
+ extents,
+ klass->user_data.font_v_extents);
+ }
+
+ inline bool has_glyph (hb_codepoint_t unicode)
+ {
+ hb_codepoint_t glyph;
+ return get_nominal_glyph (unicode, &glyph);
+ }
+
+ inline hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t *glyph)
+ {
+ *glyph = 0;
+ return klass->get.f.nominal_glyph (this, user_data,
+ unicode, glyph,
+ klass->user_data.nominal_glyph);
+ }
+
+ inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph)
+ {
+ *glyph = 0;
+ return klass->get.f.variation_glyph (this, user_data,
+ unicode, variation_selector, glyph,
+ klass->user_data.variation_glyph);
+ }
+
+ inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
+ {
+ return klass->get.f.glyph_h_advance (this, user_data,
+ glyph,
+ klass->user_data.glyph_h_advance);
+ }
+
+ inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
+ {
+ return klass->get.f.glyph_v_advance (this, user_data,
+ glyph,
+ klass->user_data.glyph_v_advance);
+ }
+
+ inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.f.glyph_h_origin (this, user_data,
+ glyph, x, y,
+ klass->user_data.glyph_h_origin);
+ }
+
+ inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.f.glyph_v_origin (this, user_data,
+ glyph, x, y,
+ klass->user_data.glyph_v_origin);
+ }
+
+ inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ {
+ return klass->get.f.glyph_h_kerning (this, user_data,
+ left_glyph, right_glyph,
+ klass->user_data.glyph_h_kerning);
+ }
+
+ inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
+ {
+ return klass->get.f.glyph_v_kerning (this, user_data,
+ top_glyph, bottom_glyph,
+ klass->user_data.glyph_v_kerning);
+ }
+
+ inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents)
+ {
+ memset (extents, 0, sizeof (*extents));
+ return klass->get.f.glyph_extents (this, user_data,
+ glyph,
+ extents,
+ klass->user_data.glyph_extents);
+ }
+
+ inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = *y = 0;
+ return klass->get.f.glyph_contour_point (this, user_data,
+ glyph, point_index,
+ x, y,
+ klass->user_data.glyph_contour_point);
+ }
+
+ inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
+ char *name, unsigned int size)
+ {
+ if (size) *name = '\0';
+ return klass->get.f.glyph_name (this, user_data,
+ glyph,
+ name, size,
+ klass->user_data.glyph_name);
+ }
+
+ inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+ {
+ *glyph = 0;
+ if (len == -1) len = strlen (name);
+ return klass->get.f.glyph_from_name (this, user_data,
+ name, len,
+ glyph,
+ klass->user_data.glyph_from_name);
+ }
+
+
+ /* A bit higher-level, and with fallback */
+
+ inline void get_h_extents_with_fallback (hb_font_extents_t *extents)
+ {
+ if (!get_font_h_extents (extents))
+ {
+ extents->ascender = y_scale * .8;
+ extents->descender = extents->ascender - y_scale;
+ extents->line_gap = 0;
+ }
+ }
+ inline void get_v_extents_with_fallback (hb_font_extents_t *extents)
+ {
+ if (!get_font_v_extents (extents))
+ {
+ extents->ascender = x_scale / 2;
+ extents->descender = extents->ascender - x_scale;
+ extents->line_gap = 0;
+ }
+ }
+
+ inline void get_extents_for_direction (hb_direction_t direction,
+ hb_font_extents_t *extents)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+ get_h_extents_with_fallback (extents);
+ else
+ get_v_extents_with_fallback (extents);
+ }
+
+ inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+ *x = get_glyph_h_advance (glyph);
+ *y = 0;
+ } else {
+ *x = 0;
+ *y = get_glyph_v_advance (glyph);
+ }
+ }
+
+ inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ *x = get_glyph_h_advance (glyph) / 2;
+
+ /* TODO cache this somehow?! */
+ hb_font_extents_t extents;
+ get_h_extents_with_fallback (&extents);
+ *y = extents.ascender;
+ }
+
+ inline void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (!get_glyph_h_origin (glyph, x, y) &&
+ get_glyph_v_origin (glyph, x, y))
+ {
+ hb_position_t dx, dy;
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+ *x -= dx; *y -= dy;
+ }
+ }
+ inline void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (!get_glyph_v_origin (glyph, x, y) &&
+ get_glyph_h_origin (glyph, x, y))
+ {
+ hb_position_t dx, dy;
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+ *x += dx; *y += dy;
+ }
+ }
+
+ inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+ get_glyph_h_origin_with_fallback (glyph, x, y);
+ else
+ get_glyph_v_origin_with_fallback (glyph, x, y);
+ }
+
+ inline void add_glyph_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
+
+ *x += origin_x;
+ *y += origin_y;
+ }
+ inline void add_glyph_v_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
+
+ *x += origin_x;
+ *y += origin_y;
+ }
+ inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+ *x += origin_x;
+ *y += origin_y;
+ }
+
+ inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
+
+ *x -= origin_x;
+ *y -= origin_y;
+ }
+ inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
+
+ *x -= origin_x;
+ *y -= origin_y;
+ }
+ inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_position_t origin_x, origin_y;
+
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+ *x -= origin_x;
+ *y -= origin_y;
+ }
+
+ inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+ *x = get_glyph_h_kerning (first_glyph, second_glyph);
+ *y = 0;
+ } else {
+ *x = 0;
+ *y = get_glyph_v_kerning (first_glyph, second_glyph);
+ }
+ }
+
+ inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_glyph_extents_t *extents)
+ {
+ hb_bool_t ret = get_glyph_extents (glyph, extents);
+
+ if (ret)
+ subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
+
+ return ret;
+ }
+
+ inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
+ {
+ hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
+
+ if (ret)
+ subtract_glyph_origin_for_direction (glyph, direction, x, y);
+
+ return ret;
+ }
+
+ /* Generates gidDDD if glyph has no name. */
+ inline void
+ glyph_to_string (hb_codepoint_t glyph,
+ char *s, unsigned int size)
+ {
+ if (get_glyph_name (glyph, s, size)) return;
+
+ if (size && snprintf (s, size, "gid%u", glyph) < 0)
+ *s = '\0';
+ }
+
+ /* Parses gidDDD and uniUUUU strings automatically. */
+ inline hb_bool_t
+ glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph)
+ {
+ if (get_glyph_from_name (s, len, glyph)) return true;
+
+ if (len == -1) len = strlen (s);
+
+ /* Straight glyph index. */
+ if (hb_codepoint_parse (s, len, 10, glyph))
+ return true;
+
+ if (len > 3)
+ {
+ /* gidDDD syntax for glyph indices. */
+ if (0 == strncmp (s, "gid", 3) &&
+ hb_codepoint_parse (s + 3, len - 3, 10, glyph))
+ return true;
+
+ /* uniUUUU and other Unicode character indices. */
+ hb_codepoint_t unichar;
+ if (0 == strncmp (s, "uni", 3) &&
+ hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
+ get_nominal_glyph (unichar, glyph))
+ return true;
+ }
+
+ return false;
+ }
+
+ inline hb_position_t em_scale (int16_t v, int scale)
+ {
+ int upem = face->get_upem ();
+ int64_t scaled = v * (int64_t) scale;
+ scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
+ return (hb_position_t) (scaled / upem);
+ }
+ inline hb_position_t em_scalef (float v, int scale)
+ {
+ return (hb_position_t) (v * scale / face->get_upem ());
+ }
+};
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_FONT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
index 688513112a7..f3534b686bf 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
@@ -26,45 +26,9 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-font.hh"
-#include "hb-draw.hh"
-#include "hb-paint.hh"
-#include "hb-machinery.hh"
-
-#include "hb-ot.h"
-
-#include "hb-ot-var-avar-table.hh"
-#include "hb-ot-var-fvar-table.hh"
-
-
-/**
- * SECTION:hb-font
- * @title: hb-font
- * @short_description: Font objects
- * @include: hb.h
- *
- * Functions for working with font objects.
- *
- * A font object represents a font face at a specific size and with
- * certain other parameters (pixels-per-em, points-per-em, variation
- * settings) specified. Font objects are created from font face
- * objects, and are used as input to hb_shape(), among other things.
- *
- * Client programs can optionally pass in their own functions that
- * implement the basic, lower-level queries of font objects. This set
- * of font functions is defined by the virtual methods in
- * #hb_font_funcs_t.
- *
- * HarfBuzz provides a built-in set of lightweight default
- * functions for each method in #hb_font_funcs_t.
- *
- * The default font functions are implemented in terms of the
- * #hb_font_funcs_t methods of the parent font object. This allows
- * client programs to override only the methods they need to, and
- * otherwise inherit the parent font's implementation, if any.
- **/
+#include "hb-font-private.hh"
/*
@@ -72,267 +36,149 @@
*/
static hb_bool_t
-hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+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)
{
- hb_memset (extents, 0, sizeof (*extents));
+ memset (metrics, 0, sizeof (*metrics));
return false;
}
-
static hb_bool_t
-hb_font_get_font_h_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+hb_font_get_font_h_extents_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_font_extents_t *metrics,
+ void *user_data HB_UNUSED)
{
- hb_bool_t ret = font->parent->get_font_h_extents (extents);
+ hb_bool_t ret = font->parent->get_font_h_extents (metrics);
if (ret) {
- extents->ascender = font->parent_scale_y_distance (extents->ascender);
- extents->descender = font->parent_scale_y_distance (extents->descender);
- extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
+ metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
+ metrics->descender = font->parent_scale_y_distance (metrics->descender);
+ metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
}
return ret;
}
static hb_bool_t
-hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+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)
{
- hb_memset (extents, 0, sizeof (*extents));
+ memset (metrics, 0, sizeof (*metrics));
return false;
}
-
static hb_bool_t
-hb_font_get_font_v_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_font_extents_t *extents,
- void *user_data HB_UNUSED)
+hb_font_get_font_v_extents_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_font_extents_t *metrics,
+ void *user_data HB_UNUSED)
{
- hb_bool_t ret = font->parent->get_font_v_extents (extents);
+ hb_bool_t ret = font->parent->get_font_v_extents (metrics);
if (ret) {
- extents->ascender = font->parent_scale_x_distance (extents->ascender);
- extents->descender = font->parent_scale_x_distance (extents->descender);
- extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
+ metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
+ metrics->descender = font->parent_scale_x_distance (metrics->descender);
+ metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
}
return ret;
}
static hb_bool_t
-hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
+hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
-
static hb_bool_t
-hb_font_get_nominal_glyph_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+hb_font_get_nominal_glyph_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
{
- if (font->has_nominal_glyphs_func_set ())
- {
- return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
- }
return font->parent->get_nominal_glyph (unicode, glyph);
}
-#define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
-
-static unsigned int
-hb_font_get_nominal_glyphs_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- void *user_data HB_UNUSED)
-{
- if (font->has_nominal_glyph_func_set ())
- {
- for (unsigned int i = 0; i < count; i++)
- {
- if (!font->get_nominal_glyph (*first_unicode, first_glyph))
- return i;
-
- first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- }
- return count;
- }
-
- return font->parent->get_nominal_glyphs (count,
- first_unicode, unicode_stride,
- first_glyph, glyph_stride);
-}
-
static hb_bool_t
-hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- hb_codepoint_t variation_selector HB_UNUSED,
+hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
-
static hb_bool_t
-hb_font_get_variation_glyph_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+hb_font_get_variation_glyph_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
{
return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
}
static hb_position_t
-hb_font_get_glyph_h_advance_nil (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
return font->x_scale;
}
-
static hb_position_t
-hb_font_get_glyph_h_advance_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_advance_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
- if (font->has_glyph_h_advances_func_set ())
- {
- hb_position_t ret;
- font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
- return ret;
- }
return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
}
static hb_position_t
-hb_font_get_glyph_v_advance_nil (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
/* TODO use font_extents.ascender+descender */
return font->y_scale;
}
-
static hb_position_t
-hb_font_get_glyph_v_advance_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_advance_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ void *user_data HB_UNUSED)
{
- if (font->has_glyph_v_advances_func_set ())
- {
- hb_position_t ret;
- font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
- return ret;
- }
return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
}
-#define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
-
-static void
-hb_font_get_glyph_h_advances_default (hb_font_t* font,
- void* font_data HB_UNUSED,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride,
- void *user_data HB_UNUSED)
-{
- if (font->has_glyph_h_advance_func_set ())
- {
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->get_glyph_h_advance (*first_glyph);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- return;
- }
-
- font->parent->get_glyph_h_advances (count,
- first_glyph, glyph_stride,
- first_advance, advance_stride);
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->parent_scale_x_distance (*first_advance);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
-}
-
-#define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
-static void
-hb_font_get_glyph_v_advances_default (hb_font_t* font,
- void* font_data HB_UNUSED,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride,
- void *user_data HB_UNUSED)
-{
- if (font->has_glyph_v_advance_func_set ())
- {
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->get_glyph_v_advance (*first_glyph);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- return;
- }
-
- font->parent->get_glyph_v_advances (count,
- first_glyph, glyph_stride,
- first_advance, advance_stride);
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->parent_scale_y_distance (*first_advance);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
-}
-
static hb_bool_t
-hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return true;
}
-
static hb_bool_t
-hb_font_get_glyph_h_origin_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_origin_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
if (ret)
@@ -341,24 +187,23 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return false;
}
-
static hb_bool_t
-hb_font_get_glyph_v_origin_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_origin_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
if (ret)
@@ -367,64 +212,59 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font,
}
static hb_position_t
-hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t left_glyph HB_UNUSED,
- hb_codepoint_t right_glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph,
+ void *user_data HB_UNUSED)
{
return 0;
}
-
static hb_position_t
-hb_font_get_glyph_h_kerning_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t left_glyph,
- hb_codepoint_t right_glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_h_kerning_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph,
+ void *user_data HB_UNUSED)
{
return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
}
-#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
-hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t top_glyph HB_UNUSED,
- hb_codepoint_t bottom_glyph HB_UNUSED,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t top_glyph,
+ hb_codepoint_t bottom_glyph,
+ void *user_data HB_UNUSED)
{
return 0;
}
-
static hb_position_t
-hb_font_get_glyph_v_kerning_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t top_glyph,
- hb_codepoint_t bottom_glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_v_kerning_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t top_glyph,
+ hb_codepoint_t bottom_glyph,
+ void *user_data HB_UNUSED)
{
return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
}
-#endif
static hb_bool_t
-hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
+hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
- hb_memset (extents, 0, sizeof (*extents));
+ memset (extents, 0, sizeof (*extents));
return false;
}
-
static hb_bool_t
-hb_font_get_glyph_extents_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_extents_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
if (ret) {
@@ -435,26 +275,25 @@ hb_font_get_glyph_extents_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- unsigned int point_index HB_UNUSED,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
*x = *y = 0;
return false;
}
-
static hb_bool_t
-hb_font_get_glyph_contour_point_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- unsigned int point_index,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_contour_point_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ unsigned int point_index,
+ hb_position_t *x,
+ hb_position_t *y,
+ void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
if (ret)
@@ -463,245 +302,86 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- char *name,
- unsigned int size,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size,
+ void *user_data HB_UNUSED)
{
if (size) *name = '\0';
return false;
}
-
static hb_bool_t
-hb_font_get_glyph_name_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- char *name,
- unsigned int size,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_name_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size,
+ void *user_data HB_UNUSED)
{
return font->parent->get_glyph_name (glyph, name, size);
}
static hb_bool_t
-hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- const char *name HB_UNUSED,
- int len HB_UNUSED, /* -1 means nul-terminated */
+hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
+ void *font_data HB_UNUSED,
+ const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+ void *user_data HB_UNUSED)
{
*glyph = 0;
return false;
}
-
static hb_bool_t
-hb_font_get_glyph_from_name_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- const char *name,
- int len, /* -1 means nul-terminated */
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
+hb_font_get_glyph_from_name_parent (hb_font_t *font,
+ void *font_data HB_UNUSED,
+ const char *name, int len, /* -1 means nul-terminated */
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
{
return font->parent->get_glyph_from_name (name, len, glyph);
}
-static void
-hb_font_draw_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs,
- void *draw_data,
- void *user_data HB_UNUSED)
-{
-}
-
-static void
-hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph HB_UNUSED,
- hb_paint_funcs_t *paint_funcs HB_UNUSED,
- void *paint_data HB_UNUSED,
- unsigned int palette HB_UNUSED,
- hb_color_t foreground HB_UNUSED,
- void *user_data HB_UNUSED)
-{
-}
-
-typedef struct hb_font_draw_glyph_default_adaptor_t {
- hb_draw_funcs_t *draw_funcs;
- void *draw_data;
- float x_scale;
- float y_scale;
- float slant;
-} hb_font_draw_glyph_default_adaptor_t;
-
-static void
-hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
- float x_scale = adaptor->x_scale;
- float y_scale = adaptor->y_scale;
- float slant = adaptor->slant;
-
- adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
- x_scale * to_x + slant * to_y, y_scale * to_y);
-}
-
-static void
-hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
- float x_scale = adaptor->x_scale;
- float y_scale = adaptor->y_scale;
- float slant = adaptor->slant;
-
- st->current_x = st->current_x * x_scale + st->current_y * slant;
- st->current_y = st->current_y * y_scale;
-
- adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
- x_scale * to_x + slant * to_y, y_scale * to_y);
-}
-
-static void
-hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
- float x_scale = adaptor->x_scale;
- float y_scale = adaptor->y_scale;
- float slant = adaptor->slant;
-
- st->current_x = st->current_x * x_scale + st->current_y * slant;
- st->current_y = st->current_y * y_scale;
-
- adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
- x_scale * control_x + slant * control_y, y_scale * control_y,
- x_scale * to_x + slant * to_y, y_scale * to_y);
-}
-
-static void
-hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
- float x_scale = adaptor->x_scale;
- float y_scale = adaptor->y_scale;
- float slant = adaptor->slant;
-
- st->current_x = st->current_x * x_scale + st->current_y * slant;
- st->current_y = st->current_y * y_scale;
-
- adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
- x_scale * control1_x + slant * control1_y, y_scale * control1_y,
- x_scale * control2_x + slant * control2_y, y_scale * control2_y,
- x_scale * to_x + slant * to_y, y_scale * to_y);
-}
-
-static void
-hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
- hb_draw_state_t *st,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
-
- adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
-}
-
-static const hb_draw_funcs_t _hb_draw_funcs_default = {
+static const hb_font_funcs_t _hb_font_funcs_nil = {
HB_OBJECT_HEADER_STATIC,
- {
-#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default,
- HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_DRAW_FUNC_IMPLEMENT
- }
-};
-
-static void
-hb_font_draw_glyph_default (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs,
- void *draw_data,
- void *user_data HB_UNUSED)
-{
- hb_font_draw_glyph_default_adaptor_t adaptor = {
- draw_funcs,
- draw_data,
- font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
- font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
- font->parent->y_scale ? (font->slant - font->parent->slant) *
- (float) font->x_scale / (float) font->parent->y_scale : 0.f
- };
+ true, /* immutable */
- font->parent->draw_glyph (glyph,
- const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
- &adaptor);
-}
-
-static void
-hb_font_paint_glyph_default (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_paint_funcs_t *paint_funcs,
- void *paint_data,
- unsigned int palette,
- hb_color_t foreground,
- void *user_data)
-{
- paint_funcs->push_transform (paint_data,
- font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
- font->parent->y_scale ? (font->slant - font->parent->slant) *
- (float) font->x_scale / (float) font->parent->y_scale : 0.f,
- 0.f,
- font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
- 0.f, 0.f);
-
- font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground);
-
- paint_funcs->pop_transform (paint_data);
-}
-
-DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
-{
- HB_OBJECT_HEADER_STATIC,
-
- nullptr,
- nullptr,
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ },
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ },
{
{
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil,
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
}
}
};
-
-static const hb_font_funcs_t _hb_font_funcs_default = {
+static const hb_font_funcs_t _hb_font_funcs_parent = {
HB_OBJECT_HEADER_STATIC,
- nullptr,
- nullptr,
+ true, /* immutable */
+
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ },
+ {
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+ },
{
{
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default,
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
}
@@ -710,23 +390,23 @@ static const hb_font_funcs_t _hb_font_funcs_default = {
/**
- * hb_font_funcs_create:
+ * hb_font_funcs_create: (Xconstructor)
*
- * Creates a new #hb_font_funcs_t structure of font functions.
+ *
*
- * Return value: (transfer full): The font-functions structure
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_font_funcs_t *
-hb_font_funcs_create ()
+hb_font_funcs_create (void)
{
hb_font_funcs_t *ffuncs;
if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
return hb_font_funcs_get_empty ();
- ffuncs->get = _hb_font_funcs_default.get;
+ ffuncs->get = _hb_font_funcs_parent.get;
return ffuncs;
}
@@ -734,25 +414,25 @@ hb_font_funcs_create ()
/**
* hb_font_funcs_get_empty:
*
- * Fetches an empty font-functions structure.
+ *
*
- * Return value: (transfer full): The font-functions structure
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_font_funcs_t *
-hb_font_funcs_get_empty ()
+hb_font_funcs_get_empty (void)
{
- return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
+ return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent);
}
/**
* hb_font_funcs_reference: (skip)
- * @ffuncs: The font-functions structure
+ * @ffuncs: font functions.
*
- * Increases the reference count on a font-functions structure.
+ *
*
- * Return value: The font-functions structure
+ * Return value:
*
* Since: 0.9.2
**/
@@ -764,11 +444,9 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
/**
* hb_font_funcs_destroy: (skip)
- * @ffuncs: The font-functions structure
+ * @ffuncs: font functions.
*
- * Decreases the reference count on a font-functions structure. When
- * the reference count reaches zero, the font-functions structure is
- * destroyed, freeing all memory.
+ *
*
* Since: 0.9.2
**/
@@ -777,31 +455,25 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
if (!hb_object_destroy (ffuncs)) return;
- if (ffuncs->destroy)
- {
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \
- ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
+ ffuncs->destroy.name (ffuncs->user_data.name);
+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
- }
- hb_free (ffuncs->destroy);
- hb_free (ffuncs->user_data);
-
- hb_free (ffuncs);
+ free (ffuncs);
}
/**
* hb_font_funcs_set_user_data: (skip)
- * @ffuncs: The font-functions structure
- * @key: The user-data key to set
- * @data: A pointer to the user data set
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @ffuncs: font functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the specified font-functions structure.
+ *
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -809,7 +481,7 @@ hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key,
void * data,
- hb_destroy_func_t destroy /* May be NULL. */,
+ hb_destroy_func_t destroy,
hb_bool_t replace)
{
return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
@@ -817,19 +489,18 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_get_user_data: (skip)
- * @ffuncs: The font-functions structure
- * @key: The user-data key to query
+ * @ffuncs: font functions.
+ * @key:
*
- * Fetches the user data associated with the specified key,
- * attached to the specified font-functions structure.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs,
- hb_user_data_key_t *key)
+hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key)
{
return hb_object_get_user_data (ffuncs, key);
}
@@ -837,148 +508,92 @@ hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_make_immutable:
- * @ffuncs: The font-functions structure
+ * @ffuncs: font functions.
*
- * Makes a font-functions structure immutable.
+ *
*
* Since: 0.9.2
**/
void
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
{
- if (hb_object_is_immutable (ffuncs))
+ if (unlikely (hb_object_is_inert (ffuncs)))
return;
- hb_object_make_immutable (ffuncs);
+ ffuncs->immutable = true;
}
/**
* hb_font_funcs_is_immutable:
- * @ffuncs: The font-functions structure
+ * @ffuncs: font functions.
*
- * Tests whether a font-functions structure is immutable.
+ *
*
- * Return value: `true` if @ffuncs is immutable, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
{
- return hb_object_is_immutable (ffuncs);
-}
-
-
-static bool
-_hb_font_funcs_set_preamble (hb_font_funcs_t *ffuncs,
- bool func_is_null,
- void **user_data,
- hb_destroy_func_t *destroy)
-{
- if (hb_object_is_immutable (ffuncs))
- {
- if (*destroy)
- (*destroy) (*user_data);
- return false;
- }
-
- if (func_is_null)
- {
- if (*destroy)
- (*destroy) (*user_data);
- *destroy = nullptr;
- *user_data = nullptr;
- }
-
- return true;
+ return ffuncs->immutable;
}
-static bool
-_hb_font_funcs_set_middle (hb_font_funcs_t *ffuncs,
- void *user_data,
- hb_destroy_func_t destroy)
-{
- if (user_data && !ffuncs->user_data)
- {
- ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data));
- if (unlikely (!ffuncs->user_data))
- goto fail;
- }
- if (destroy && !ffuncs->destroy)
- {
- ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy));
- if (unlikely (!ffuncs->destroy))
- goto fail;
- }
-
- return true;
-
-fail:
- if (destroy)
- (destroy) (user_data);
- return false;
-}
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
- \
+#define HB_FONT_FUNC_IMPLEMENT(name) \
+ \
void \
hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
- hb_font_##get_##name##_func_t func, \
- void *user_data, \
- hb_destroy_func_t destroy) \
+ hb_font_get_##name##_func_t func, \
+ void *user_data, \
+ hb_destroy_func_t destroy) \
{ \
- if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\
- return; \
- \
- if (ffuncs->destroy && ffuncs->destroy->name) \
- ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
+ if (ffuncs->immutable) { \
+ if (destroy) \
+ destroy (user_data); \
+ return; \
+ } \
+ \
+ if (ffuncs->destroy.name) \
+ ffuncs->destroy.name (ffuncs->user_data.name); \
\
- if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy)) \
- return; \
- \
- if (func) \
+ if (func) { \
ffuncs->get.f.name = func; \
- else \
- ffuncs->get.f.name = hb_font_##get_##name##_default; \
- \
- if (ffuncs->user_data) \
- ffuncs->user_data->name = user_data; \
- if (ffuncs->destroy) \
- ffuncs->destroy->name = destroy; \
+ ffuncs->user_data.name = user_data; \
+ ffuncs->destroy.name = destroy; \
+ } else { \
+ ffuncs->get.f.name = hb_font_get_##name##_parent; \
+ ffuncs->user_data.name = nullptr; \
+ ffuncs->destroy.name = nullptr; \
+ } \
}
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
bool
-hb_font_t::has_func_set (unsigned int i)
-{
- return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
-}
-
-bool
hb_font_t::has_func (unsigned int i)
{
- return has_func_set (i) ||
- (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
+ if (parent && parent != hb_font_get_empty () && parent->has_func (i))
+ return true;
+ return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i];
}
/* Public getters */
/**
* hb_font_get_h_extents:
- * @font: #hb_font_t to work upon
- * @extents: (out): The font extents retrieved
+ * @font: a font.
+ * @extents: (out):
*
- * Fetches the extents for a specified font, for horizontal
- * text segments.
*
- * Return value: `true` if data found, `false` otherwise
+ *
+ * Return value:
*
* Since: 1.1.3
**/
hb_bool_t
-hb_font_get_h_extents (hb_font_t *font,
+hb_font_get_h_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_h_extents (extents);
@@ -986,18 +601,17 @@ hb_font_get_h_extents (hb_font_t *font,
/**
* hb_font_get_v_extents:
- * @font: #hb_font_t to work upon
- * @extents: (out): The font extents retrieved
+ * @font: a font.
+ * @extents: (out):
*
- * Fetches the extents for a specified font, for vertical
- * text segments.
*
- * Return value: `true` if data found, `false` otherwise
+ *
+ * Return value:
*
* Since: 1.1.3
**/
hb_bool_t
-hb_font_get_v_extents (hb_font_t *font,
+hb_font_get_v_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_v_extents (extents);
@@ -1005,25 +619,20 @@ hb_font_get_v_extents (hb_font_t *font,
/**
* hb_font_get_glyph:
- * @font: #hb_font_t to work upon
- * @unicode: The Unicode code point to query
- * @variation_selector: A variation-selector code point
- * @glyph: (out): The glyph ID retrieved
- *
- * Fetches the glyph ID for a Unicode code point in the specified
- * font, with an optional variation selector.
+ * @font: a font.
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
*
- * If @variation_selector is 0, calls hb_font_get_nominal_glyph();
- * otherwise calls hb_font_get_variation_glyph().
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph (hb_font_t *font,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
+hb_font_get_glyph (hb_font_t *font,
+ hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
if (unlikely (variation_selector))
@@ -1033,78 +642,40 @@ hb_font_get_glyph (hb_font_t *font,
/**
* hb_font_get_nominal_glyph:
- * @font: #hb_font_t to work upon
- * @unicode: The Unicode code point to query
- * @glyph: (out): The glyph ID retrieved
- *
- * Fetches the nominal glyph ID for a Unicode code point in the
- * specified font.
+ * @font: a font.
+ * @unicode:
+ * @glyph: (out):
*
- * This version of the function should not be used to fetch glyph IDs
- * for code points modified by variation selectors. For variation-selector
- * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 1.2.3
**/
hb_bool_t
-hb_font_get_nominal_glyph (hb_font_t *font,
- hb_codepoint_t unicode,
+hb_font_get_nominal_glyph (hb_font_t *font,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph)
{
return font->get_nominal_glyph (unicode, glyph);
}
/**
- * hb_font_get_nominal_glyphs:
- * @font: #hb_font_t to work upon
- * @count: number of code points to query
- * @first_unicode: The first Unicode code point to query
- * @unicode_stride: The stride between successive code points
- * @first_glyph: (out): The first glyph ID retrieved
- * @glyph_stride: The stride between successive glyph IDs
- *
- * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
- * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the
- * first unsupported glyph ID.
- *
- * Return value: the number of code points processed
- *
- * Since: 2.6.3
- **/
-unsigned int
-hb_font_get_nominal_glyphs (hb_font_t *font,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride)
-{
- return font->get_nominal_glyphs (count,
- first_unicode, unicode_stride,
- first_glyph, glyph_stride);
-}
-
-/**
* hb_font_get_variation_glyph:
- * @font: #hb_font_t to work upon
- * @unicode: The Unicode code point to query
- * @variation_selector: The variation-selector code point to query
- * @glyph: (out): The glyph ID retrieved
+ * @font: a font.
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
*
- * Fetches the glyph ID for a Unicode code point when followed by
- * by the specified variation-selector code point, in the specified
- * font.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 1.2.3
**/
hb_bool_t
-hb_font_get_variation_glyph (hb_font_t *font,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
+hb_font_get_variation_glyph (hb_font_t *font,
+ hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
return font->get_variation_glyph (unicode, variation_selector, glyph);
@@ -1112,204 +683,135 @@ hb_font_get_variation_glyph (hb_font_t *font,
/**
* hb_font_get_glyph_h_advance:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
+ * @font: a font.
+ * @glyph:
*
- * Fetches the advance for a glyph ID in the specified font,
- * for horizontal text segments.
+ *
*
- * Return value: The advance of @glyph within @font
+ * Return value:
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_h_advance (hb_font_t *font,
- hb_codepoint_t glyph)
+hb_font_get_glyph_h_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
{
return font->get_glyph_h_advance (glyph);
}
/**
* hb_font_get_glyph_v_advance:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
+ * @font: a font.
+ * @glyph:
*
- * Fetches the advance for a glyph ID in the specified font,
- * for vertical text segments.
+ *
*
- * Return value: The advance of @glyph within @font
+ * Return value:
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_v_advance (hb_font_t *font,
- hb_codepoint_t glyph)
+hb_font_get_glyph_v_advance (hb_font_t *font,
+ hb_codepoint_t glyph)
{
return font->get_glyph_v_advance (glyph);
}
/**
- * hb_font_get_glyph_h_advances:
- * @font: #hb_font_t to work upon
- * @count: The number of glyph IDs in the sequence queried
- * @first_glyph: The first glyph ID to query
- * @glyph_stride: The stride between successive glyph IDs
- * @first_advance: (out): The first advance retrieved
- * @advance_stride: The stride between successive advances
- *
- * Fetches the advances for a sequence of glyph IDs in the specified
- * font, for horizontal text segments.
- *
- * Since: 1.8.6
- **/
-void
-hb_font_get_glyph_h_advances (hb_font_t* font,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
-{
- font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
-}
-/**
- * hb_font_get_glyph_v_advances:
- * @font: #hb_font_t to work upon
- * @count: The number of glyph IDs in the sequence queried
- * @first_glyph: The first glyph ID to query
- * @glyph_stride: The stride between successive glyph IDs
- * @first_advance: (out): The first advance retrieved
- * @advance_stride: (out): The stride between successive advances
- *
- * Fetches the advances for a sequence of glyph IDs in the specified
- * font, for vertical text segments.
- *
- * Since: 1.8.6
- **/
-void
-hb_font_get_glyph_v_advances (hb_font_t* font,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
-{
- font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
-}
-
-/**
* hb_font_get_glyph_h_origin:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @x: (out): The X coordinate of the origin
- * @y: (out): The Y coordinate of the origin
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
*
- * Fetches the (X,Y) coordinates of the origin for a glyph ID
- * in the specified font, for horizontal text segments.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_h_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_h_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_h_origin (glyph, x, y);
}
/**
* hb_font_get_glyph_v_origin:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @x: (out): The X coordinate of the origin
- * @y: (out): The Y coordinate of the origin
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
*
- * Fetches the (X,Y) coordinates of the origin for a glyph ID
- * in the specified font, for vertical text segments.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_v_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_v_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_v_origin (glyph, x, y);
}
/**
* hb_font_get_glyph_h_kerning:
- * @font: #hb_font_t to work upon
- * @left_glyph: The glyph ID of the left glyph in the glyph pair
- * @right_glyph: The glyph ID of the right glyph in the glyph pair
- *
- * Fetches the kerning-adjustment value for a glyph-pair in
- * the specified font, for horizontal text segments.
+ * @font: a font.
+ * @left_glyph:
+ * @right_glyph:
*
- * <note>It handles legacy kerning only (as returned by the corresponding
- * #hb_font_funcs_t function).</note>
+ *
*
- * Return value: The kerning adjustment value
+ * Return value:
*
* Since: 0.9.2
**/
hb_position_t
-hb_font_get_glyph_h_kerning (hb_font_t *font,
- hb_codepoint_t left_glyph,
- hb_codepoint_t right_glyph)
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+ hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
{
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
-#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_v_kerning:
- * @font: #hb_font_t to work upon
- * @top_glyph: The glyph ID of the top glyph in the glyph pair
- * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
- *
- * Fetches the kerning-adjustment value for a glyph-pair in
- * the specified font, for vertical text segments.
+ * @font: a font.
+ * @top_glyph:
+ * @bottom_glyph:
*
- * <note>It handles legacy kerning only (as returned by the corresponding
- * #hb_font_funcs_t function).</note>
+ *
*
- * Return value: The kerning adjustment value
+ * Return value:
*
* Since: 0.9.2
- * Deprecated: 2.0.0
**/
hb_position_t
-hb_font_get_glyph_v_kerning (hb_font_t *font,
- hb_codepoint_t top_glyph,
- hb_codepoint_t bottom_glyph)
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+ hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
{
return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
}
-#endif
/**
* hb_font_get_glyph_extents:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @extents: (out): The #hb_glyph_extents_t retrieved
+ * @font: a font.
+ * @glyph:
+ * @extents: (out):
*
- * Fetches the #hb_glyph_extents_t data for a glyph ID
- * in the specified font.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_extents (hb_font_t *font,
- hb_codepoint_t glyph,
+hb_font_get_glyph_extents (hb_font_t *font,
+ hb_codepoint_t glyph,
hb_glyph_extents_t *extents)
{
return font->get_glyph_extents (glyph, extents);
@@ -1317,362 +819,211 @@ hb_font_get_glyph_extents (hb_font_t *font,
/**
* hb_font_get_glyph_contour_point:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @point_index: The contour-point index to query
- * @x: (out): The X value retrieved for the contour point
- * @y: (out): The Y value retrieved for the contour point
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @x: (out):
+ * @y: (out):
*
- * Fetches the (x,y) coordinates of a specified contour-point index
- * in the specified glyph, within the specified font.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_contour_point (hb_font_t *font,
- hb_codepoint_t glyph,
- unsigned int point_index,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_contour_point (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_contour_point (glyph, point_index, x, y);
}
/**
* hb_font_get_glyph_name:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @name: (out) (array length=size): Name string retrieved for the glyph ID
- * @size: Length of the glyph-name string retrieved
- *
- * Fetches the glyph-name string for a glyph ID in the specified @font.
+ * @font: a font.
+ * @glyph:
+ * @name: (array length=size):
+ * @size:
*
- * According to the OpenType specification, glyph names are limited to 63
- * characters and can only contain (a subset of) ASCII.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_name (hb_font_t *font,
- hb_codepoint_t glyph,
- char *name,
- unsigned int size)
+hb_font_get_glyph_name (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size)
{
return font->get_glyph_name (glyph, name, size);
}
/**
* hb_font_get_glyph_from_name:
- * @font: #hb_font_t to work upon
- * @name: (array length=len): The name string to query
- * @len: The length of the name queried
- * @glyph: (out): The glyph ID retrieved
- *
- * Fetches the glyph ID that corresponds to a name string in the specified @font.
+ * @font: a font.
+ * @name: (array length=len):
+ * @len:
+ * @glyph: (out):
*
- * <note>Note: @len == -1 means the name string is null-terminated.</note>
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_from_name (hb_font_t *font,
- const char *name,
- int len, /* -1 means nul-terminated */
+hb_font_get_glyph_from_name (hb_font_t *font,
+ const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph)
{
return font->get_glyph_from_name (name, len, glyph);
}
-/**
- * hb_font_get_glyph_shape:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID
- * @dfuncs: #hb_draw_funcs_t to draw to
- * @draw_data: User data to pass to draw callbacks
- *
- * Fetches the glyph shape that corresponds to a glyph in the specified @font.
- * The shape is returned by way of calls to the callbacks of the @dfuncs
- * objects, with @draw_data passed to them.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use hb_font_draw_glyph() instead
- */
-void
-hb_font_get_glyph_shape (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *dfuncs, void *draw_data)
-{
- hb_font_draw_glyph (font, glyph, dfuncs, draw_data);
-}
-
-/**
- * hb_font_draw_glyph:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID
- * @dfuncs: #hb_draw_funcs_t to draw to
- * @draw_data: User data to pass to draw callbacks
- *
- * Draws the outline that corresponds to a glyph in the specified @font.
- *
- * The outline is returned by way of calls to the callbacks of the @dfuncs
- * objects, with @draw_data passed to them.
- *
- * Since: 7.0.0
- **/
-void
-hb_font_draw_glyph (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *dfuncs, void *draw_data)
-{
- font->draw_glyph (glyph, dfuncs, draw_data);
-}
-
-/**
- * hb_font_paint_glyph:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID
- * @pfuncs: #hb_paint_funcs_t to paint with
- * @paint_data: User data to pass to paint callbacks
- * @palette_index: The index of the font's color palette to use
- * @foreground: The foreground color, unpremultipled
- *
- * Paints the glyph.
- *
- * The painting instructions are returned by way of calls to
- * the callbacks of the @funcs object, with @paint_data passed
- * to them.
- *
- * If the font has color palettes (see hb_ot_color_has_palettes()),
- * then @palette_index selects the palette to use. If the font only
- * has one palette, this will be 0.
- *
- * Since: 7.0.0
- */
-void
-hb_font_paint_glyph (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_paint_funcs_t *pfuncs, void *paint_data,
- unsigned int palette_index,
- hb_color_t foreground)
-{
- font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
-}
/* A bit higher-level, and with fallback */
/**
* hb_font_get_extents_for_direction:
- * @font: #hb_font_t to work upon
- * @direction: The direction of the text segment
- * @extents: (out): The #hb_font_extents_t retrieved
+ * @font: a font.
+ * @direction:
+ * @extents:
*
- * Fetches the extents for a font in a text segment of the
- * specified direction.
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
*
* Since: 1.1.3
**/
void
-hb_font_get_extents_for_direction (hb_font_t *font,
- hb_direction_t direction,
+hb_font_get_extents_for_direction (hb_font_t *font,
+ hb_direction_t direction,
hb_font_extents_t *extents)
{
- font->get_extents_for_direction (direction, extents);
+ return font->get_extents_for_direction (direction, extents);
}
/**
* hb_font_get_glyph_advance_for_direction:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @direction: The direction of the text segment
- * @x: (out): The horizontal advance retrieved
- * @y: (out): The vertical advance retrieved
- *
- * Fetches the advance for a glyph ID from the specified font,
- * in a text segment of the specified direction.
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_advance_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
- font->get_glyph_advance_for_direction (glyph, direction, x, y);
-}
-/**
- * hb_font_get_glyph_advances_for_direction:
- * @font: #hb_font_t to work upon
- * @direction: The direction of the text segment
- * @count: The number of glyph IDs in the sequence queried
- * @first_glyph: The first glyph ID to query
- * @glyph_stride: The stride between successive glyph IDs
- * @first_advance: (out): The first advance retrieved
- * @advance_stride: (out): The stride between successive advances
- *
- * Fetches the advances for a sequence of glyph IDs in the specified
- * font, in a text segment of the specified direction.
- *
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
- *
- * Since: 1.8.6
- **/
-HB_EXTERN void
-hb_font_get_glyph_advances_for_direction (hb_font_t* font,
- hb_direction_t direction,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
-{
- font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
+ return font->get_glyph_advance_for_direction (glyph, direction, x, y);
}
/**
* hb_font_get_glyph_origin_for_direction:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @direction: The direction of the text segment
- * @x: (out): The X coordinate retrieved for the origin
- * @y: (out): The Y coordinate retrieved for the origin
- *
- * Fetches the (X,Y) coordinates of the origin for a glyph in
- * the specified font.
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_add_glyph_origin_for_direction:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate
- * Output = The X coordinate plus the X-coordinate of the origin
- * @y: (inout): Input = The original Y coordinate
- * Output = The Y coordinate plus the Y-coordinate of the origin
- *
- * Adds the origin coordinates to an (X,Y) point coordinate, in
- * the specified glyph ID in the specified font.
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_add_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
return font->add_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_subtract_glyph_origin_for_direction:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate
- * Output = The X coordinate minus the X-coordinate of the origin
- * @y: (inout): Input = The original Y coordinate
- * Output = The Y coordinate minus the Y-coordinate of the origin
- *
- * Subtracts the origin coordinates from an (X,Y) point coordinate,
- * in the specified glyph ID in the specified font.
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
/**
* hb_font_get_glyph_kerning_for_direction:
- * @font: #hb_font_t to work upon
- * @first_glyph: The glyph ID of the first glyph in the glyph pair to query
- * @second_glyph: The glyph ID of the second glyph in the glyph pair to query
- * @direction: The direction of the text segment
- * @x: (out): The horizontal kerning-adjustment value retrieved
- * @y: (out): The vertical kerning-adjustment value retrieved
- *
- * Fetches the kerning-adjustment value for a glyph-pair in the specified font.
+ * @font: a font.
+ * @first_glyph:
+ * @second_glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
- hb_codepoint_t first_glyph,
- hb_codepoint_t second_glyph,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+ hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
/**
* hb_font_get_glyph_extents_for_origin:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @direction: The direction of the text segment
- * @extents: (out): The #hb_glyph_extents_t retrieved
- *
- * Fetches the #hb_glyph_extents_t data for a glyph ID
- * in the specified font, with respect to the origin in
- * a text segment in the specified direction.
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @extents: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_extents_for_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_direction_t direction,
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
hb_glyph_extents_t *extents)
{
return font->get_glyph_extents_for_origin (glyph, direction, extents);
@@ -1680,82 +1031,65 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
/**
* hb_font_get_glyph_contour_point_for_origin:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @point_index: The contour-point index to query
- * @direction: The direction of the text segment
- * @x: (out): The X value retrieved for the contour point
- * @y: (out): The Y value retrieved for the contour point
- *
- * Fetches the (X,Y) coordinates of a specified contour-point index
- * in the specified glyph ID in the specified font, with respect
- * to the origin in a text segment in the specified direction.
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
*
- * Calls the appropriate direction-specific variant (horizontal
- * or vertical) depending on the value of @direction.
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
- hb_codepoint_t glyph,
- unsigned int point_index,
- hb_direction_t direction,
- hb_position_t *x,
- hb_position_t *y)
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+ hb_codepoint_t glyph, unsigned int point_index,
+ hb_direction_t direction,
+ hb_position_t *x, hb_position_t *y)
{
return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
}
+/* Generates gidDDD if glyph has no name. */
/**
* hb_font_glyph_to_string:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph ID to query
- * @s: (out) (array length=size): The string containing the glyph name
- * @size: Length of string @s
- *
- * Fetches the name of the specified glyph ID in @font and returns
- * it in string @s.
- *
- * If the glyph ID has no name in @font, a string of the form `gidDDD` is
- * generated, with `DDD` being the glyph ID.
+ * @font: a font.
+ * @glyph:
+ * @s: (array length=size):
+ * @size:
*
- * According to the OpenType specification, glyph names are limited to 63
- * characters and can only contain (a subset of) ASCII.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_glyph_to_string (hb_font_t *font,
- hb_codepoint_t glyph,
- char *s,
- unsigned int size)
+hb_font_glyph_to_string (hb_font_t *font,
+ hb_codepoint_t glyph,
+ char *s, unsigned int size)
{
font->glyph_to_string (glyph, s, size);
}
+/* Parses gidDDD and uniUUUU strings automatically. */
/**
* hb_font_glyph_from_string:
- * @font: #hb_font_t to work upon
- * @s: (array length=len) (element-type uint8_t): string to query
- * @len: The length of the string @s
- * @glyph: (out): The glyph ID corresponding to the string requested
- *
- * Fetches the glyph ID from @font that matches the specified string.
- * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically.
+ * @font: a font.
+ * @s: (array length=len) (element-type uint8_t):
+ * @len:
+ * @glyph: (out):
*
- * <note>Note: @len == -1 means the string is null-terminated.</note>
+ *
*
- * Return value: `true` if data found, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_font_glyph_from_string (hb_font_t *font,
- const char *s,
- int len,
+hb_font_glyph_from_string (hb_font_t *font,
+ const char *s, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph)
{
return font->glyph_from_string (s, len, glyph);
@@ -1766,53 +1100,23 @@ hb_font_glyph_from_string (hb_font_t *font,
* hb_font_t
*/
-DEFINE_NULL_INSTANCE (hb_font_t) =
-{
- HB_OBJECT_HEADER_STATIC,
-
- 0, /* serial */
- 0, /* serial_coords */
-
- nullptr, /* parent */
- const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
-
- 1000, /* x_scale */
- 1000, /* y_scale */
- 0.f, /* x_embolden */
- 0.f, /* y_embolden */
- true, /* embolden_in_place */
- 0, /* x_strength */
- 0, /* y_strength */
- 0.f, /* slant */
- 0.f, /* slant_xy; */
- 1.f, /* x_multf */
- 1.f, /* y_multf */
- 1<<16, /* x_mult */
- 1<<16, /* y_mult */
-
- 0, /* x_ppem */
- 0, /* y_ppem */
- 0, /* ptem */
-
- HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */
- 0, /* num_coords */
- nullptr, /* coords */
- nullptr, /* design_coords */
-
- const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
-
- /* Zero for the rest is fine. */
-};
-
-
-static hb_font_t *
-_hb_font_create (hb_face_t *face)
+/**
+ * hb_font_create: (Xconstructor)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_create (hb_face_t *face)
{
hb_font_t *font;
if (unlikely (!face))
face = hb_face_get_empty ();
-
if (!(font = hb_object_create<hb_font_t> ()))
return hb_font_get_empty ();
@@ -1820,75 +1124,19 @@ _hb_font_create (hb_face_t *face)
font->parent = hb_font_get_empty ();
font->face = hb_face_reference (face);
font->klass = hb_font_funcs_get_empty ();
- font->data.init0 (font);
- font->x_scale = font->y_scale = face->get_upem ();
- font->embolden_in_place = true;
- font->x_multf = font->y_multf = 1.f;
- font->x_mult = font->y_mult = 1 << 16;
- font->instance_index = HB_FONT_NO_VAR_NAMED_INSTANCE;
- return font;
-}
-
-/**
- * hb_font_create:
- * @face: a face.
- *
- * Constructs a new font object from the specified face.
- *
- * <note>Note: If @face's index value (as passed to hb_face_create()
- * has non-zero top 16-bits, those bits minus one are passed to
- * hb_font_set_var_named_instance(), effectively loading a named-instance
- * of a variable font, instead of the default-instance. This allows
- * specifying which named-instance to load by default when creating the
- * face.</note>
- *
- * Return value: (transfer full): The new font object
- *
- * Since: 0.9.2
- **/
-hb_font_t *
-hb_font_create (hb_face_t *face)
-{
- hb_font_t *font = _hb_font_create (face);
-
-#ifndef HB_NO_OT_FONT
- /* Install our in-house, very lightweight, funcs. */
- hb_ot_font_set_funcs (font);
-#endif
-
-#ifndef HB_NO_VAR
- if (face && face->index >> 16)
- hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
-#endif
+ font->x_scale = font->y_scale = hb_face_get_upem (face);
return font;
}
-static void
-_hb_font_adopt_var_coords (hb_font_t *font,
- int *coords, /* 2.14 normalized */
- float *design_coords,
- unsigned int coords_length)
-{
- hb_free (font->coords);
- hb_free (font->design_coords);
-
- font->coords = coords;
- font->design_coords = design_coords;
- font->num_coords = coords_length;
-
- font->mults_changed (); // Easiest to call this to drop cached data
-}
-
/**
* hb_font_create_sub_font:
- * @parent: The parent font object
+ * @parent: parent font.
*
- * Constructs a sub-font font object from the specified @parent font,
- * replicating the parent's properties.
+ *
*
- * Return value: (transfer full): The new sub-font font object
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -1898,68 +1146,86 @@ hb_font_create_sub_font (hb_font_t *parent)
if (unlikely (!parent))
parent = hb_font_get_empty ();
- hb_font_t *font = _hb_font_create (parent->face);
+ hb_font_t *font = hb_font_create (parent->face);
- if (unlikely (hb_object_is_immutable (font)))
+ if (unlikely (hb_object_is_inert (font)))
return font;
font->parent = hb_font_reference (parent);
font->x_scale = parent->x_scale;
font->y_scale = parent->y_scale;
- font->x_embolden = parent->x_embolden;
- font->y_embolden = parent->y_embolden;
- font->embolden_in_place = parent->embolden_in_place;
- font->slant = parent->slant;
font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem;
font->ptem = parent->ptem;
- unsigned int num_coords = parent->num_coords;
- if (num_coords)
+ font->num_coords = parent->num_coords;
+ if (!font->num_coords)
+ font->coords = nullptr;
+ else
{
- int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0]));
- float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
- if (likely (coords && design_coords))
- {
- hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
- hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
- _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
- }
+ unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
+ font->coords = (int *) malloc (size);
+ if (unlikely (!font->coords))
+ font->num_coords = 0;
else
- {
- hb_free (coords);
- hb_free (design_coords);
- }
+ memcpy (font->coords, parent->coords, size);
}
- font->mults_changed ();
-
return font;
}
/**
* hb_font_get_empty:
*
- * Fetches the empty font object.
+ *
*
- * Return value: (transfer full): The empty font object
+ * Return value: (transfer full)
*
* Since: 0.9.2
**/
hb_font_t *
-hb_font_get_empty ()
+hb_font_get_empty (void)
{
- return const_cast<hb_font_t *> (&Null (hb_font_t));
+ static const hb_font_t _hb_font_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* immutable */
+
+ nullptr, /* parent */
+ const_cast<hb_face_t *> (&_hb_face_nil),
+
+ 1000, /* x_scale */
+ 1000, /* y_scale */
+
+ 0, /* x_ppem */
+ 0, /* y_ppem */
+ 0, /* ptem */
+
+ 0, /* num_coords */
+ nullptr, /* coords */
+
+ const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
+ nullptr, /* user_data */
+ nullptr, /* destroy */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
+ };
+
+ return const_cast<hb_font_t *> (&_hb_font_nil);
}
/**
* hb_font_reference: (skip)
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Increases the reference count on the given font object.
+ *
*
- * Return value: (transfer full): The @font object
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -1971,11 +1237,9 @@ hb_font_reference (hb_font_t *font)
/**
* hb_font_destroy: (skip)
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Decreases the reference count on the given font object. When the
- * reference count reaches zero, the font is destroyed,
- * freeing all memory.
+ *
*
* Since: 0.9.2
**/
@@ -1984,7 +1248,9 @@ hb_font_destroy (hb_font_t *font)
{
if (!hb_object_destroy (font)) return;
- font->data.fini ();
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
if (font->destroy)
font->destroy (font->user_data);
@@ -1993,23 +1259,22 @@ hb_font_destroy (hb_font_t *font)
hb_face_destroy (font->face);
hb_font_funcs_destroy (font->klass);
- hb_free (font->coords);
- hb_free (font->design_coords);
+ free (font->coords);
- hb_free (font);
+ free (font);
}
/**
* hb_font_set_user_data: (skip)
- * @font: #hb_font_t to work upon
- * @key: The user-data key
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @font: a font.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the specified font object.
+ *
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -2017,29 +1282,25 @@ hb_bool_t
hb_font_set_user_data (hb_font_t *font,
hb_user_data_key_t *key,
void * data,
- hb_destroy_func_t destroy /* May be NULL. */,
+ hb_destroy_func_t destroy,
hb_bool_t replace)
{
- if (!hb_object_is_immutable (font))
- font->serial++;
-
return hb_object_set_user_data (font, key, data, destroy, replace);
}
/**
* hb_font_get_user_data: (skip)
- * @font: #hb_font_t to work upon
- * @key: The user-data key to query
+ * @font: a font.
+ * @key:
*
- * Fetches the user-data object associated with the specified key,
- * attached to the specified font object.
+ *
*
- * Return value: (transfer none): Pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_font_get_user_data (const hb_font_t *font,
+hb_font_get_user_data (hb_font_t *font,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (font, key);
@@ -2047,85 +1308,46 @@ hb_font_get_user_data (const hb_font_t *font,
/**
* hb_font_make_immutable:
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Makes @font immutable.
+ *
*
* Since: 0.9.2
**/
void
hb_font_make_immutable (hb_font_t *font)
{
- if (hb_object_is_immutable (font))
+ if (unlikely (hb_object_is_inert (font)))
return;
if (font->parent)
hb_font_make_immutable (font->parent);
- hb_object_make_immutable (font);
+ font->immutable = true;
}
/**
* hb_font_is_immutable:
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Tests whether a font object is immutable.
+ *
*
- * Return value: `true` if @font is immutable, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
hb_font_is_immutable (hb_font_t *font)
{
- return hb_object_is_immutable (font);
-}
-
-/**
- * hb_font_get_serial:
- * @font: #hb_font_t to work upon
- *
- * Returns the internal serial number of the font. The serial
- * number is increased every time a setting on the font is
- * changed, using a setter function.
- *
- * Return value: serial number
- *
- * Since: 4.4.0
- **/
-unsigned int
-hb_font_get_serial (hb_font_t *font)
-{
- return font->serial;
-}
-
-/**
- * hb_font_changed:
- * @font: #hb_font_t to work upon
- *
- * Notifies the @font that underlying font data has changed.
- * This has the effect of increasing the serial as returned
- * by hb_font_get_serial(), which invalidates internal caches.
- *
- * Since: 4.4.0
- **/
-void
-hb_font_changed (hb_font_t *font)
-{
- if (hb_object_is_immutable (font))
- return;
-
- font->serial++;
-
- font->mults_changed ();
+ return font->immutable;
}
/**
* hb_font_set_parent:
- * @font: #hb_font_t to work upon
- * @parent: The parent font object to assign
+ * @font: a font.
+ * @parent: new parent.
*
- * Sets the parent font of @font.
+ * Sets parent font of @font.
*
* Since: 1.0.5
**/
@@ -2133,14 +1355,9 @@ void
hb_font_set_parent (hb_font_t *font,
hb_font_t *parent)
{
- if (hb_object_is_immutable (font))
- return;
-
- if (parent == font->parent)
+ if (font->immutable)
return;
- font->serial++;
-
if (!parent)
parent = hb_font_get_empty ();
@@ -2153,11 +1370,11 @@ hb_font_set_parent (hb_font_t *font,
/**
* hb_font_get_parent:
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Fetches the parent font of @font.
+ *
*
- * Return value: (transfer none): The parent font object
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
@@ -2169,10 +1386,10 @@ hb_font_get_parent (hb_font_t *font)
/**
* hb_font_set_face:
- * @font: #hb_font_t to work upon
- * @face: The #hb_face_t to assign
+ * @font: a font.
+ * @face: new face.
*
- * Sets @face as the font-face value of @font.
+ * Sets font-face of @font.
*
* Since: 1.4.3
**/
@@ -2180,33 +1397,26 @@ void
hb_font_set_face (hb_font_t *font,
hb_face_t *face)
{
- if (hb_object_is_immutable (font))
+ if (font->immutable)
return;
- if (face == font->face)
- return;
-
- font->serial++;
-
if (unlikely (!face))
face = hb_face_get_empty ();
hb_face_t *old = font->face;
- hb_face_make_immutable (face);
font->face = hb_face_reference (face);
- font->mults_changed ();
hb_face_destroy (old);
}
/**
* hb_font_get_face:
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Fetches the face associated with the specified font object.
+ *
*
- * Return value: (transfer none): The #hb_face_t value
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
@@ -2219,13 +1429,12 @@ hb_font_get_face (hb_font_t *font)
/**
* hb_font_set_funcs:
- * @font: #hb_font_t to work upon
- * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure.
- * @font_data: Data to attach to @font
- * @destroy: (nullable): The function to call when @font_data is not needed anymore
+ * @font: a font.
+ * @klass: (closure font_data) (destroy destroy) (scope notified):
+ * @font_data:
+ * @destroy:
*
- * Replaces the font-functions structure attached to a font, updating
- * the font's user-data with @font-data and the @destroy callback.
+ *
*
* Since: 0.9.2
**/
@@ -2233,17 +1442,14 @@ void
hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_t *klass,
void *font_data,
- hb_destroy_func_t destroy /* May be NULL. */)
+ hb_destroy_func_t destroy)
{
- if (hb_object_is_immutable (font))
- {
+ if (font->immutable) {
if (destroy)
destroy (font_data);
return;
}
- font->serial++;
-
if (font->destroy)
font->destroy (font->user_data);
@@ -2259,30 +1465,26 @@ hb_font_set_funcs (hb_font_t *font,
/**
* hb_font_set_funcs_data:
- * @font: #hb_font_t to work upon
- * @font_data: (destroy destroy) (scope notified): Data to attach to @font
- * @destroy: (nullable): The function to call when @font_data is not needed anymore
+ * @font: a font.
+ * @font_data: (destroy destroy) (scope notified):
+ * @destroy:
*
- * Replaces the user data attached to a font, updating the font's
- * @destroy callback.
+ *
*
* Since: 0.9.2
**/
void
hb_font_set_funcs_data (hb_font_t *font,
void *font_data,
- hb_destroy_func_t destroy /* May be NULL. */)
+ hb_destroy_func_t destroy)
{
/* Destroy user_data? */
- if (hb_object_is_immutable (font))
- {
+ if (font->immutable) {
if (destroy)
destroy (font_data);
return;
}
- font->serial++;
-
if (font->destroy)
font->destroy (font->user_data);
@@ -2293,71 +1495,40 @@ hb_font_set_funcs_data (hb_font_t *font,
/**
* hb_font_set_scale:
- * @font: #hb_font_t to work upon
- * @x_scale: Horizontal scale value to assign
- * @y_scale: Vertical scale value to assign
- *
- * Sets the horizontal and vertical scale of a font.
- *
- * The font scale is a number related to, but not the same as,
- * font size. Typically the client establishes a scale factor
- * to be used between the two. For example, 64, or 256, which
- * would be the fractional-precision part of the font scale.
- * This is necessary because #hb_position_t values are integer
- * types and you need to leave room for fractional values
- * in there.
- *
- * For example, to set the font size to 20, with 64
- * levels of fractional precision you would call
- * `hb_font_set_scale(font, 20 * 64, 20 * 64)`.
- *
- * In the example above, even what font size 20 means is up to
- * you. It might be 20 pixels, or 20 points, or 20 millimeters.
- * HarfBuzz does not care about that. You can set the point
- * size of the font using hb_font_set_ptem(), and the pixel
- * size using hb_font_set_ppem().
- *
- * The choice of scale is yours but needs to be consistent between
- * what you set here, and what you expect out of #hb_position_t
- * as well has draw / paint API output values.
+ * @font: a font.
+ * @x_scale:
+ * @y_scale:
*
- * Fonts default to a scale equal to the UPEM value of their face.
- * A font with this setting is sometimes called an "unscaled" font.
+ *
*
* Since: 0.9.2
**/
void
hb_font_set_scale (hb_font_t *font,
- int x_scale,
- int y_scale)
+ int x_scale,
+ int y_scale)
{
- if (hb_object_is_immutable (font))
- return;
-
- if (font->x_scale == x_scale && font->y_scale == y_scale)
+ if (font->immutable)
return;
- font->serial++;
-
font->x_scale = x_scale;
font->y_scale = y_scale;
- font->mults_changed ();
}
/**
* hb_font_get_scale:
- * @font: #hb_font_t to work upon
- * @x_scale: (out): Horizontal scale value
- * @y_scale: (out): Vertical scale value
+ * @font: a font.
+ * @x_scale: (out):
+ * @y_scale: (out):
*
- * Fetches the horizontal and vertical scale of a font.
+ *
*
* Since: 0.9.2
**/
void
hb_font_get_scale (hb_font_t *font,
- int *x_scale,
- int *y_scale)
+ int *x_scale,
+ int *y_scale)
{
if (x_scale) *x_scale = font->x_scale;
if (y_scale) *y_scale = font->y_scale;
@@ -2365,47 +1536,38 @@ hb_font_get_scale (hb_font_t *font,
/**
* hb_font_set_ppem:
- * @font: #hb_font_t to work upon
- * @x_ppem: Horizontal ppem value to assign
- * @y_ppem: Vertical ppem value to assign
- *
- * Sets the horizontal and vertical pixels-per-em (PPEM) of a font.
+ * @font: a font.
+ * @x_ppem:
+ * @y_ppem:
*
- * These values are used for pixel-size-specific adjustment to
- * shaping and draw results, though for the most part they are
- * unused and can be left unset.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_set_ppem (hb_font_t *font,
- unsigned int x_ppem,
- unsigned int y_ppem)
+hb_font_set_ppem (hb_font_t *font,
+ unsigned int x_ppem,
+ unsigned int y_ppem)
{
- if (hb_object_is_immutable (font))
- return;
-
- if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
+ if (font->immutable)
return;
- font->serial++;
-
font->x_ppem = x_ppem;
font->y_ppem = y_ppem;
}
/**
* hb_font_get_ppem:
- * @font: #hb_font_t to work upon
- * @x_ppem: (out): Horizontal ppem value
- * @y_ppem: (out): Vertical ppem value
+ * @font: a font.
+ * @x_ppem: (out):
+ * @y_ppem: (out):
*
- * Fetches the horizontal and vertical points-per-em (ppem) of a font.
+ *
*
* Since: 0.9.2
**/
void
-hb_font_get_ppem (hb_font_t *font,
+hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem)
{
@@ -2415,41 +1577,31 @@ hb_font_get_ppem (hb_font_t *font,
/**
* hb_font_set_ptem:
- * @font: #hb_font_t to work upon
- * @ptem: font size in points.
- *
- * Sets the "point size" of a font. Set to zero to unset.
- * Used in CoreText to implement optical sizing.
+ * @font: a font.
+ * @ptem:
*
- * <note>Note: There are 72 points in an inch.</note>
+ * Sets "point size" of the font.
*
* Since: 1.6.0
**/
void
-hb_font_set_ptem (hb_font_t *font,
- float ptem)
+hb_font_set_ptem (hb_font_t *font, float ptem)
{
- if (hb_object_is_immutable (font))
+ if (font->immutable)
return;
- if (font->ptem == ptem)
- return;
-
- font->serial++;
-
font->ptem = ptem;
}
/**
* hb_font_get_ptem:
- * @font: #hb_font_t to work upon
+ * @font: a font.
*
- * Fetches the "point size" of a font. Used in CoreText to
- * implement optical sizing.
+ * Gets the "point size" of the font. A value of 0 means unset.
*
- * Return value: Point size. A value of zero means "not set."
+ * Return value: Point size.
*
- * Since: 1.6.0
+ * Since: 0.9.2
**/
float
hb_font_get_ptem (hb_font_t *font)
@@ -2457,433 +1609,106 @@ hb_font_get_ptem (hb_font_t *font)
return font->ptem;
}
-/**
- * hb_font_set_synthetic_bold:
- * @font: #hb_font_t to work upon
- * @x_embolden: the amount to embolden horizontally
- * @y_embolden: the amount to embolden vertically
- * @in_place: whether to embolden glyphs in-place
- *
- * Sets the "synthetic boldness" of a font.
- *
- * Positive values for @x_embolden / @y_embolden make a font
- * bolder, negative values thinner. Typical values are in the
- * 0.01 to 0.05 range. The default value is zero.
- *
- * Synthetic boldness is applied by offsetting the contour
- * points of the glyph shape.
- *
- * Synthetic boldness is applied when rendering a glyph via
- * hb_font_draw_glyph().
- *
- * If @in_place is `false`, then glyph advance-widths are also
- * adjusted, otherwise they are not. The in-place mode is
- * useful for simulating [font grading](https://fonts.google.com/knowledge/glossary/grade).
- *
- *
- * Since: 7.0.0
- **/
-void
-hb_font_set_synthetic_bold (hb_font_t *font,
- float x_embolden,
- float y_embolden,
- hb_bool_t in_place)
-{
- if (hb_object_is_immutable (font))
- return;
-
- if (font->x_embolden == x_embolden &&
- font->y_embolden == y_embolden &&
- font->embolden_in_place == (bool) in_place)
- return;
-
- font->serial++;
-
- font->x_embolden = x_embolden;
- font->y_embolden = y_embolden;
- font->embolden_in_place = in_place;
- font->mults_changed ();
-}
-
-/**
- * hb_font_get_synthetic_bold:
- * @font: #hb_font_t to work upon
- * @x_embolden: (out): return location for horizontal value
- * @y_embolden: (out): return location for vertical value
- * @in_place: (out): return location for in-place value
- *
- * Fetches the "synthetic boldness" parameters of a font.
- *
- * Since: 7.0.0
- **/
-void
-hb_font_get_synthetic_bold (hb_font_t *font,
- float *x_embolden,
- float *y_embolden,
- hb_bool_t *in_place)
-{
- if (x_embolden) *x_embolden = font->x_embolden;
- if (y_embolden) *y_embolden = font->y_embolden;
- if (in_place) *in_place = font->embolden_in_place;
-}
+/*
+ * Variations
+ */
-/**
- * hb_font_set_synthetic_slant:
- * @font: #hb_font_t to work upon
- * @slant: synthetic slant value.
- *
- * Sets the "synthetic slant" of a font. By default is zero.
- * Synthetic slant is the graphical skew applied to the font
- * at rendering time.
- *
- * HarfBuzz needs to know this value to adjust shaping results,
- * metrics, and style values to match the slanted rendering.
- *
- * <note>Note: The glyph shape fetched via the hb_font_draw_glyph()
- * function is slanted to reflect this value as well.</note>
- *
- * <note>Note: The slant value is a ratio. For example, a
- * 20% slant would be represented as a 0.2 value.</note>
- *
- * Since: 3.3.0
- **/
-HB_EXTERN void
-hb_font_set_synthetic_slant (hb_font_t *font, float slant)
+static void
+_hb_font_adopt_var_coords_normalized (hb_font_t *font,
+ int *coords, /* 2.14 normalized */
+ unsigned int coords_length)
{
- if (hb_object_is_immutable (font))
- return;
+ free (font->coords);
- if (font->slant == slant)
- return;
-
- font->serial++;
-
- font->slant = slant;
- font->mults_changed ();
-}
-
-/**
- * hb_font_get_synthetic_slant:
- * @font: #hb_font_t to work upon
- *
- * Fetches the "synthetic slant" of a font.
- *
- * Return value: Synthetic slant. By default is zero.
- *
- * Since: 3.3.0
- **/
-HB_EXTERN float
-hb_font_get_synthetic_slant (hb_font_t *font)
-{
- return font->slant;
+ font->coords = coords;
+ font->num_coords = coords_length;
}
-#ifndef HB_NO_VAR
-/*
- * Variations
- */
-
/**
* hb_font_set_variations:
- * @font: #hb_font_t to work upon
- * @variations: (array length=variations_length): Array of variation settings to apply
- * @variations_length: Number of variations to apply
- *
- * Applies a list of font-variation settings to a font.
- *
- * Note that this overrides all existing variations set on @font.
- * Axes not included in @variations will be effectively set to their
- * default values.
*
* Since: 1.4.2
*/
void
-hb_font_set_variations (hb_font_t *font,
+hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,
- unsigned int variations_length)
+ unsigned int variations_length)
{
- if (hb_object_is_immutable (font))
+ if (font->immutable)
return;
- font->serial_coords = ++font->serial;
-
- if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE)
+ if (!variations_length)
{
hb_font_set_var_coords_normalized (font, nullptr, 0);
return;
}
- const OT::fvar &fvar = *font->face->table.fvar;
- auto axes = fvar.get_axes ();
- const unsigned coords_length = axes.length;
-
- int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
- float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
-
- if (unlikely (coords_length && !(normalized && design_coords)))
- {
- hb_free (normalized);
- hb_free (design_coords);
- return;
- }
-
- /* Initialize design coords. */
- for (unsigned int i = 0; i < coords_length; i++)
- design_coords[i] = axes[i].get_default ();
- if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
- {
- unsigned count = coords_length;
- /* This may fail if index is out-of-range;
- * That's why we initialize design_coords from fvar above
- * unconditionally. */
- hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
- &count, design_coords);
- }
-
- for (unsigned int i = 0; i < variations_length; i++)
- {
- const auto tag = variations[i].tag;
- const auto v = variations[i].value;
- for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
- if (axes[axis_index].axisTag == tag)
- design_coords[axis_index] = v;
- }
- font->face->table.avar->map_coords (normalized, coords_length);
-
- hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
- _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
-}
-
-/**
- * hb_font_set_variation:
- * @font: #hb_font_t to work upon
- * @tag: The #hb_tag_t tag of the variation-axis name
- * @value: The value of the variation axis
- *
- * Change the value of one variation axis on the font.
- *
- * Note: This function is expensive to be called repeatedly.
- * If you want to set multiple variation axes at the same time,
- * use hb_font_set_variations() instead.
- *
- * Since: 7.1.0
- */
-void
-hb_font_set_variation (hb_font_t *font,
- hb_tag_t tag,
- float value)
-{
- if (hb_object_is_immutable (font))
- return;
-
- font->serial_coords = ++font->serial;
-
- // TODO Share some of this code with set_variations()
-
- const OT::fvar &fvar = *font->face->table.fvar;
- auto axes = fvar.get_axes ();
- const unsigned coords_length = axes.length;
-
- int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
- float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
+ unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
- if (unlikely (coords_length && !(normalized && design_coords)))
- {
- hb_free (normalized);
- hb_free (design_coords);
+ int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
+ if (unlikely (coords_length && !normalized))
return;
- }
-
- /* Initialize design coords. */
- if (font->design_coords)
- {
- assert (coords_length == font->num_coords);
- for (unsigned int i = 0; i < coords_length; i++)
- design_coords[i] = font->design_coords[i];
- }
- else
- {
- for (unsigned int i = 0; i < coords_length; i++)
- design_coords[i] = axes[i].get_default ();
- if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
- {
- unsigned count = coords_length;
- /* This may fail if index is out-of-range;
- * That's why we initialize design_coords from fvar above
- * unconditionally. */
- hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
- &count, design_coords);
- }
- }
-
- for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
- if (axes[axis_index].axisTag == tag)
- design_coords[axis_index] = value;
-
- font->face->table.avar->map_coords (normalized, coords_length);
-
- hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
- _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
+ 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:
- * @font: #hb_font_t to work upon
- * @coords: (array length=coords_length): Array of variation coordinates to apply
- * @coords_length: Number of coordinates to apply
- *
- * Applies a list of variation coordinates (in design-space units)
- * to a font.
- *
- * Note that this overrides all existing variations set on @font.
- * Axes not included in @coords will be effectively set to their
- * default values.
*
* Since: 1.4.2
*/
void
-hb_font_set_var_coords_design (hb_font_t *font,
- const float *coords,
- unsigned int coords_length)
+hb_font_set_var_coords_design (hb_font_t *font,
+ const float *coords,
+ unsigned int coords_length)
{
- if (hb_object_is_immutable (font))
+ if (font->immutable)
return;
- font->serial_coords = ++font->serial;
-
- int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
- float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
-
- if (unlikely (coords_length && !(normalized && design_coords)))
- {
- hb_free (normalized);
- hb_free (design_coords);
+ int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
+ if (unlikely (coords_length && !normalized))
return;
- }
-
- if (coords_length)
- hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
- _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
-}
-
-/**
- * hb_font_set_var_named_instance:
- * @font: a font.
- * @instance_index: named instance index.
- *
- * Sets design coords of a font from a named-instance index.
- *
- * Since: 2.6.0
- */
-void
-hb_font_set_var_named_instance (hb_font_t *font,
- unsigned int instance_index)
-{
- if (hb_object_is_immutable (font))
- return;
-
- if (font->instance_index == instance_index)
- return;
-
- font->serial_coords = ++font->serial;
-
- font->instance_index = instance_index;
- hb_font_set_variations (font, nullptr, 0);
-}
-
-/**
- * hb_font_get_var_named_instance:
- * @font: a font.
- *
- * Returns the currently-set named-instance index of the font.
- *
- * Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE.
- *
- * Since: 7.0.0
- **/
-unsigned int
-hb_font_get_var_named_instance (hb_font_t *font)
-{
- return font->instance_index;
+ _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
/**
* hb_font_set_var_coords_normalized:
- * @font: #hb_font_t to work upon
- * @coords: (array length=coords_length): Array of variation coordinates to apply
- * @coords_length: Number of coordinates to apply
- *
- * Applies a list of variation coordinates (in normalized units)
- * to a font.
- *
- * Note that this overrides all existing variations set on @font.
- * Axes not included in @coords will be effectively set to their
- * default values.
- *
- * <note>Note: Coordinates should be normalized to 2.14.</note>
*
* Since: 1.4.2
*/
void
-hb_font_set_var_coords_normalized (hb_font_t *font,
- const int *coords, /* 2.14 normalized */
- unsigned int coords_length)
+hb_font_set_var_coords_normalized (hb_font_t *font,
+ const int *coords, /* 2.14 normalized */
+ unsigned int coords_length)
{
- if (hb_object_is_immutable (font))
+ if (font->immutable)
return;
- font->serial_coords = ++font->serial;
-
- int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
- int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
- float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
-
- if (unlikely (coords_length && !(copy && unmapped && design_coords)))
- {
- hb_free (copy);
- hb_free (unmapped);
- hb_free (design_coords);
+ int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
+ if (unlikely (coords_length && !copy))
return;
- }
if (coords_length)
- {
- hb_memcpy (copy, coords, coords_length * sizeof (coords[0]));
- hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
- }
-
- /* Best effort design coords simulation */
- font->face->table.avar->unmap_coords (unmapped, coords_length);
- for (unsigned int i = 0; i < coords_length; ++i)
- design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]);
- hb_free (unmapped);
+ memcpy (copy, coords, coords_length * sizeof (coords[0]));
- _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
+ _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
}
/**
* hb_font_get_var_coords_normalized:
- * @font: #hb_font_t to work upon
- * @length: (out): Number of coordinates retrieved
- *
- * Fetches the list of normalized variation coordinates currently
- * set on a font.
- *
- * Note that this returned array may only contain values for some
- * (or none) of the axes; omitted axes effectively have zero values.
*
* Return value is valid as long as variation coordinates of the font
* are not modified.
*
- * Return value: coordinates array
- *
* Since: 1.4.2
*/
const int *
-hb_font_get_var_coords_normalized (hb_font_t *font,
+hb_font_get_var_coords_normalized (hb_font_t *font,
unsigned int *length)
{
if (length)
@@ -2892,37 +1717,9 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
return font->coords;
}
-/**
- * hb_font_get_var_coords_design:
- * @font: #hb_font_t to work upon
- * @length: (out): Number of coordinates retrieved
- *
- * Fetches the list of variation coordinates (in design-space units) currently
- * set on a font.
- *
- * Note that this returned array may only contain values for some
- * (or none) of the axes; omitted axes effectively have their default
- * values.
- *
- * Return value is valid as long as variation coordinates of the font
- * are not modified.
- *
- * Return value: coordinates array
- *
- * Since: 3.3.0
- */
-const float *
-hb_font_get_var_coords_design (hb_font_t *font,
- unsigned int *length)
-{
- if (length)
- *length = font->num_coords;
-
- return font->design_coords;
-}
-#endif
#ifndef HB_DISABLE_DEPRECATED
+
/*
* Deprecated get_glyph_func():
*/
@@ -2949,7 +1746,7 @@ trampoline_create (FuncType func,
{
typedef hb_trampoline_t<FuncType> trampoline_t;
- trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t));
+ trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
if (unlikely (!trampoline))
return nullptr;
@@ -2978,29 +1775,29 @@ trampoline_destroy (void *user_data)
if (closure->destroy)
closure->destroy (closure->user_data);
- hb_free (closure);
+ free (closure);
}
typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
static hb_bool_t
-hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
+hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t unicode,
hb_codepoint_t *glyph,
- void *user_data)
+ void *user_data)
{
hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
}
static hb_bool_t
-hb_font_get_variation_glyph_trampoline (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
+hb_font_get_variation_glyph_trampoline (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
- void *user_data)
+ void *user_data)
{
hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
@@ -3008,10 +1805,10 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font,
/**
* hb_font_funcs_set_glyph_func:
- * @ffuncs: The font-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): callback function
- * @user_data: data to pass to @func
- * @destroy: (nullable): function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
* Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and
* hb_font_funcs_set_variation_glyph_func() instead.
@@ -3020,18 +1817,10 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font,
* Deprecated: 1.2.3
**/
void
-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 /* May be NULL. */)
+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)
{
- if (hb_object_is_immutable (ffuncs))
- {
- if (destroy)
- destroy (user_data);
- return;
- }
-
hb_font_get_glyph_trampoline_t *trampoline;
trampoline = trampoline_create (func, user_data, destroy);
@@ -3042,27 +1831,16 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
return;
}
- /* Since we pass it to two destroying functions. */
- trampoline_reference (&trampoline->closure);
-
hb_font_funcs_set_nominal_glyph_func (ffuncs,
hb_font_get_nominal_glyph_trampoline,
trampoline,
trampoline_destroy);
+ trampoline_reference (&trampoline->closure);
hb_font_funcs_set_variation_glyph_func (ffuncs,
hb_font_get_variation_glyph_trampoline,
trampoline,
trampoline_destroy);
}
-#endif
-
-void
-hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_shape_func_t func,
- void *user_data,
- hb_destroy_func_t destroy /* May be NULL. */)
-{
- hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
-}
+#endif /* HB_DISABLE_DEPRECATED */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h
index f3b589bd0d8..540cdcab953 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -33,28 +33,17 @@
#include "hb-common.h"
#include "hb-face.h"
-#include "hb-draw.h"
-#include "hb-paint.h"
HB_BEGIN_DECLS
+
+typedef struct hb_font_t hb_font_t;
+
+
/*
* hb_font_funcs_t
*/
-/**
- * hb_font_funcs_t:
- *
- * Data type containing a set of virtual methods used for
- * working on #hb_font_t font objects.
- *
- * HarfBuzz provides a lightweight default function for each of
- * the methods in #hb_font_funcs_t. Client programs can implement
- * their own replacements for the individual font functions, as
- * needed, and replace the default by calling the setter for a
- * method.
- *
- **/
typedef struct hb_font_funcs_t hb_font_funcs_t;
HB_EXTERN hb_font_funcs_t *
@@ -78,8 +67,8 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
HB_EXTERN void *
-hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs,
- hb_user_data_key_t *key);
+hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
+ hb_user_data_key_t *key);
HB_EXTERN void
@@ -89,23 +78,14 @@ HB_EXTERN hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
-/* font extents */
+/* font and glyph extents */
-/**
- * hb_font_extents_t:
- * @ascender: The height of typographic ascenders.
- * @descender: The depth of typographic descenders.
- * @line_gap: The suggested line-spacing gap.
- *
- * Font-wide extent values, measured in font units.
- *
- * Note that typically @ascender is positive and @descender
- * negative, in coordinate systems that grow up.
- **/
-typedef struct hb_font_extents_t {
- hb_position_t ascender;
- hb_position_t descender;
- hb_position_t line_gap;
+/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */
+typedef struct hb_font_extents_t
+{
+ hb_position_t ascender; /* typographic ascender. */
+ hb_position_t descender; /* typographic descender. */
+ hb_position_t line_gap; /* suggested line spacing gap. */
/*< private >*/
hb_position_t reserved9;
hb_position_t reserved8;
@@ -118,443 +98,84 @@ typedef struct hb_font_extents_t {
hb_position_t reserved1;
} hb_font_extents_t;
+/* Note that height is negative in coordinate systems that grow up. */
+typedef struct hb_glyph_extents_t
+{
+ hb_position_t x_bearing; /* left side of glyph from origin. */
+ hb_position_t y_bearing; /* top side of glyph from origin. */
+ hb_position_t width; /* distance from left to right side. */
+ hb_position_t height; /* distance from top to bottom side. */
+} hb_glyph_extents_t;
+
/* func types */
-/**
- * hb_font_get_font_extents_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @extents: (out): The font extents retrieved
- * @user_data: User data pointer passed by the caller
- *
- * This method should retrieve the extents for a font.
- *
- **/
typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data,
- hb_font_extents_t *extents,
+ hb_font_extents_t *metrics,
void *user_data);
-
-/**
- * hb_font_get_font_h_extents_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the extents for a font, for horizontal-direction
- * text segments. Extents must be returned in an #hb_glyph_extents output
- * parameter.
- *
- **/
typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t;
-
-/**
- * hb_font_get_font_v_extents_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the extents for a font, for vertical-direction
- * text segments. Extents must be returned in an #hb_glyph_extents output
- * parameter.
- *
- **/
typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t;
-/**
- * hb_font_get_nominal_glyph_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @unicode: The Unicode code point to query
- * @glyph: (out): The glyph ID retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the nominal glyph ID for a specified Unicode code
- * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
void *user_data);
-
-/**
- * hb_font_get_variation_glyph_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @unicode: The Unicode code point to query
- * @variation_selector: The variation-selector code point to query
- * @glyph: (out): The glyph ID retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the glyph ID for a specified Unicode code point
- * followed by a specified Variation Selector code point. Glyph IDs must be
- * returned in a #hb_codepoint_t output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data);
-/**
- * hb_font_get_nominal_glyphs_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @count: number of code points to query
- * @first_unicode: The first Unicode code point to query
- * @unicode_stride: The stride between successive code points
- * @first_glyph: (out): The first glyph ID retrieved
- * @glyph_stride: The stride between successive glyph IDs
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the nominal glyph IDs for a sequence of
- * Unicode code points. Glyph IDs must be returned in a #hb_codepoint_t
- * output parameter.
- *
- * Return value: the number of code points processed
- *
- **/
-typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- void *user_data);
-
-/**
- * hb_font_get_glyph_advance_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advance for a specified glyph. The
- * method must return an #hb_position_t.
- *
- * Return value: The advance of @glyph within @font
- *
- **/
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
void *user_data);
-
-/**
- * hb_font_get_glyph_h_advance_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advance for a specified glyph, in
- * horizontal-direction text segments. Advances must be returned in
- * an #hb_position_t output parameter.
- *
- **/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
-
-/**
- * hb_font_get_glyph_v_advance_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advance for a specified glyph, in
- * vertical-direction text segments. Advances must be returned in
- * an #hb_position_t output parameter.
- *
- **/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
-/**
- * hb_font_get_glyph_advances_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @count: The number of glyph IDs in the sequence queried
- * @first_glyph: The first glyph ID to query
- * @glyph_stride: The stride between successive glyph IDs
- * @first_advance: (out): The first advance retrieved
- * @advance_stride: The stride between successive advances
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advances for a sequence of glyphs.
- *
- **/
-typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride,
- void *user_data);
-
-/**
- * hb_font_get_glyph_h_advances_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advances for a sequence of glyphs, in
- * horizontal-direction text segments.
- *
- **/
-typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_h_advances_func_t;
-
-/**
- * hb_font_get_glyph_v_advances_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the advances for a sequence of glyphs, in
- * vertical-direction text segments.
- *
- **/
-typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t;
-
-/**
- * hb_font_get_glyph_origin_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @x: (out): The X coordinate of the origin
- * @y: (out): The Y coordinate of the origin
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the (X,Y) coordinates (in font units) of the
- * origin for a glyph. Each coordinate must be returned in an #hb_position_t
- * output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y,
void *user_data);
-
-/**
- * hb_font_get_glyph_h_origin_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the (X,Y) coordinates (in font units) of the
- * origin for a glyph, for horizontal-direction text segments. Each
- * coordinate must be returned in an #hb_position_t output parameter.
- *
- **/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
-
-/**
- * hb_font_get_glyph_v_origin_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the (X,Y) coordinates (in font units) of the
- * origin for a glyph, for vertical-direction text segments. Each coordinate
- * must be returned in an #hb_position_t output parameter.
- *
- **/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
-/**
- * hb_font_get_glyph_kerning_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @first_glyph: The glyph ID of the first glyph in the glyph pair
- * @second_glyph: The glyph ID of the second glyph in the glyph pair
- * @user_data: User data pointer passed by the caller
- *
- * This method should retrieve the kerning-adjustment value for a glyph-pair in
- * the specified font, for horizontal text segments.
- *
- **/
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
-/**
- * hb_font_get_glyph_h_kerning_func_t:
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the kerning-adjustment value for a glyph-pair in
- * the specified font, for horizontal text segments.
- *
- **/
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
-/**
- * hb_font_get_glyph_extents_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @extents: (out): The #hb_glyph_extents_t retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the extents for a specified glyph. Extents must be
- * returned in an #hb_glyph_extents output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data);
-
-/**
- * hb_font_get_glyph_contour_point_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @point_index: The contour-point index to query
- * @x: (out): The X value retrieved for the contour point
- * @y: (out): The Y value retrieved for the contour point
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the (X,Y) coordinates (in font units) for a
- * specified contour point in a glyph. Each coordinate must be returned as
- * an #hb_position_t output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y,
void *user_data);
-/**
- * hb_font_get_glyph_name_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @name: (out) (array length=size): Name string retrieved for the glyph ID
- * @size: Length of the glyph-name string retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the glyph name that corresponds to a
- * glyph ID. The name should be returned in a string output parameter.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
char *name, unsigned int size,
void *user_data);
-
-/**
- * hb_font_get_glyph_from_name_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @name: (array length=len): The name string to query
- * @len: The length of the name queried
- * @glyph: (out): The glyph ID retrieved
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * This method should retrieve the glyph ID that corresponds to a glyph-name
- * string.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
void *user_data);
-/**
- * hb_font_get_glyph_shape_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @draw_funcs: The draw functions to send the shape data to
- * @draw_data: The data accompanying the draw functions
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
- **/
-typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs, void *draw_data,
- void *user_data);
-
-/**
- * hb_font_draw_glyph_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @draw_funcs: The draw functions to send the shape data to
- * @draw_data: The data accompanying the draw functions
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * Since: 7.0.0
- *
- **/
-typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs, void *draw_data,
- void *user_data);
-
-/**
- * hb_font_paint_glyph_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @paint_funcs: The paint functions to use
- * @paint_data: The data accompanying the paint functions
- * @palette_index: The color palette to use
- * @foreground: The foreground color
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data,
- hb_codepoint_t glyph,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- unsigned int palette_index,
- hb_color_t foreground,
- void *user_data);
/* func setters */
/**
* hb_font_funcs_set_font_h_extents_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
*
- * Sets the implementation function for #hb_font_get_font_h_extents_func_t.
*
* Since: 1.1.2
**/
@@ -565,12 +186,12 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_font_v_extents_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
*
- * Sets the implementation function for #hb_font_get_font_v_extents_func_t.
*
* Since: 1.1.2
**/
@@ -581,12 +202,12 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_nominal_glyph_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_nominal_glyph_func_t.
+ *
*
* Since: 1.2.3
**/
@@ -596,29 +217,13 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
/**
- * hb_font_funcs_set_nominal_glyphs_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_nominal_glyphs_func_t.
- *
- * Since: 2.0.0
- **/
-HB_EXTERN void
-hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
- hb_font_get_nominal_glyphs_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
* hb_font_funcs_set_variation_glyph_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_variation_glyph_func_t.
+ *
*
* Since: 1.2.3
**/
@@ -629,12 +234,12 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_advance_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_h_advance_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -645,12 +250,12 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_advance_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_v_advance_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -660,45 +265,13 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
/**
- * hb_font_funcs_set_glyph_h_advances_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_h_advances_func_t.
- *
- * Since: 1.8.6
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_h_advances_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_font_funcs_set_glyph_v_advances_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_v_advances_func_t.
- *
- * Since: 1.8.6
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_v_advances_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
* hb_font_funcs_set_glyph_h_origin_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_h_origin_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -709,12 +282,12 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_origin_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_v_origin_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -725,12 +298,12 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_kerning_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_h_kerning_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -740,13 +313,29 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+ hb_font_get_glyph_v_kerning_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+/**
* hb_font_funcs_set_glyph_extents_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_extents_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -757,12 +346,12 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_contour_point_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_contour_point_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -773,12 +362,12 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_name_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_name_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -789,12 +378,12 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_from_name_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_font_get_glyph_from_name_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -803,57 +392,6 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_from_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
-/**
- * hb_font_funcs_set_glyph_shape_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
- * which is the same as #hb_font_draw_glyph_func_t.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_shape_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_font_funcs_set_draw_glyph_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_draw_glyph_func_t,
- * which is the same as #hb_font_get_glyph_shape_func_t.
- *
- * Since: 7.0.0
- **/
-HB_EXTERN void
-hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs,
- hb_font_draw_glyph_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_font_funcs_set_paint_glyph_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is no longer needed
- *
- * Sets the implementation function for #hb_font_paint_glyph_func_t.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs,
- hb_font_paint_glyph_func_t func,
- void *user_data, hb_destroy_func_t destroy);
-
/* func dispatch */
HB_EXTERN hb_bool_t
@@ -872,14 +410,6 @@ hb_font_get_variation_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
-HB_EXTERN unsigned int
-hb_font_get_nominal_glyphs (hb_font_t *font,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride);
-
HB_EXTERN hb_position_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph);
@@ -887,21 +417,6 @@ HB_EXTERN hb_position_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph);
-HB_EXTERN void
-hb_font_get_glyph_h_advances (hb_font_t* font,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride);
-HB_EXTERN void
-hb_font_get_glyph_v_advances (hb_font_t* font,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride);
-
HB_EXTERN hb_bool_t
hb_font_get_glyph_h_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -914,6 +429,9 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+HB_EXTERN hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+ hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
@@ -934,27 +452,11 @@ hb_font_get_glyph_from_name (hb_font_t *font,
const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph);
-HB_EXTERN void
-hb_font_get_glyph_shape (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *dfuncs, void *draw_data);
-
-HB_EXTERN void
-hb_font_draw_glyph (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *dfuncs, void *draw_data);
-
-HB_EXTERN void
-hb_font_paint_glyph (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_paint_funcs_t *pfuncs, void *paint_data,
- unsigned int palette_index,
- hb_color_t foreground);
/* high-level funcs, with fallback */
/* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
- * otherwise calls hb_font_get_variation_glyph(). */
+ * otherwise callse hb_font_get_variation_glyph(). */
HB_EXTERN hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
@@ -970,14 +472,6 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN void
-hb_font_get_glyph_advances_for_direction (hb_font_t* font,
- hb_direction_t direction,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride);
-HB_EXTERN void
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
@@ -1053,7 +547,7 @@ hb_font_set_user_data (hb_font_t *font,
HB_EXTERN void *
-hb_font_get_user_data (const hb_font_t *font,
+hb_font_get_user_data (hb_font_t *font,
hb_user_data_key_t *key);
HB_EXTERN void
@@ -1062,12 +556,6 @@ hb_font_make_immutable (hb_font_t *font);
HB_EXTERN hb_bool_t
hb_font_is_immutable (hb_font_t *font);
-HB_EXTERN unsigned int
-hb_font_get_serial (hb_font_t *font);
-
-HB_EXTERN void
-hb_font_changed (hb_font_t *font);
-
HB_EXTERN void
hb_font_set_parent (hb_font_t *font,
hb_font_t *parent);
@@ -1092,8 +580,8 @@ hb_font_set_funcs (hb_font_t *font,
/* Be *very* careful with this function! */
HB_EXTERN void
hb_font_set_funcs_data (hb_font_t *font,
- void *font_data,
- hb_destroy_func_t destroy);
+ void *font_data,
+ hb_destroy_func_t destroy);
HB_EXTERN void
@@ -1130,40 +618,15 @@ HB_EXTERN float
hb_font_get_ptem (hb_font_t *font);
HB_EXTERN void
-hb_font_set_synthetic_bold (hb_font_t *font,
- float x_embolden, float y_embolden,
- hb_bool_t in_place);
-
-HB_EXTERN void
-hb_font_get_synthetic_bold (hb_font_t *font,
- float *x_embolden, float *y_embolden,
- hb_bool_t *in_place);
-
-HB_EXTERN void
-hb_font_set_synthetic_slant (hb_font_t *font, float slant);
-
-HB_EXTERN float
-hb_font_get_synthetic_slant (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_variation (hb_font_t *font,
- hb_tag_t tag,
- float value);
-
-HB_EXTERN void
hb_font_set_var_coords_design (hb_font_t *font,
const float *coords,
unsigned int coords_length);
-HB_EXTERN const float *
-hb_font_get_var_coords_design (hb_font_t *font,
- unsigned int *length);
-
HB_EXTERN void
hb_font_set_var_coords_normalized (hb_font_t *font,
const int *coords, /* 2.14 normalized */
@@ -1173,24 +636,6 @@ HB_EXTERN const int *
hb_font_get_var_coords_normalized (hb_font_t *font,
unsigned int *length);
-/**
- * HB_FONT_NO_VAR_NAMED_INSTANCE:
- *
- * Constant signifying that a font does not have any
- * named-instance index set. This is the default of
- * a font.
- *
- * Since: 7.0.0
- */
-#define HB_FONT_NO_VAR_NAMED_INSTANCE 0xFFFFFFFF
-
-HB_EXTERN void
-hb_font_set_var_named_instance (hb_font_t *font,
- unsigned int instance_index);
-
-HB_EXTERN unsigned int
-hb_font_get_var_named_instance (hb_font_t *font);
-
HB_END_DECLS
#endif /* HB_FONT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.hh b/src/3rdparty/harfbuzz-ng/src/hb-font.hh
deleted file mode 100644
index f503575c34a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.hh
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2011 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_FONT_HH
-#define HB_FONT_HH
-
-#include "hb.hh"
-
-#include "hb-face.hh"
-#include "hb-shaper.hh"
-
-
-/*
- * hb_font_funcs_t
- */
-
-#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
- HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \
- HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \
- HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \
- HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \
- HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \
- HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \
- HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \
- HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \
- HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \
- /* ^--- Add new callbacks here */
-
-struct hb_font_funcs_t
-{
- hb_object_header_t header;
-
- struct {
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name;
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- } *user_data;
-
- struct {
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name;
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- } *destroy;
-
- /* Don't access these directly. Call font->get_*() instead. */
- union get_t {
- struct get_funcs_t {
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name;
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- } f;
- void (*array[0
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
- ]) ();
- } get;
-};
-DECLARE_NULL_INSTANCE (hb_font_funcs_t);
-
-
-/*
- * hb_font_t
- */
-
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font);
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-
-struct hb_font_t
-{
- hb_object_header_t header;
- unsigned int serial;
- unsigned int serial_coords;
-
- hb_font_t *parent;
- hb_face_t *face;
-
- int32_t x_scale;
- int32_t y_scale;
-
- float x_embolden;
- float y_embolden;
- bool embolden_in_place;
- int32_t x_strength; /* x_embolden, in scaled units. */
- int32_t y_strength; /* y_embolden, in scaled units. */
-
- float slant;
- float slant_xy;
-
- float x_multf;
- float y_multf;
- int64_t x_mult;
- int64_t y_mult;
-
- unsigned int x_ppem;
- unsigned int y_ppem;
-
- float ptem;
-
- /* Font variation coordinates. */
- unsigned int instance_index;
- unsigned int num_coords;
- int *coords;
- float *design_coords;
-
- hb_font_funcs_t *klass;
- void *user_data;
- hb_destroy_func_t destroy;
-
- hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */
-
-
- /* Convert from font-space to user-space */
- int64_t dir_mult (hb_direction_t direction)
- { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
- hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
- hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
- hb_position_t em_scalef_x (float v) { return em_multf (v, x_multf); }
- hb_position_t em_scalef_y (float v) { return em_multf (v, y_multf); }
- float em_fscale_x (int16_t v) { return em_fmult (v, x_multf); }
- float em_fscale_y (int16_t v) { return em_fmult (v, y_multf); }
- float em_fscalef_x (float v) { return em_fmultf (v, x_multf); }
- float em_fscalef_y (float v) { return em_fmultf (v, y_multf); }
- hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
- { return em_mult (v, dir_mult (direction)); }
-
- /* Convert from parent-font user-space to our user-space */
- hb_position_t parent_scale_x_distance (hb_position_t v)
- {
- if (unlikely (parent && parent->x_scale != x_scale))
- return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
- return v;
- }
- hb_position_t parent_scale_y_distance (hb_position_t v)
- {
- if (unlikely (parent && parent->y_scale != y_scale))
- return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
- return v;
- }
- hb_position_t parent_scale_x_position (hb_position_t v)
- { return parent_scale_x_distance (v); }
- hb_position_t parent_scale_y_position (hb_position_t v)
- { return parent_scale_y_distance (v); }
-
- void parent_scale_distance (hb_position_t *x, hb_position_t *y)
- {
- *x = parent_scale_x_distance (*x);
- *y = parent_scale_y_distance (*y);
- }
- void parent_scale_position (hb_position_t *x, hb_position_t *y)
- {
- *x = parent_scale_x_position (*x);
- *y = parent_scale_y_position (*y);
- }
-
- void scale_glyph_extents (hb_glyph_extents_t *extents)
- {
- float x1 = em_fscale_x (extents->x_bearing);
- float y1 = em_fscale_y (extents->y_bearing);
- float x2 = em_fscale_x (extents->x_bearing + extents->width);
- float y2 = em_fscale_y (extents->y_bearing + extents->height);
-
- /* Apply slant. */
- if (slant_xy)
- {
- x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
- x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
- }
-
- extents->x_bearing = floorf (x1);
- extents->y_bearing = floorf (y1);
- extents->width = ceilf (x2) - extents->x_bearing;
- extents->height = ceilf (y2) - extents->y_bearing;
-
- if (x_strength || y_strength)
- {
- /* Y */
- int y_shift = y_strength;
- if (y_scale < 0) y_shift = -y_shift;
- extents->y_bearing += y_shift;
- extents->height -= y_shift;
-
- /* X */
- int x_shift = x_strength;
- if (x_scale < 0) x_shift = -x_shift;
- if (embolden_in_place)
- extents->x_bearing -= x_shift / 2;
- extents->width += x_shift;
- }
- }
-
-
- /* Public getters */
-
- HB_INTERNAL bool has_func (unsigned int i);
- HB_INTERNAL bool has_func_set (unsigned int i);
-
- /* has_* ... */
-#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
- bool \
- has_##name##_func () \
- { \
- hb_font_funcs_t *funcs = this->klass; \
- unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
- return has_func (i); \
- } \
- bool \
- has_##name##_func_set () \
- { \
- hb_font_funcs_t *funcs = this->klass; \
- unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
- return has_func_set (i); \
- }
- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_FONT_FUNC_IMPLEMENT
-
- hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
- {
- hb_memset (extents, 0, sizeof (*extents));
- return klass->get.f.font_h_extents (this, user_data,
- extents,
- !klass->user_data ? nullptr : klass->user_data->font_h_extents);
- }
- hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
- {
- hb_memset (extents, 0, sizeof (*extents));
- return klass->get.f.font_v_extents (this, user_data,
- extents,
- !klass->user_data ? nullptr : klass->user_data->font_v_extents);
- }
-
- bool has_glyph (hb_codepoint_t unicode)
- {
- hb_codepoint_t glyph;
- return get_nominal_glyph (unicode, &glyph);
- }
-
- hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- hb_codepoint_t not_found = 0)
- {
- *glyph = not_found;
- return klass->get.f.nominal_glyph (this, user_data,
- unicode, glyph,
- !klass->user_data ? nullptr : klass->user_data->nominal_glyph);
- }
- unsigned int get_nominal_glyphs (unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride)
- {
- return klass->get.f.nominal_glyphs (this, user_data,
- count,
- first_unicode, unicode_stride,
- first_glyph, glyph_stride,
- !klass->user_data ? nullptr : klass->user_data->nominal_glyphs);
- }
-
- hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph,
- hb_codepoint_t not_found = 0)
- {
- *glyph = not_found;
- return klass->get.f.variation_glyph (this, user_data,
- unicode, variation_selector, glyph,
- !klass->user_data ? nullptr : klass->user_data->variation_glyph);
- }
-
- hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
- {
- return klass->get.f.glyph_h_advance (this, user_data,
- glyph,
- !klass->user_data ? nullptr : klass->user_data->glyph_h_advance);
- }
-
- hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
- {
- return klass->get.f.glyph_v_advance (this, user_data,
- glyph,
- !klass->user_data ? nullptr : klass->user_data->glyph_v_advance);
- }
-
- void get_glyph_h_advances (unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride)
- {
- return klass->get.f.glyph_h_advances (this, user_data,
- count,
- first_glyph, glyph_stride,
- first_advance, advance_stride,
- !klass->user_data ? nullptr : klass->user_data->glyph_h_advances);
- }
-
- void get_glyph_v_advances (unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- hb_position_t *first_advance,
- unsigned int advance_stride)
- {
- return klass->get.f.glyph_v_advances (this, user_data,
- count,
- first_glyph, glyph_stride,
- first_advance, advance_stride,
- !klass->user_data ? nullptr : klass->user_data->glyph_v_advances);
- }
-
- hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- *x = *y = 0;
- return klass->get.f.glyph_h_origin (this, user_data,
- glyph, x, y,
- !klass->user_data ? nullptr : klass->user_data->glyph_h_origin);
- }
-
- hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- *x = *y = 0;
- return klass->get.f.glyph_v_origin (this, user_data,
- glyph, x, y,
- !klass->user_data ? nullptr : klass->user_data->glyph_v_origin);
- }
-
- hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
- hb_codepoint_t right_glyph)
- {
-#ifdef HB_DISABLE_DEPRECATED
- return 0;
-#else
- return klass->get.f.glyph_h_kerning (this, user_data,
- left_glyph, right_glyph,
- !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
-#endif
- }
-
- hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
- hb_codepoint_t bottom_glyph)
- {
-#ifdef HB_DISABLE_DEPRECATED
- return 0;
-#else
- return klass->get.f.glyph_v_kerning (this, user_data,
- top_glyph, bottom_glyph,
- !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
-#endif
- }
-
- hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
- hb_glyph_extents_t *extents)
- {
- hb_memset (extents, 0, sizeof (*extents));
- return klass->get.f.glyph_extents (this, user_data,
- glyph,
- extents,
- !klass->user_data ? nullptr : klass->user_data->glyph_extents);
- }
-
- hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
- hb_position_t *x, hb_position_t *y)
- {
- *x = *y = 0;
- return klass->get.f.glyph_contour_point (this, user_data,
- glyph, point_index,
- x, y,
- !klass->user_data ? nullptr : klass->user_data->glyph_contour_point);
- }
-
- hb_bool_t get_glyph_name (hb_codepoint_t glyph,
- char *name, unsigned int size)
- {
- if (size) *name = '\0';
- return klass->get.f.glyph_name (this, user_data,
- glyph,
- name, size,
- !klass->user_data ? nullptr : klass->user_data->glyph_name);
- }
-
- hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
- hb_codepoint_t *glyph)
- {
- *glyph = 0;
- if (len == -1) len = strlen (name);
- return klass->get.f.glyph_from_name (this, user_data,
- name, len,
- glyph,
- !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
- }
-
- void draw_glyph (hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs, void *draw_data)
- {
- klass->get.f.draw_glyph (this, user_data,
- glyph,
- draw_funcs, draw_data,
- !klass->user_data ? nullptr : klass->user_data->draw_glyph);
- }
-
- void paint_glyph (hb_codepoint_t glyph,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- unsigned int palette,
- hb_color_t foreground)
- {
- klass->get.f.paint_glyph (this, user_data,
- glyph,
- paint_funcs, paint_data,
- palette, foreground,
- !klass->user_data ? nullptr : klass->user_data->paint_glyph);
- }
-
- /* A bit higher-level, and with fallback */
-
- void get_h_extents_with_fallback (hb_font_extents_t *extents)
- {
- if (!get_font_h_extents (extents))
- {
- extents->ascender = y_scale * .8;
- extents->descender = extents->ascender - y_scale;
- extents->line_gap = 0;
- }
- }
- void get_v_extents_with_fallback (hb_font_extents_t *extents)
- {
- if (!get_font_v_extents (extents))
- {
- extents->ascender = x_scale / 2;
- extents->descender = extents->ascender - x_scale;
- extents->line_gap = 0;
- }
- }
-
- void get_extents_for_direction (hb_direction_t direction,
- hb_font_extents_t *extents)
- {
- if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
- get_h_extents_with_fallback (extents);
- else
- get_v_extents_with_fallback (extents);
- }
-
- void get_glyph_advance_for_direction (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- *x = *y = 0;
- if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
- *x = get_glyph_h_advance (glyph);
- else
- *y = get_glyph_v_advance (glyph);
- }
- void get_glyph_advances_for_direction (hb_direction_t direction,
- unsigned int count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride)
- {
- if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
- get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
- else
- get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
- }
-
- void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- *x = get_glyph_h_advance (glyph) / 2;
-
- hb_font_extents_t extents;
- get_h_extents_with_fallback (&extents);
- *y = extents.ascender;
- }
-
- void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- if (!get_glyph_h_origin (glyph, x, y) &&
- get_glyph_v_origin (glyph, x, y))
- {
- hb_position_t dx, dy;
- guess_v_origin_minus_h_origin (glyph, &dx, &dy);
- *x -= dx; *y -= dy;
- }
- }
- void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- if (!get_glyph_v_origin (glyph, x, y) &&
- get_glyph_h_origin (glyph, x, y))
- {
- hb_position_t dx, dy;
- guess_v_origin_minus_h_origin (glyph, &dx, &dy);
- *x += dx; *y += dy;
- }
- }
-
- void get_glyph_origin_for_direction (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
- get_glyph_h_origin_with_fallback (glyph, x, y);
- else
- get_glyph_v_origin_with_fallback (glyph, x, y);
- }
-
- void add_glyph_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
-
- *x += origin_x;
- *y += origin_y;
- }
- void add_glyph_v_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
-
- *x += origin_x;
- *y += origin_y;
- }
- void add_glyph_origin_for_direction (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
-
- *x += origin_x;
- *y += origin_y;
- }
-
- void subtract_glyph_h_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
-
- *x -= origin_x;
- *y -= origin_y;
- }
- void subtract_glyph_v_origin (hb_codepoint_t glyph,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
-
- *x -= origin_x;
- *y -= origin_y;
- }
- void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- hb_position_t origin_x, origin_y;
-
- get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
-
- *x -= origin_x;
- *y -= origin_y;
- }
-
- void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
- *y = 0;
- *x = get_glyph_h_kerning (first_glyph, second_glyph);
- } else {
- *x = 0;
- *y = get_glyph_v_kerning (first_glyph, second_glyph);
- }
- }
-
- hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_glyph_extents_t *extents)
- {
- hb_bool_t ret = get_glyph_extents (glyph, extents);
-
- if (ret)
- subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
-
- return ret;
- }
-
- hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
- hb_direction_t direction,
- hb_position_t *x, hb_position_t *y)
- {
- hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
-
- if (ret)
- subtract_glyph_origin_for_direction (glyph, direction, x, y);
-
- return ret;
- }
-
- /* Generates gidDDD if glyph has no name. */
- void
- glyph_to_string (hb_codepoint_t glyph,
- char *s, unsigned int size)
- {
- if (get_glyph_name (glyph, s, size)) return;
-
- if (size && snprintf (s, size, "gid%u", glyph) < 0)
- *s = '\0';
- }
-
- /* Parses gidDDD and uniUUUU strings automatically. */
- hb_bool_t
- glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
- hb_codepoint_t *glyph)
- {
- if (get_glyph_from_name (s, len, glyph)) return true;
-
- if (len == -1) len = strlen (s);
-
- /* Straight glyph index. */
- if (hb_codepoint_parse (s, len, 10, glyph))
- return true;
-
- if (len > 3)
- {
- /* gidDDD syntax for glyph indices. */
- if (0 == strncmp (s, "gid", 3) &&
- hb_codepoint_parse (s + 3, len - 3, 10, glyph))
- return true;
-
- /* uniUUUU and other Unicode character indices. */
- hb_codepoint_t unichar;
- if (0 == strncmp (s, "uni", 3) &&
- hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
- get_nominal_glyph (unichar, glyph))
- return true;
- }
-
- return false;
- }
-
- void mults_changed ()
- {
- float upem = face->get_upem ();
-
- x_multf = x_scale / upem;
- y_multf = y_scale / upem;
- bool x_neg = x_scale < 0;
- x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
- bool y_neg = y_scale < 0;
- y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem;
-
- x_strength = fabsf (roundf (x_scale * x_embolden));
- y_strength = fabsf (roundf (y_scale * y_embolden));
-
- slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
-
- data.fini ();
- }
-
- hb_position_t em_mult (int16_t v, int64_t mult)
- { return (hb_position_t) ((v * mult + 32768) >> 16); }
- hb_position_t em_multf (float v, float mult)
- { return (hb_position_t) roundf (em_fmultf (v, mult)); }
- float em_fmultf (float v, float mult)
- { return v * mult; }
- float em_fmult (int16_t v, float mult)
- { return (float) v * mult; }
-};
-DECLARE_NULL_INSTANCE (hb_font_t);
-
-
-#endif /* HB_FONT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh b/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh
deleted file mode 100644
index fa5712f9b33..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ft-colr.hh
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_FT_COLR_HH
-#define HB_FT_COLR_HH
-
-#include "hb.hh"
-
-#include "hb-paint-extents.hh"
-
-#include FT_COLOR_H
-
-
-static hb_paint_composite_mode_t
-_hb_ft_paint_composite_mode (FT_Composite_Mode mode)
-{
- switch (mode)
- {
- case FT_COLR_COMPOSITE_CLEAR: return HB_PAINT_COMPOSITE_MODE_CLEAR;
- case FT_COLR_COMPOSITE_SRC: return HB_PAINT_COMPOSITE_MODE_SRC;
- case FT_COLR_COMPOSITE_DEST: return HB_PAINT_COMPOSITE_MODE_DEST;
- case FT_COLR_COMPOSITE_SRC_OVER: return HB_PAINT_COMPOSITE_MODE_SRC_OVER;
- case FT_COLR_COMPOSITE_DEST_OVER: return HB_PAINT_COMPOSITE_MODE_DEST_OVER;
- case FT_COLR_COMPOSITE_SRC_IN: return HB_PAINT_COMPOSITE_MODE_SRC_IN;
- case FT_COLR_COMPOSITE_DEST_IN: return HB_PAINT_COMPOSITE_MODE_DEST_IN;
- case FT_COLR_COMPOSITE_SRC_OUT: return HB_PAINT_COMPOSITE_MODE_SRC_OUT;
- case FT_COLR_COMPOSITE_DEST_OUT: return HB_PAINT_COMPOSITE_MODE_DEST_OUT;
- case FT_COLR_COMPOSITE_SRC_ATOP: return HB_PAINT_COMPOSITE_MODE_SRC_ATOP;
- case FT_COLR_COMPOSITE_DEST_ATOP: return HB_PAINT_COMPOSITE_MODE_DEST_ATOP;
- case FT_COLR_COMPOSITE_XOR: return HB_PAINT_COMPOSITE_MODE_XOR;
- case FT_COLR_COMPOSITE_PLUS: return HB_PAINT_COMPOSITE_MODE_PLUS;
- case FT_COLR_COMPOSITE_SCREEN: return HB_PAINT_COMPOSITE_MODE_SCREEN;
- case FT_COLR_COMPOSITE_OVERLAY: return HB_PAINT_COMPOSITE_MODE_OVERLAY;
- case FT_COLR_COMPOSITE_DARKEN: return HB_PAINT_COMPOSITE_MODE_DARKEN;
- case FT_COLR_COMPOSITE_LIGHTEN: return HB_PAINT_COMPOSITE_MODE_LIGHTEN;
- case FT_COLR_COMPOSITE_COLOR_DODGE: return HB_PAINT_COMPOSITE_MODE_COLOR_DODGE;
- case FT_COLR_COMPOSITE_COLOR_BURN: return HB_PAINT_COMPOSITE_MODE_COLOR_BURN;
- case FT_COLR_COMPOSITE_HARD_LIGHT: return HB_PAINT_COMPOSITE_MODE_HARD_LIGHT;
- case FT_COLR_COMPOSITE_SOFT_LIGHT: return HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT;
- case FT_COLR_COMPOSITE_DIFFERENCE: return HB_PAINT_COMPOSITE_MODE_DIFFERENCE;
- case FT_COLR_COMPOSITE_EXCLUSION: return HB_PAINT_COMPOSITE_MODE_EXCLUSION;
- case FT_COLR_COMPOSITE_MULTIPLY: return HB_PAINT_COMPOSITE_MODE_MULTIPLY;
- case FT_COLR_COMPOSITE_HSL_HUE: return HB_PAINT_COMPOSITE_MODE_HSL_HUE;
- case FT_COLR_COMPOSITE_HSL_SATURATION: return HB_PAINT_COMPOSITE_MODE_HSL_SATURATION;
- case FT_COLR_COMPOSITE_HSL_COLOR: return HB_PAINT_COMPOSITE_MODE_HSL_COLOR;
- case FT_COLR_COMPOSITE_HSL_LUMINOSITY: return HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY;
-
- case FT_COLR_COMPOSITE_MAX: HB_FALLTHROUGH;
- default: return HB_PAINT_COMPOSITE_MODE_CLEAR;
- }
-}
-
-typedef struct hb_ft_paint_context_t hb_ft_paint_context_t;
-
-static void
-_hb_ft_paint (hb_ft_paint_context_t *c,
- FT_OpaquePaint opaque_paint);
-
-struct hb_ft_paint_context_t
-{
- hb_ft_paint_context_t (const hb_ft_font_t *ft_font,
- hb_font_t *font,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- FT_Color *palette,
- unsigned palette_index,
- hb_color_t foreground) :
- ft_font (ft_font), font(font),
- funcs (paint_funcs), data (paint_data),
- palette (palette), palette_index (palette_index), foreground (foreground) {}
-
- void recurse (FT_OpaquePaint paint)
- {
- if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
- depth_left--;
- edge_count--;
- _hb_ft_paint (this, paint);
- depth_left++;
- }
-
- const hb_ft_font_t *ft_font;
- hb_font_t *font;
- hb_paint_funcs_t *funcs;
- void *data;
- FT_Color *palette;
- unsigned palette_index;
- hb_color_t foreground;
- int depth_left = HB_MAX_NESTING_LEVEL;
- int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
-};
-
-static unsigned
-_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line,
- void *color_line_data,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops,
- void *user_data)
-{
- FT_ColorLine *cl = (FT_ColorLine *) color_line_data;
- hb_ft_paint_context_t *c = (hb_ft_paint_context_t *) user_data;
-
- if (count)
- {
- FT_ColorStop stop;
- unsigned wrote = 0;
- FT_ColorStopIterator iter = cl->color_stop_iterator;
-
- if (start >= cl->color_stop_iterator.num_color_stops)
- {
- *count = 0;
- return cl->color_stop_iterator.num_color_stops;
- }
-
- while (cl->color_stop_iterator.current_color_stop < start)
- FT_Get_Colorline_Stops(c->ft_font->ft_face,
- &stop,
- &cl->color_stop_iterator);
-
- while (count && *count &&
- FT_Get_Colorline_Stops(c->ft_font->ft_face,
- &stop,
- &cl->color_stop_iterator))
- {
- // https://github.com/harfbuzz/harfbuzz/issues/4013
- if (sizeof stop.stop_offset == 2)
- color_stops->offset = stop.stop_offset / 16384.f;
- else
- color_stops->offset = stop.stop_offset / 65536.f;
-
- color_stops->is_foreground = stop.color.palette_index == 0xFFFF;
- if (color_stops->is_foreground)
- color_stops->color = HB_COLOR (hb_color_get_blue (c->foreground),
- hb_color_get_green (c->foreground),
- hb_color_get_red (c->foreground),
- (hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
- else
- {
- hb_color_t color;
- if (c->funcs->custom_palette_color (c->data, stop.color.palette_index, &color))
- {
- color_stops->color = HB_COLOR (hb_color_get_blue (color),
- hb_color_get_green (color),
- hb_color_get_red (color),
- (hb_color_get_alpha (color) * stop.color.alpha) >> 14);
- }
- else
- {
- FT_Color ft_color = c->palette[stop.color.palette_index];
- color_stops->color = HB_COLOR (ft_color.blue,
- ft_color.green,
- ft_color.red,
- (ft_color.alpha * stop.color.alpha) >> 14);
- }
- }
-
- color_stops++;
- wrote++;
- }
-
- *count = wrote;
-
- // reset the iterator for next time
- cl->color_stop_iterator = iter;
- }
-
- return cl->color_stop_iterator.num_color_stops;
-}
-
-static hb_paint_extend_t
-_hb_ft_color_line_get_extend (hb_color_line_t *color_line,
- void *color_line_data,
- void *user_data)
-{
- FT_ColorLine *c = (FT_ColorLine *) color_line_data;
- switch (c->extend)
- {
- default:
- case FT_COLR_PAINT_EXTEND_PAD: return HB_PAINT_EXTEND_PAD;
- case FT_COLR_PAINT_EXTEND_REPEAT: return HB_PAINT_EXTEND_REPEAT;
- case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT;
- }
-}
-
-void
-_hb_ft_paint (hb_ft_paint_context_t *c,
- FT_OpaquePaint opaque_paint)
-{
- FT_Face ft_face = c->ft_font->ft_face;
- FT_COLR_Paint paint;
- if (!FT_Get_Paint (ft_face, opaque_paint, &paint))
- return;
-
- switch (paint.format)
- {
- case FT_COLR_PAINTFORMAT_COLR_LAYERS:
- {
- FT_OpaquePaint other_paint = {0};
- while (FT_Get_Paint_Layers (ft_face,
- &paint.u.colr_layers.layer_iterator,
- &other_paint))
- {
- c->funcs->push_group (c->data);
- c->recurse (other_paint);
- c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
- }
- }
- break;
- case FT_COLR_PAINTFORMAT_SOLID:
- {
- bool is_foreground = paint.u.solid.color.palette_index == 0xFFFF;
- hb_color_t color;
- if (is_foreground)
- color = HB_COLOR (hb_color_get_blue (c->foreground),
- hb_color_get_green (c->foreground),
- hb_color_get_red (c->foreground),
- (hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
- else
- {
- if (c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index, &color))
- {
- color = HB_COLOR (hb_color_get_blue (color),
- hb_color_get_green (color),
- hb_color_get_red (color),
- (hb_color_get_alpha (color) * paint.u.solid.color.alpha) >> 14);
- }
- else
- {
- FT_Color ft_color = c->palette[paint.u.solid.color.palette_index];
- color = HB_COLOR (ft_color.blue,
- ft_color.green,
- ft_color.red,
- (ft_color.alpha * paint.u.solid.color.alpha) >> 14);
- }
- }
- c->funcs->color (c->data, is_foreground, color);
- }
- break;
- case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
- {
- hb_color_line_t cl = {
- &paint.u.linear_gradient.colorline,
- _hb_ft_color_line_get_color_stops, c,
- _hb_ft_color_line_get_extend, nullptr
- };
-
- c->funcs->linear_gradient (c->data, &cl,
- paint.u.linear_gradient.p0.x / 65536.f,
- paint.u.linear_gradient.p0.y / 65536.f,
- paint.u.linear_gradient.p1.x / 65536.f,
- paint.u.linear_gradient.p1.y / 65536.f,
- paint.u.linear_gradient.p2.x / 65536.f,
- paint.u.linear_gradient.p2.y / 65536.f);
- }
- break;
- case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
- {
- hb_color_line_t cl = {
- &paint.u.linear_gradient.colorline,
- _hb_ft_color_line_get_color_stops, c,
- _hb_ft_color_line_get_extend, nullptr
- };
-
- c->funcs->radial_gradient (c->data, &cl,
- paint.u.radial_gradient.c0.x / 65536.f,
- paint.u.radial_gradient.c0.y / 65536.f,
- paint.u.radial_gradient.r0 / 65536.f,
- paint.u.radial_gradient.c1.x / 65536.f,
- paint.u.radial_gradient.c1.y / 65536.f,
- paint.u.radial_gradient.r1 / 65536.f);
- }
- break;
- case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT:
- {
- hb_color_line_t cl = {
- &paint.u.linear_gradient.colorline,
- _hb_ft_color_line_get_color_stops, c,
- _hb_ft_color_line_get_extend, nullptr
- };
-
- c->funcs->sweep_gradient (c->data, &cl,
- paint.u.sweep_gradient.center.x / 65536.f,
- paint.u.sweep_gradient.center.y / 65536.f,
- (paint.u.sweep_gradient.start_angle / 65536.f + 1) * HB_PI,
- (paint.u.sweep_gradient.end_angle / 65536.f + 1) * HB_PI);
- }
- break;
- case FT_COLR_PAINTFORMAT_GLYPH:
- {
- c->funcs->push_inverse_root_transform (c->data, c->font);
- c->ft_font->lock.unlock ();
- c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font);
- c->ft_font->lock.lock ();
- c->funcs->push_root_transform (c->data, c->font);
- c->recurse (paint.u.glyph.paint);
- c->funcs->pop_transform (c->data);
- c->funcs->pop_clip (c->data);
- c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_COLR_GLYPH:
- {
- FT_OpaquePaint other_paint = {0};
- if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID,
- FT_COLOR_NO_ROOT_TRANSFORM,
- &other_paint))
- {
- bool has_clip_box;
- FT_ClipBox clip_box;
- has_clip_box = FT_Get_Color_Glyph_ClipBox (ft_face, paint.u.colr_glyph.glyphID, &clip_box);
-
- if (has_clip_box)
- {
- /* The FreeType ClipBox is in scaled coordinates, whereas we need
- * unscaled clipbox here. Oh well...
- */
-
- float upem = c->font->face->get_upem ();
- float xscale = upem / (c->font->x_scale ? c->font->x_scale : upem);
- float yscale = upem / (c->font->y_scale ? c->font->y_scale : upem);
-
- c->funcs->push_clip_rectangle (c->data,
- clip_box.bottom_left.x * xscale,
- clip_box.bottom_left.y * yscale,
- clip_box.top_right.x * xscale,
- clip_box.top_right.y * yscale);
- }
-
- c->recurse (other_paint);
-
- if (has_clip_box)
- c->funcs->pop_clip (c->data);
- }
- }
- break;
- case FT_COLR_PAINTFORMAT_TRANSFORM:
- {
- c->funcs->push_transform (c->data,
- paint.u.transform.affine.xx / 65536.f,
- paint.u.transform.affine.yx / 65536.f,
- paint.u.transform.affine.xy / 65536.f,
- paint.u.transform.affine.yy / 65536.f,
- paint.u.transform.affine.dx / 65536.f,
- paint.u.transform.affine.dy / 65536.f);
- c->recurse (paint.u.transform.paint);
- c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_TRANSLATE:
- {
- float dx = paint.u.translate.dx / 65536.f;
- float dy = paint.u.translate.dy / 65536.f;
-
- bool p1 = c->funcs->push_translate (c->data, dx, dy);
- c->recurse (paint.u.translate.paint);
- if (p1) c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_SCALE:
- {
- float dx = paint.u.scale.center_x / 65536.f;
- float dy = paint.u.scale.center_y / 65536.f;
- float sx = paint.u.scale.scale_x / 65536.f;
- float sy = paint.u.scale.scale_y / 65536.f;
-
- bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
- bool p2 = c->funcs->push_scale (c->data, sx, sy);
- bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
- c->recurse (paint.u.scale.paint);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_ROTATE:
- {
- float dx = paint.u.rotate.center_x / 65536.f;
- float dy = paint.u.rotate.center_y / 65536.f;
- float a = paint.u.rotate.angle / 65536.f;
-
- bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
- bool p2 = c->funcs->push_rotate (c->data, a);
- bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
- c->recurse (paint.u.rotate.paint);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_SKEW:
- {
- float dx = paint.u.skew.center_x / 65536.f;
- float dy = paint.u.skew.center_y / 65536.f;
- float sx = paint.u.skew.x_skew_angle / 65536.f;
- float sy = paint.u.skew.y_skew_angle / 65536.f;
-
- bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
- bool p2 = c->funcs->push_skew (c->data, sx, sy);
- bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
- c->recurse (paint.u.skew.paint);
- if (p3) c->funcs->pop_transform (c->data);
- if (p2) c->funcs->pop_transform (c->data);
- if (p1) c->funcs->pop_transform (c->data);
- }
- break;
- case FT_COLR_PAINTFORMAT_COMPOSITE:
- {
- c->recurse (paint.u.composite.backdrop_paint);
- c->funcs->push_group (c->data);
- c->recurse (paint.u.composite.source_paint);
- c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode));
- }
- break;
-
- case FT_COLR_PAINT_FORMAT_MAX: break;
- default: HB_FALLTHROUGH;
- case FT_COLR_PAINTFORMAT_UNSUPPORTED: break;
- }
-}
-
-
-static bool
-hb_ft_paint_glyph_colr (hb_font_t *font,
- void *font_data,
- hb_codepoint_t gid,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- unsigned int palette_index,
- hb_color_t foreground,
- void *user_data)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- FT_Face ft_face = ft_font->ft_face;
-
- /* Face is locked. */
-
- FT_Error error;
- FT_Color* palette;
- FT_LayerIterator iterator;
-
- FT_Bool have_layers;
- FT_UInt layer_glyph_index;
- FT_UInt layer_color_index;
-
- error = FT_Palette_Select(ft_face, palette_index, &palette);
- if (error)
- palette = NULL;
-
- /* COLRv1 */
- FT_OpaquePaint paint = {0};
- if (FT_Get_Color_Glyph_Paint (ft_face, gid,
- FT_COLOR_NO_ROOT_TRANSFORM,
- &paint))
- {
- hb_ft_paint_context_t c (ft_font, font,
- paint_funcs, paint_data,
- palette, palette_index, foreground);
-
- bool is_bounded = true;
- FT_ClipBox clip_box;
- if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box))
- {
- c.funcs->push_clip_rectangle (c.data,
- clip_box.bottom_left.x +
- roundf (hb_min (font->slant_xy * clip_box.bottom_left.y,
- font->slant_xy * clip_box.top_left.y)),
- clip_box.bottom_left.y,
- clip_box.top_right.x +
- roundf (hb_max (font->slant_xy * clip_box.bottom_right.y,
- font->slant_xy * clip_box.top_right.y)),
- clip_box.top_right.y);
- }
- else
- {
-
- auto *extents_funcs = hb_paint_extents_get_funcs ();
- hb_paint_extents_context_t extents_data;
- hb_ft_paint_context_t ce (ft_font, font,
- extents_funcs, &extents_data,
- palette, palette_index, foreground);
- ce.funcs->push_root_transform (ce.data, font);
- ce.recurse (paint);
- ce.funcs->pop_transform (ce.data);
- hb_extents_t extents = extents_data.get_extents ();
- is_bounded = extents_data.is_bounded ();
-
- c.funcs->push_clip_rectangle (c.data,
- extents.xmin,
- extents.ymin,
- extents.xmax,
- extents.ymax);
- }
-
- c.funcs->push_root_transform (c.data, font);
-
- if (is_bounded)
- c.recurse (paint);
-
- c.funcs->pop_transform (c.data);
- c.funcs->pop_clip (c.data);
-
- return true;
- }
-
- /* COLRv0 */
- iterator.p = NULL;
- have_layers = FT_Get_Color_Glyph_Layer(ft_face,
- gid,
- &layer_glyph_index,
- &layer_color_index,
- &iterator);
-
- if (palette && have_layers)
- {
- do
- {
- hb_bool_t is_foreground = true;
- hb_color_t color = foreground;
-
- if ( layer_color_index != 0xFFFF )
- {
- FT_Color layer_color = palette[layer_color_index];
- color = HB_COLOR (layer_color.blue,
- layer_color.green,
- layer_color.red,
- layer_color.alpha);
- is_foreground = false;
- }
-
- ft_font->lock.unlock ();
- paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font);
- ft_font->lock.lock ();
- paint_funcs->color (paint_data, is_foreground, color);
- paint_funcs->pop_clip (paint_data);
-
- } while (FT_Get_Color_Glyph_Layer(ft_face,
- gid,
- &layer_glyph_index,
- &layer_color_index,
- &iterator));
- return true;
- }
-
- return false;
-}
-
-
-#endif /* HB_FT_COLR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc
deleted file mode 100644
index 1105862fbc9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2009 Keith Stribley
- * Copyright © 2015 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_FREETYPE
-
-#include "hb-ft.h"
-
-#include "hb-cache.hh"
-#include "hb-draw.hh"
-#include "hb-font.hh"
-#include "hb-machinery.hh"
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-shaper-arabic-pua.hh"
-#include "hb-paint.hh"
-
-#include FT_ADVANCES_H
-#include FT_MULTIPLE_MASTERS_H
-#include FT_OUTLINE_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_SYNTHESIS_H
-#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
-#include FT_COLOR_H
-#endif
-
-
-/**
- * SECTION:hb-ft
- * @title: hb-ft
- * @short_description: FreeType integration
- * @include: hb-ft.h
- *
- * Functions for using HarfBuzz with the FreeType library.
- *
- * HarfBuzz supports using FreeType to provide face and
- * font data.
- *
- * <note>Note that FreeType is not thread-safe, therefore these
- * functions are not thread-safe either.</note>
- **/
-
-
-/* TODO:
- *
- * In general, this file does a fine job of what it's supposed to do.
- * There are, however, things that need more work:
- *
- * - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
- * would work fine. However, we also abuse this API for performing in font-space,
- * but don't pass the correct flags to FreeType. We just abuse the no-hinting mode
- * for that, such that no rounding etc happens. As such, we don't set ppem, and
- * pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale
- * ourselves.
- *
- * - We don't handle / allow for emboldening / obliqueing.
- *
- * - In the future, we should add constructors to create fonts in font space?
- */
-
-
-using hb_ft_advance_cache_t = hb_cache_t<16, 24, 8, false>;
-
-struct hb_ft_font_t
-{
- int load_flags;
- bool symbol; /* Whether selected cmap is symbol cmap. */
- bool unref; /* Whether to destroy ft_face when done. */
- bool transform; /* Whether to apply FT_Face's transform. */
-
- mutable hb_mutex_t lock; /* Protects members below. */
- FT_Face ft_face;
- mutable unsigned cached_serial;
- mutable hb_ft_advance_cache_t advance_cache;
-};
-
-static hb_ft_font_t *
-_hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
-{
- hb_ft_font_t *ft_font = (hb_ft_font_t *) hb_calloc (1, sizeof (hb_ft_font_t));
- if (unlikely (!ft_font)) return nullptr;
-
- ft_font->lock.init ();
- ft_font->ft_face = ft_face;
- ft_font->symbol = symbol;
- ft_font->unref = unref;
-
- ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
-
- ft_font->cached_serial = (unsigned) -1;
- ft_font->advance_cache.init ();
-
- return ft_font;
-}
-
-static void
-_hb_ft_face_destroy (void *data)
-{
- FT_Done_Face ((FT_Face) data);
-}
-
-static void
-_hb_ft_font_destroy (void *data)
-{
- hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
-
- if (ft_font->unref)
- _hb_ft_face_destroy (ft_font->ft_face);
-
- ft_font->lock.fini ();
-
- hb_free (ft_font);
-}
-
-
-/* hb_font changed, update FT_Face. */
-static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face)
-{
- hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
-
- float x_mult = 1.f, y_mult = 1.f;
-
- if (font->x_scale < 0) x_mult = -x_mult;
- if (font->y_scale < 0) y_mult = -y_mult;
-
- if (FT_Set_Char_Size (ft_face,
- abs (font->x_scale), abs (font->y_scale),
- 0, 0
-#if 0
- font->x_ppem * 72 * 64 / font->x_scale,
- font->y_ppem * 72 * 64 / font->y_scale
-#endif
- ) && ft_face->num_fixed_sizes)
- {
-#ifdef HAVE_FT_GET_TRANSFORM
- /* Bitmap font, eg. bitmap color emoji. */
- /* Pick largest size? */
- int x_scale = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].x_ppem;
- int y_scale = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].y_ppem;
- FT_Set_Char_Size (ft_face,
- x_scale, y_scale,
- 0, 0);
-
- /* This contains the sign that was previously in x_mult/y_mult. */
- x_mult = (float) font->x_scale / x_scale;
- y_mult = (float) font->y_scale / y_scale;
-#endif
- }
- else
- { /* Shrug */ }
-
-
- if (x_mult != 1.f || y_mult != 1.f)
- {
- FT_Matrix matrix = { (int) roundf (x_mult * (1<<16)), 0,
- 0, (int) roundf (y_mult * (1<<16))};
- FT_Set_Transform (ft_face, &matrix, nullptr);
- ft_font->transform = true;
- }
-
-#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
- unsigned int num_coords;
- const float *coords = hb_font_get_var_coords_design (font, &num_coords);
- if (num_coords)
- {
- FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed));
- if (ft_coords)
- {
- for (unsigned int i = 0; i < num_coords; i++)
- ft_coords[i] = coords[i] * 65536.f;
- FT_Set_Var_Design_Coordinates (ft_face, num_coords, ft_coords);
- hb_free (ft_coords);
- }
- }
-#endif
-}
-
-/* Check if hb_font changed, update FT_Face. */
-static inline bool
-_hb_ft_hb_font_check_changed (hb_font_t *font,
- const hb_ft_font_t *ft_font)
-{
- if (font->serial != ft_font->cached_serial)
- {
- _hb_ft_hb_font_changed (font, ft_font->ft_face);
- ft_font->advance_cache.clear ();
- ft_font->cached_serial = font->serial;
- return true;
- }
- return false;
-}
-
-
-/**
- * hb_ft_font_set_load_flags:
- * @font: #hb_font_t to work upon
- * @load_flags: The FreeType load flags to set
- *
- * Sets the FT_Load_Glyph load flags for the specified #hb_font_t.
- *
- * For more information, see
- * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
- *
- * This function works with #hb_font_t objects created by
- * hb_ft_font_create() or hb_ft_font_create_referenced().
- *
- * Since: 1.0.5
- **/
-void
-hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
-{
- if (hb_object_is_immutable (font))
- return;
-
- if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
- return;
-
- hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
-
- ft_font->load_flags = load_flags;
-}
-
-/**
- * hb_ft_font_get_load_flags:
- * @font: #hb_font_t to work upon
- *
- * Fetches the FT_Load_Glyph load flags of the specified #hb_font_t.
- *
- * For more information, see
- * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
- *
- * This function works with #hb_font_t objects created by
- * hb_ft_font_create() or hb_ft_font_create_referenced().
- *
- * Return value: FT_Load_Glyph flags found, or 0
- *
- * Since: 1.0.5
- **/
-int
-hb_ft_font_get_load_flags (hb_font_t *font)
-{
- if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
- return 0;
-
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
-
- return ft_font->load_flags;
-}
-
-/**
- * hb_ft_font_get_face: (skip)
- * @font: #hb_font_t to work upon
- *
- * Fetches the FT_Face associated with the specified #hb_font_t
- * font object.
- *
- * This function works with #hb_font_t objects created by
- * hb_ft_font_create() or hb_ft_font_create_referenced().
- *
- * Return value: (nullable): the FT_Face found or `NULL`
- *
- * Since: 0.9.2
- **/
-FT_Face
-hb_ft_font_get_face (hb_font_t *font)
-{
- if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
- return nullptr;
-
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
-
- return ft_font->ft_face;
-}
-
-/**
- * hb_ft_font_lock_face: (skip)
- * @font: #hb_font_t to work upon
- *
- * Gets the FT_Face associated with @font.
- *
- * This face will be kept around and access to the FT_Face object
- * from other HarfBuzz API wil be blocked until you call hb_ft_font_unlock_face().
- *
- * This function works with #hb_font_t objects created by
- * hb_ft_font_create() or hb_ft_font_create_referenced().
- *
- * Return value: (nullable) (transfer none): the FT_Face associated with @font or `NULL`
- * Since: 2.6.5
- **/
-FT_Face
-hb_ft_font_lock_face (hb_font_t *font)
-{
- if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
- return nullptr;
-
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
-
- ft_font->lock.lock ();
-
- return ft_font->ft_face;
-}
-
-/**
- * hb_ft_font_unlock_face: (skip)
- * @font: #hb_font_t to work upon
- *
- * Releases an FT_Face previously obtained with hb_ft_font_lock_face().
- *
- * Since: 2.6.5
- **/
-void
-hb_ft_font_unlock_face (hb_font_t *font)
-{
- if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy))
- return;
-
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
-
- ft_font->lock.unlock ();
-}
-
-
-static hb_bool_t
-hb_ft_get_nominal_glyph (hb_font_t *font,
- void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
-
- if (unlikely (!g))
- {
- if (unlikely (ft_font->symbol))
- {
- switch ((unsigned) font->face->table.OS2->get_font_page ()) {
- case OT::OS2::font_page_t::FONT_PAGE_NONE:
- if (unicode <= 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:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
- * under "Non-Standard (Symbol) Fonts". */
- g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
- break;
-#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK
- case OT::OS2::font_page_t::FONT_PAGE_SIMP_ARABIC:
- g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_simp_map (unicode));
- break;
- case OT::OS2::font_page_t::FONT_PAGE_TRAD_ARABIC:
- g = FT_Get_Char_Index (ft_font->ft_face, _hb_arabic_pua_trad_map (unicode));
- break;
-#endif
- default:
- break;
- }
- if (!g)
- return false;
- }
- else
- return false;
- }
-
- *glyph = g;
- return true;
-}
-
-static unsigned int
-hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
- void *font_data,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- unsigned int done;
- for (done = 0;
- done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode));
- done++)
- {
- first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- }
- /* We don't need to do ft_font->symbol dance here, since HB calls the singular
- * nominal_glyph() for what we don't handle here. */
- return done;
-}
-
-
-static hb_bool_t
-hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
- void *font_data,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
-
- if (unlikely (!g))
- return false;
-
- *glyph = g;
- return true;
-}
-
-static void
-hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
- unsigned count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_position_t *orig_first_advance = first_advance;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
- int load_flags = ft_font->load_flags;
- float x_mult;
-#ifdef HAVE_FT_GET_TRANSFORM
- if (ft_font->transform)
- {
- FT_Matrix matrix;
- FT_Get_Transform (ft_face, &matrix, nullptr);
- x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
- x_mult *= font->x_scale < 0 ? -1 : +1;
- }
- else
-#endif
- {
- x_mult = font->x_scale < 0 ? -1 : +1;
- }
-
- for (unsigned int i = 0; i < count; i++)
- {
- FT_Fixed v = 0;
- hb_codepoint_t glyph = *first_glyph;
-
- unsigned int cv;
- if (ft_font->advance_cache.get (glyph, &cv))
- v = cv;
- else
- {
- FT_Get_Advance (ft_face, glyph, load_flags, &v);
- /* Work around bug that FreeType seems to return negative advance
- * for variable-set fonts if x_scale is negative! */
- v = abs (v);
- v = (int) (v * x_mult + (1<<9)) >> 10;
- ft_font->advance_cache.set (glyph, v);
- }
-
- *first_advance = v;
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
-
- if (font->x_strength && !font->embolden_in_place)
- {
- /* Emboldening. */
- hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength;
- first_advance = orig_first_advance;
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance += *first_advance ? x_strength : 0;
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
-}
-
-#ifndef HB_NO_VERTICAL
-static hb_position_t
-hb_ft_get_glyph_v_advance (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Fixed v;
- float y_mult;
-#ifdef HAVE_FT_GET_TRANSFORM
- if (ft_font->transform)
- {
- FT_Matrix matrix;
- FT_Get_Transform (ft_font->ft_face, &matrix, nullptr);
- y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
- y_mult *= font->y_scale < 0 ? -1 : +1;
- }
- else
-#endif
- {
- y_mult = font->y_scale < 0 ? -1 : +1;
- }
-
- if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
- return 0;
-
- v = (int) (y_mult * v);
-
- /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
- * have a Y growing upward. Hence the extra negation. */
-
- hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength;
- return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength);
-}
-#endif
-
-#ifndef HB_NO_VERTICAL
-static hb_bool_t
-hb_ft_get_glyph_v_origin (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
- float x_mult, y_mult;
-#ifdef HAVE_FT_GET_TRANSFORM
- if (ft_font->transform)
- {
- FT_Matrix matrix;
- FT_Get_Transform (ft_face, &matrix, nullptr);
- x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
- x_mult *= font->x_scale < 0 ? -1 : +1;
- y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
- y_mult *= font->y_scale < 0 ? -1 : +1;
- }
- else
-#endif
- {
- x_mult = font->x_scale < 0 ? -1 : +1;
- y_mult = font->y_scale < 0 ? -1 : +1;
- }
-
- if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
- return false;
-
- /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
- * have a Y growing upward. Hence the extra negation. */
- *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX;
- *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
-
- *x = (hb_position_t) (x_mult * *x);
- *y = (hb_position_t) (y_mult * *y);
-
- return true;
-}
-#endif
-
-#ifndef HB_NO_OT_SHAPE_FALLBACK
-static hb_position_t
-hb_ft_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_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Vector kerningv;
-
- FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
- if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
- return 0;
-
- return kerningv.x;
-}
-#endif
-
-static hb_bool_t
-hb_ft_get_glyph_extents (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
- float x_mult, y_mult;
- float slant_xy = font->slant_xy;
-#ifdef HAVE_FT_GET_TRANSFORM
- if (ft_font->transform)
- {
- FT_Matrix matrix;
- FT_Get_Transform (ft_face, &matrix, nullptr);
- x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
- x_mult *= font->x_scale < 0 ? -1 : +1;
- y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
- y_mult *= font->y_scale < 0 ? -1 : +1;
- }
- else
-#endif
- {
- x_mult = font->x_scale < 0 ? -1 : +1;
- y_mult = font->y_scale < 0 ? -1 : +1;
- }
-
- if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
- return false;
-
- /* Copied from hb_font_t::scale_glyph_extents. */
-
- float x1 = x_mult * ft_face->glyph->metrics.horiBearingX;
- float y1 = y_mult * ft_face->glyph->metrics.horiBearingY;
- float x2 = x1 + x_mult * ft_face->glyph->metrics.width;
- float y2 = y1 + y_mult * -ft_face->glyph->metrics.height;
-
- /* Apply slant. */
- if (slant_xy)
- {
- x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
- x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
- }
-
- extents->x_bearing = floorf (x1);
- extents->y_bearing = floorf (y1);
- extents->width = ceilf (x2) - extents->x_bearing;
- extents->height = ceilf (y2) - extents->y_bearing;
-
- if (font->x_strength || font->y_strength)
- {
- /* Y */
- int y_shift = font->y_strength;
- if (font->y_scale < 0) y_shift = -y_shift;
- extents->y_bearing += y_shift;
- extents->height -= y_shift;
-
- /* X */
- int x_shift = font->x_strength;
- if (font->x_scale < 0) x_shift = -x_shift;
- if (font->embolden_in_place)
- extents->x_bearing -= x_shift / 2;
- extents->width += x_shift;
- }
-
- return true;
-}
-
-static hb_bool_t
-hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
- void *font_data,
- hb_codepoint_t glyph,
- unsigned int point_index,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
-
- if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
- return false;
-
- if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
- return false;
-
- if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
- return false;
-
- *x = ft_face->glyph->outline.points[point_index].x;
- *y = ft_face->glyph->outline.points[point_index].y;
-
- return true;
-}
-
-static hb_bool_t
-hb_ft_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_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
-
- hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
- if (ret && (size && !*name))
- ret = false;
-
- return ret;
-}
-
-static hb_bool_t
-hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
- void *font_data,
- const char *name, int len, /* -1 means nul-terminated */
- hb_codepoint_t *glyph,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
-
- if (len < 0)
- *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name);
- else {
- /* Make a nul-terminated version. */
- char buf[128];
- len = hb_min (len, (int) sizeof (buf) - 1);
- strncpy (buf, name, len);
- buf[len] = '\0';
- *glyph = FT_Get_Name_Index (ft_face, buf);
- }
-
- if (*glyph == 0)
- {
- /* Check whether the given name was actually the name of glyph 0. */
- char buf[128];
- if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) &&
- len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
- return true;
- }
-
- return *glyph != 0;
-}
-
-static hb_bool_t
-hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
- void *font_data,
- hb_font_extents_t *metrics,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
- float y_mult;
-#ifdef HAVE_FT_GET_TRANSFORM
- if (ft_font->transform)
- {
- FT_Matrix matrix;
- FT_Get_Transform (ft_face, &matrix, nullptr);
- y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
- y_mult *= font->y_scale < 0 ? -1 : +1;
- }
- else
-#endif
- {
- y_mult = font->y_scale < 0 ? -1 : +1;
- }
-
- if (ft_face->units_per_EM != 0)
- {
- metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
- metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
- metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
- }
- else
- {
- /* Bitmap-only font, eg. color bitmap font. */
- metrics->ascender = ft_face->size->metrics.ascender;
- metrics->descender = ft_face->size->metrics.descender;
- metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender);
- }
-
- metrics->ascender = (hb_position_t) (y_mult * (metrics->ascender + font->y_strength));
- metrics->descender = (hb_position_t) (y_mult * metrics->descender);
- metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap);
-
- return true;
-}
-
-#ifndef HB_NO_DRAW
-
-static int
-_hb_ft_move_to (const FT_Vector *to,
- void *arg)
-{
- hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
- drawing->move_to (to->x, to->y);
- return FT_Err_Ok;
-}
-
-static int
-_hb_ft_line_to (const FT_Vector *to,
- void *arg)
-{
- hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
- drawing->line_to (to->x, to->y);
- return FT_Err_Ok;
-}
-
-static int
-_hb_ft_conic_to (const FT_Vector *control,
- const FT_Vector *to,
- void *arg)
-{
- hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
- drawing->quadratic_to (control->x, control->y,
- to->x, to->y);
- return FT_Err_Ok;
-}
-
-static int
-_hb_ft_cubic_to (const FT_Vector *control1,
- const FT_Vector *control2,
- const FT_Vector *to,
- void *arg)
-{
- hb_draw_session_t *drawing = (hb_draw_session_t *) arg;
- drawing->cubic_to (control1->x, control1->y,
- control2->x, control2->y,
- to->x, to->y);
- return FT_Err_Ok;
-}
-
-static void
-hb_ft_draw_glyph (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs, void *draw_data,
- void *user_data HB_UNUSED)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
-
- if (unlikely (FT_Load_Glyph (ft_face, glyph,
- FT_LOAD_NO_BITMAP | ft_font->load_flags)))
- return;
-
- if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
- return;
-
- const FT_Outline_Funcs outline_funcs = {
- _hb_ft_move_to,
- _hb_ft_line_to,
- _hb_ft_conic_to,
- _hb_ft_cubic_to,
- 0, /* shift */
- 0, /* delta */
- };
-
- hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
-
- /* Embolden */
- if (font->x_strength || font->y_strength)
- {
- FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength);
-
- int x_shift = 0;
- int y_shift = 0;
- if (font->embolden_in_place)
- {
- /* Undo the FreeType shift. */
- x_shift = -font->x_strength / 2;
- y_shift = 0;
- if (font->y_scale < 0) y_shift = -font->y_strength;
- }
- else
- {
- /* FreeType applied things in the wrong direction for negative scale; fix up. */
- if (font->x_scale < 0) x_shift = -font->x_strength;
- if (font->y_scale < 0) y_shift = -font->y_strength;
- }
- if (x_shift || y_shift)
- {
- auto &outline = ft_face->glyph->outline;
- for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1))
- {
- point.x += x_shift;
- point.y += y_shift;
- }
- }
- }
-
-
- FT_Outline_Decompose (&ft_face->glyph->outline,
- &outline_funcs,
- &draw_session);
-}
-#endif
-
-#ifndef HB_NO_PAINT
-#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
-
-#include "hb-ft-colr.hh"
-
-static void
-hb_ft_paint_glyph (hb_font_t *font,
- void *font_data,
- hb_codepoint_t gid,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- unsigned int palette_index,
- hb_color_t foreground,
- void *user_data)
-{
- const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
- hb_lock_t lock (ft_font->lock);
- FT_Face ft_face = ft_font->ft_face;
-
- /* We release the lock before calling into glyph callbacks, such that
- * eg. draw API can call back into the face.*/
-
- if (unlikely (FT_Load_Glyph (ft_face, gid,
- ft_font->load_flags | FT_LOAD_COLOR)))
- return;
-
- if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
- {
- if (hb_ft_paint_glyph_colr (font, font_data, gid,
- paint_funcs, paint_data,
- palette_index, foreground,
- user_data))
- return;
-
- /* Simple outline. */
- ft_font->lock.unlock ();
- paint_funcs->push_clip_glyph (paint_data, gid, font);
- ft_font->lock.lock ();
- paint_funcs->color (paint_data, true, foreground);
- paint_funcs->pop_clip (paint_data);
-
- return;
- }
-
- auto *glyph = ft_face->glyph;
- if (glyph->format == FT_GLYPH_FORMAT_BITMAP)
- {
- auto &bitmap = glyph->bitmap;
- if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
- {
- if (bitmap.pitch != (signed) bitmap.width * 4)
- return;
-
- ft_font->lock.unlock ();
-
- hb_blob_t *blob = hb_blob_create ((const char *) bitmap.buffer,
- bitmap.pitch * bitmap.rows,
- HB_MEMORY_MODE_DUPLICATE,
- nullptr, nullptr);
-
- hb_glyph_extents_t extents;
- if (!hb_font_get_glyph_extents (font, gid, &extents))
- goto out;
-
- if (!paint_funcs->image (paint_data,
- blob,
- bitmap.width,
- bitmap.rows,
- HB_PAINT_IMAGE_FORMAT_BGRA,
- font->slant_xy,
- &extents))
- {
- /* TODO Try a forced outline load and paint? */
- }
-
- out:
- hb_blob_destroy (blob);
- ft_font->lock.lock ();
- }
-
- return;
- }
-}
-#endif
-#endif
-
-
-static inline void free_static_ft_funcs ();
-
-static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t>
-{
- static hb_font_funcs_t *create ()
- {
- hb_font_funcs_t *funcs = hb_font_funcs_create ();
-
- hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
- hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr);
- hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr);
-
- hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr);
- //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
-
-#ifndef HB_NO_VERTICAL
- //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
-#endif
-
-#ifndef HB_NO_OT_SHAPE_FALLBACK
- hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
-#endif
- //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
- hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
- hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
- hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr);
-
-#ifndef HB_NO_DRAW
- hb_font_funcs_set_draw_glyph_func (funcs, hb_ft_draw_glyph, nullptr, nullptr);
-#endif
-
-#ifndef HB_NO_PAINT
-#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
- hb_font_funcs_set_paint_glyph_func (funcs, hb_ft_paint_glyph, nullptr, nullptr);
-#endif
-#endif
-
- hb_font_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_ft_funcs);
-
- return funcs;
- }
-} static_ft_funcs;
-
-static inline
-void free_static_ft_funcs ()
-{
- static_ft_funcs.free_instance ();
-}
-
-static hb_font_funcs_t *
-_hb_ft_get_font_funcs ()
-{
- return static_ft_funcs.get_unconst ();
-}
-
-static void
-_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
-{
- bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
-
- hb_ft_font_t *ft_font = _hb_ft_font_create (ft_face, symbol, unref);
- if (unlikely (!ft_font)) return;
-
- hb_font_set_funcs (font,
- _hb_ft_get_font_funcs (),
- ft_font,
- _hb_ft_font_destroy);
-}
-
-
-static hb_blob_t *
-_hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
- FT_Face ft_face = (FT_Face) user_data;
- FT_Byte *buffer;
- FT_ULong length = 0;
- FT_Error error;
-
- /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
-
- error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length);
- if (error)
- return nullptr;
-
- buffer = (FT_Byte *) hb_malloc (length);
- if (!buffer)
- return nullptr;
-
- error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
- if (error)
- {
- hb_free (buffer);
- return nullptr;
- }
-
- return hb_blob_create ((const char *) buffer, length,
- HB_MEMORY_MODE_WRITABLE,
- buffer, hb_free);
-}
-
-/**
- * hb_ft_face_create:
- * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
- * @destroy: (nullable): A callback to call when the face object is not needed anymore
- *
- * Creates an #hb_face_t face object from the specified FT_Face.
- *
- * Note that this is using the FT_Face object just to get at the underlying
- * font data, and fonts created from the returned #hb_face_t will use the native
- * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
- *
- * This variant of the function does not provide any life-cycle management.
- *
- * Most client programs should use hb_ft_face_create_referenced()
- * (or, perhaps, hb_ft_face_create_cached()) instead.
- *
- * If you know you have valid reasons not to use hb_ft_face_create_referenced(),
- * then it is the client program's responsibility to destroy @ft_face
- * after the #hb_face_t face object has been destroyed.
- *
- * Return value: (transfer full): the new #hb_face_t face object
- *
- * Since: 0.9.2
- **/
-hb_face_t *
-hb_ft_face_create (FT_Face ft_face,
- hb_destroy_func_t destroy)
-{
- hb_face_t *face;
-
- if (!ft_face->stream->read) {
- hb_blob_t *blob;
-
- blob = hb_blob_create ((const char *) ft_face->stream->base,
- (unsigned int) ft_face->stream->size,
- HB_MEMORY_MODE_READONLY,
- ft_face, destroy);
- face = hb_face_create (blob, ft_face->face_index);
- hb_blob_destroy (blob);
- } else {
- face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy);
- }
-
- hb_face_set_index (face, ft_face->face_index);
- hb_face_set_upem (face, ft_face->units_per_EM);
-
- return face;
-}
-
-/**
- * hb_ft_face_create_referenced:
- * @ft_face: FT_Face to work upon
- *
- * Creates an #hb_face_t face object from the specified FT_Face.
- *
- * Note that this is using the FT_Face object just to get at the underlying
- * font data, and fonts created from the returned #hb_face_t will use the native
- * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
- *
- * This is the preferred variant of the hb_ft_face_create*
- * function family, because it calls FT_Reference_Face() on @ft_face,
- * ensuring that @ft_face remains alive as long as the resulting
- * #hb_face_t face object remains alive. Also calls FT_Done_Face()
- * when the #hb_face_t face object is destroyed.
- *
- * Use this version unless you know you have good reasons not to.
- *
- * Return value: (transfer full): the new #hb_face_t face object
- *
- * Since: 0.9.38
- **/
-hb_face_t *
-hb_ft_face_create_referenced (FT_Face ft_face)
-{
- FT_Reference_Face (ft_face);
- return hb_ft_face_create (ft_face, _hb_ft_face_destroy);
-}
-
-static void
-hb_ft_face_finalize (void *arg)
-{
- FT_Face ft_face = (FT_Face) arg;
- hb_face_destroy ((hb_face_t *) ft_face->generic.data);
-}
-
-/**
- * hb_ft_face_create_cached:
- * @ft_face: FT_Face to work upon
- *
- * Creates an #hb_face_t face object from the specified FT_Face.
- *
- * Note that this is using the FT_Face object just to get at the underlying
- * font data, and fonts created from the returned #hb_face_t will use the native
- * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
- *
- * This variant of the function caches the newly created #hb_face_t
- * face object, using the @generic pointer of @ft_face. Subsequent function
- * calls that are passed the same @ft_face parameter will have the same
- * #hb_face_t returned to them, and that #hb_face_t will be correctly
- * reference counted.
- *
- * However, client programs are still responsible for destroying
- * @ft_face after the last #hb_face_t face object has been destroyed.
- *
- * Return value: (transfer full): the new #hb_face_t face object
- *
- * Since: 0.9.2
- **/
-hb_face_t *
-hb_ft_face_create_cached (FT_Face ft_face)
-{
- if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
- {
- if (ft_face->generic.finalizer)
- ft_face->generic.finalizer (ft_face);
-
- ft_face->generic.data = hb_ft_face_create (ft_face, nullptr);
- ft_face->generic.finalizer = hb_ft_face_finalize;
- }
-
- return hb_face_reference ((hb_face_t *) ft_face->generic.data);
-}
-
-/**
- * hb_ft_font_create:
- * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
- * @destroy: (nullable): A callback to call when the font object is not needed anymore
- *
- * Creates an #hb_font_t font object from the specified FT_Face.
- *
- * <note>Note: You must set the face size on @ft_face before calling
- * hb_ft_font_create() on it. HarfBuzz assumes size is always set and will
- * access `size` member of FT_Face unconditionally.</note>
- *
- * This variant of the function does not provide any life-cycle management.
- *
- * Most client programs should use hb_ft_font_create_referenced()
- * instead.
- *
- * If you know you have valid reasons not to use hb_ft_font_create_referenced(),
- * then it is the client program's responsibility to destroy @ft_face
- * after the #hb_font_t font object has been destroyed.
- *
- * HarfBuzz will use the @destroy callback on the #hb_font_t font object
- * if it is supplied when you use this function. However, even if @destroy
- * is provided, it is the client program's responsibility to destroy @ft_face,
- * and it is the client program's responsibility to ensure that @ft_face is
- * destroyed only after the #hb_font_t font object has been destroyed.
- *
- * Return value: (transfer full): the new #hb_font_t font object
- *
- * Since: 0.9.2
- **/
-hb_font_t *
-hb_ft_font_create (FT_Face ft_face,
- hb_destroy_func_t destroy)
-{
- hb_font_t *font;
- hb_face_t *face;
-
- face = hb_ft_face_create (ft_face, destroy);
- font = hb_font_create (face);
- hb_face_destroy (face);
- _hb_ft_font_set_funcs (font, ft_face, false);
- hb_ft_font_changed (font);
- return font;
-}
-
-/**
- * hb_ft_font_changed:
- * @font: #hb_font_t to work upon
- *
- * Refreshes the state of @font when the underlying FT_Face has changed.
- * This function should be called after changing the size or
- * variation-axis settings on the FT_Face.
- *
- * Since: 1.0.5
- **/
-void
-hb_ft_font_changed (hb_font_t *font)
-{
- if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
- return;
-
- hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
-
- FT_Face ft_face = ft_font->ft_face;
-
- hb_font_set_scale (font,
- (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16),
- (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16));
-#if 0 /* hb-ft works in no-hinting model */
- hb_font_set_ppem (font,
- ft_face->size->metrics.x_ppem,
- ft_face->size->metrics.y_ppem);
-#endif
-
-#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
- FT_MM_Var *mm_var = nullptr;
- if (!FT_Get_MM_Var (ft_face, &mm_var))
- {
- FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (mm_var->num_axis, sizeof (FT_Fixed));
- int *coords = (int *) hb_calloc (mm_var->num_axis, sizeof (int));
- if (coords && ft_coords)
- {
- if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords))
- {
- bool nonzero = false;
-
- for (unsigned int i = 0; i < mm_var->num_axis; ++i)
- {
- coords[i] = ft_coords[i] >>= 2;
- nonzero = nonzero || coords[i];
- }
-
- if (nonzero)
- hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
- else
- hb_font_set_var_coords_normalized (font, nullptr, 0);
- }
- }
- hb_free (coords);
- hb_free (ft_coords);
-#ifdef HAVE_FT_DONE_MM_VAR
- FT_Done_MM_Var (ft_face->glyph->library, mm_var);
-#else
- hb_free (mm_var);
-#endif
- }
-#endif
-
- ft_font->advance_cache.clear ();
- ft_font->cached_serial = font->serial;
-}
-
-/**
- * hb_ft_hb_font_changed:
- * @font: #hb_font_t to work upon
- *
- * Refreshes the state of the underlying FT_Face of @font when the hb_font_t
- * @font has changed.
- * This function should be called after changing the size or
- * variation-axis settings on the @font.
- * This call is fast if nothing has changed on @font.
- *
- * Return value: true if changed, false otherwise
- *
- * Since: 4.4.0
- **/
-hb_bool_t
-hb_ft_hb_font_changed (hb_font_t *font)
-{
- if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
- return false;
-
- hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
-
- return _hb_ft_hb_font_check_changed (font, ft_font);
-}
-
-/**
- * hb_ft_font_create_referenced:
- * @ft_face: FT_Face to work upon
- *
- * Creates an #hb_font_t font object from the specified FT_Face.
- *
- * <note>Note: You must set the face size on @ft_face before calling
- * hb_ft_font_create_referenced() on it. HarfBuzz assumes size is always set
- * and will access `size` member of FT_Face unconditionally.</note>
- *
- * This is the preferred variant of the hb_ft_font_create*
- * function family, because it calls FT_Reference_Face() on @ft_face,
- * ensuring that @ft_face remains alive as long as the resulting
- * #hb_font_t font object remains alive.
- *
- * Use this version unless you know you have good reasons not to.
- *
- * Return value: (transfer full): the new #hb_font_t font object
- *
- * Since: 0.9.38
- **/
-hb_font_t *
-hb_ft_font_create_referenced (FT_Face ft_face)
-{
- FT_Reference_Face (ft_face);
- return hb_ft_font_create (ft_face, _hb_ft_face_destroy);
-}
-
-static inline void free_static_ft_library ();
-
-static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
- hb_ft_library_lazy_loader_t>
-{
- static FT_Library create ()
- {
- FT_Library l;
- if (FT_Init_FreeType (&l))
- return nullptr;
-
- hb_atexit (free_static_ft_library);
-
- return l;
- }
- static void destroy (FT_Library l)
- {
- FT_Done_FreeType (l);
- }
- static FT_Library get_null ()
- {
- return nullptr;
- }
-} static_ft_library;
-
-static inline
-void free_static_ft_library ()
-{
- static_ft_library.free_instance ();
-}
-
-static FT_Library
-get_ft_library ()
-{
- return static_ft_library.get_unconst ();
-}
-
-static void
-_release_blob (void *arg)
-{
- FT_Face ft_face = (FT_Face) arg;
- hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
-}
-
-/**
- * hb_ft_font_set_funcs:
- * @font: #hb_font_t to work upon
- *
- * Configures the font-functions structure of the specified
- * #hb_font_t font object to use FreeType font functions.
- *
- * In particular, you can use this function to configure an
- * existing #hb_face_t face object for use with FreeType font
- * functions even if that #hb_face_t face object was initially
- * created with hb_face_create(), and therefore was not
- * initially configured to use FreeType font functions.
- *
- * An #hb_font_t object created with hb_ft_font_create()
- * is preconfigured for FreeType font functions and does not
- * require this function to be used.
- *
- * Note that if you modify the underlying #hb_font_t after
- * calling this function, you need to call hb_ft_hb_font_changed()
- * to update the underlying FT_Face.
- *
- * <note>Note: Internally, this function creates an FT_Face.
-* </note>
- *
- * Since: 1.0.5
- **/
-void
-hb_ft_font_set_funcs (hb_font_t *font)
-{
- hb_blob_t *blob = hb_face_reference_blob (font->face);
- unsigned int blob_length;
- const char *blob_data = hb_blob_get_data (blob, &blob_length);
- if (unlikely (!blob_length))
- DEBUG_MSG (FT, font, "Font face has empty blob");
-
- FT_Face ft_face = nullptr;
- FT_Error err = FT_New_Memory_Face (get_ft_library (),
- (const FT_Byte *) blob_data,
- blob_length,
- hb_face_get_index (font->face),
- &ft_face);
-
- if (unlikely (err)) {
- hb_blob_destroy (blob);
- DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
- return;
- }
-
- if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
- FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
-
-
- ft_face->generic.data = blob;
- ft_face->generic.finalizer = _release_blob;
-
- _hb_ft_font_set_funcs (font, ft_face, true);
- hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
-
- _hb_ft_hb_font_changed (font, ft_face);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.h b/src/3rdparty/harfbuzz-ng/src/hb-ft.h
deleted file mode 100644
index 6a8a7abe8cc..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ft.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2015 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_FT_H
-#define HB_FT_H
-
-#include "hb.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-HB_BEGIN_DECLS
-
-/*
- * Note: FreeType is not thread-safe.
- * Hence, these functions are not either.
- */
-
-/*
- * hb-face from ft-face.
- */
-
-/* This one creates a new hb-face for given ft-face.
- * When the returned hb-face is destroyed, the destroy
- * callback is called (if not NULL), with the ft-face passed
- * to it.
- *
- * The client is responsible to make sure that ft-face is
- * destroyed after hb-face is destroyed.
- *
- * Most often you don't want this function. You should use either
- * hb_ft_face_create_cached(), or hb_ft_face_create_referenced().
- * In particular, if you are going to pass NULL as destroy, you
- * probably should use (the more recent) hb_ft_face_create_referenced()
- * instead.
- */
-HB_EXTERN hb_face_t *
-hb_ft_face_create (FT_Face ft_face,
- hb_destroy_func_t destroy);
-
-/* This version is like hb_ft_face_create(), except that it caches
- * the hb-face using the generic pointer of the ft-face. This means
- * that subsequent calls to this function with the same ft-face will
- * return the same hb-face (correctly referenced).
- *
- * Client is still responsible for making sure that ft-face is destroyed
- * after hb-face is.
- */
-HB_EXTERN hb_face_t *
-hb_ft_face_create_cached (FT_Face ft_face);
-
-/* This version is like hb_ft_face_create(), except that it calls
- * FT_Reference_Face() on ft-face, as such keeping ft-face alive
- * as long as the hb-face is.
- *
- * This is the most convenient version to use. Use it unless you have
- * very good reasons not to.
- */
-HB_EXTERN hb_face_t *
-hb_ft_face_create_referenced (FT_Face ft_face);
-
-
-/*
- * hb-font from ft-face.
- */
-
-/*
- * Note:
- *
- * Set face size on ft-face before creating hb-font from it.
- * Otherwise hb-ft would NOT pick up the font size correctly.
- */
-
-/* See notes on hb_ft_face_create(). Same issues re lifecycle-management
- * apply here. Use hb_ft_font_create_referenced() if you can. */
-HB_EXTERN hb_font_t *
-hb_ft_font_create (FT_Face ft_face,
- hb_destroy_func_t destroy);
-
-/* See notes on hb_ft_face_create_referenced() re lifecycle-management
- * issues. */
-HB_EXTERN hb_font_t *
-hb_ft_font_create_referenced (FT_Face ft_face);
-
-HB_EXTERN FT_Face
-hb_ft_font_get_face (hb_font_t *font);
-
-HB_EXTERN FT_Face
-hb_ft_font_lock_face (hb_font_t *font);
-
-HB_EXTERN void
-hb_ft_font_unlock_face (hb_font_t *font);
-
-HB_EXTERN void
-hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
-
-HB_EXTERN int
-hb_ft_font_get_load_flags (hb_font_t *font);
-
-/* Call when size or variations settings on underlying FT_Face changed,
- * and you want to update the hb_font_t from it. */
-HB_EXTERN void
-hb_ft_font_changed (hb_font_t *font);
-
-/* Call when size or variations settings on underlying hb_font_t may have
- * changed, and you want to update the FT_Face from it. This call is fast
- * if nothing changed on hb_font_t. Returns true if changed. */
-HB_EXTERN hb_bool_t
-hb_ft_hb_font_changed (hb_font_t *font);
-
-/* Makes an hb_font_t use FreeType internally to implement font functions.
- * Note: this internally creates an FT_Face. Use it when you create your
- * hb_face_t using hb_face_create(). */
-HB_EXTERN void
-hb_ft_font_set_funcs (hb_font_t *font);
-
-
-HB_END_DECLS
-
-#endif /* HB_FT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc b/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc
deleted file mode 100644
index 8e7589beacb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gdi.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_GDI
-
-#include "hb-gdi.h"
-
-
-/**
- * SECTION:hb-gdi
- * @title: hb-gdi
- * @short_description: GDI integration
- * @include: hb-gdi.h
- *
- * Functions for using HarfBuzz with GDI fonts.
- **/
-
-static hb_blob_t *
-_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
- char *buffer = nullptr;
- DWORD length = 0;
-
- HDC hdc = GetDC (nullptr);
- if (unlikely (!SelectObject (hdc, (HFONT) user_data))) goto fail;
-
- length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
- if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc;
-
- buffer = (char *) hb_malloc (length);
- if (unlikely (!buffer)) goto fail_with_releasedc;
- length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
- if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free;
- ReleaseDC (nullptr, hdc);
-
- return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, hb_free);
-
-fail_with_releasedc_and_free:
- hb_free (buffer);
-fail_with_releasedc:
- ReleaseDC (nullptr, hdc);
-fail:
- return hb_blob_get_empty ();
-}
-
-/**
- * hb_gdi_face_create:
- * @hfont: a HFONT object.
- *
- * Constructs a new face object from the specified GDI HFONT.
- *
- * Return value: #hb_face_t object corresponding to the given input
- *
- * Since: 2.6.0
- **/
-hb_face_t *
-hb_gdi_face_create (HFONT hfont)
-{
- return hb_face_create_for_tables (_hb_gdi_reference_table, (void *) hfont, nullptr);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gdi.h b/src/3rdparty/harfbuzz-ng/src/hb-gdi.h
deleted file mode 100644
index 68cc43917e0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gdi.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_GDI_H
-#define HB_GDI_H
-
-#include "hb.h"
-
-#include <windows.h>
-
-HB_BEGIN_DECLS
-
-HB_EXTERN hb_face_t *
-hb_gdi_face_create (HFONT hfont);
-
-HB_END_DECLS
-
-#endif /* HB_GDI_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-glib.cc b/src/3rdparty/harfbuzz-ng/src/hb-glib.cc
deleted file mode 100644
index 1da81696e75..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-glib.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2011 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_GLIB
-
-#include "hb-glib.h"
-
-#include "hb-machinery.hh"
-
-
-/**
- * SECTION:hb-glib
- * @title: hb-glib
- * @short_description: GLib integration
- * @include: hb-glib.h
- *
- * Functions for using HarfBuzz with the GLib library.
- *
- * HarfBuzz supports using GLib to provide Unicode data, by attaching
- * GLib functions to the virtual methods in a #hb_unicode_funcs_t function
- * structure.
- **/
-
-
-/**
- * hb_glib_script_to_script:
- * @script: The GUnicodeScript identifier to query
- *
- * Fetches the #hb_script_t script that corresponds to the
- * specified GUnicodeScript identifier.
- *
- * Return value: the #hb_script_t script found
- *
- * Since: 0.9.38
- **/
-hb_script_t
-hb_glib_script_to_script (GUnicodeScript script)
-{
- return (hb_script_t) g_unicode_script_to_iso15924 (script);
-}
-
-/**
- * hb_glib_script_from_script:
- * @script: The #hb_script_t to query
- *
- * Fetches the GUnicodeScript identifier that corresponds to the
- * specified #hb_script_t script.
- *
- * Return value: the GUnicodeScript identifier found
- *
- * Since: 0.9.38
- **/
-GUnicodeScript
-hb_glib_script_from_script (hb_script_t script)
-{
- return g_unicode_script_from_iso15924 (script);
-}
-
-
-static hb_unicode_combining_class_t
-hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-
-{
- return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
-}
-
-static hb_unicode_general_category_t
-hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-
-{
- /* hb_unicode_general_category_t and GUnicodeType are identical */
- return (hb_unicode_general_category_t) g_unichar_type (unicode);
-}
-
-static hb_codepoint_t
-hb_glib_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- g_unichar_get_mirror_char (unicode, &unicode);
- return unicode;
-}
-
-static hb_script_t
-hb_glib_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return hb_glib_script_to_script (g_unichar_get_script (unicode));
-}
-
-static hb_bool_t
-hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab,
- void *user_data HB_UNUSED)
-{
-#if GLIB_CHECK_VERSION(2,29,12)
- return g_unichar_compose (a, b, ab);
-#else
- return false;
-#endif
-}
-
-static hb_bool_t
-hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t ab,
- hb_codepoint_t *a,
- hb_codepoint_t *b,
- void *user_data HB_UNUSED)
-{
-#if GLIB_CHECK_VERSION(2,29,12)
- return g_unichar_decompose (ab, a, b);
-#else
- return false;
-#endif
-}
-
-
-static inline void free_static_glib_funcs ();
-
-static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_glib_unicode_funcs_lazy_loader_t>
-{
- static hb_unicode_funcs_t *create ()
- {
- hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
-
- hb_unicode_funcs_set_combining_class_func (funcs, hb_glib_unicode_combining_class, nullptr, nullptr);
- hb_unicode_funcs_set_general_category_func (funcs, hb_glib_unicode_general_category, nullptr, nullptr);
- hb_unicode_funcs_set_mirroring_func (funcs, hb_glib_unicode_mirroring, nullptr, nullptr);
- hb_unicode_funcs_set_script_func (funcs, hb_glib_unicode_script, nullptr, nullptr);
- hb_unicode_funcs_set_compose_func (funcs, hb_glib_unicode_compose, nullptr, nullptr);
- hb_unicode_funcs_set_decompose_func (funcs, hb_glib_unicode_decompose, nullptr, nullptr);
-
- hb_unicode_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_glib_funcs);
-
- return funcs;
- }
-} static_glib_funcs;
-
-static inline
-void free_static_glib_funcs ()
-{
- static_glib_funcs.free_instance ();
-}
-
-/**
- * hb_glib_get_unicode_funcs:
- *
- * Fetches a Unicode-functions structure that is populated
- * with the appropriate GLib function for each method.
- *
- * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
- *
- * Since: 0.9.38
- **/
-hb_unicode_funcs_t *
-hb_glib_get_unicode_funcs ()
-{
- return static_glib_funcs.get_unconst ();
-}
-
-
-
-#if GLIB_CHECK_VERSION(2,31,10)
-
-static void
-_hb_g_bytes_unref (void *data)
-{
- g_bytes_unref ((GBytes *) data);
-}
-
-/**
- * hb_glib_blob_create:
- * @gbytes: the GBytes structure to work upon
- *
- * Creates an #hb_blob_t blob from the specified
- * GBytes data structure.
- *
- * Return value: (transfer full): the new #hb_blob_t blob object
- *
- * Since: 0.9.38
- **/
-hb_blob_t *
-hb_glib_blob_create (GBytes *gbytes)
-{
- gsize size = 0;
- gconstpointer data = g_bytes_get_data (gbytes, &size);
- return hb_blob_create ((const char *) data,
- size,
- HB_MEMORY_MODE_READONLY,
- g_bytes_ref (gbytes),
- _hb_g_bytes_unref);
-}
-#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl b/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl
deleted file mode 100644
index 87a11dd407e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.cc.tmpl
+++ /dev/null
@@ -1,80 +0,0 @@
-/*** BEGIN file-header ***/
-/*
- * Copyright (C) 2011 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.hh"
-
-#ifdef HAVE_GOBJECT
-
-/* g++ didn't like older gtype.h gcc-only code path. */
-#include <glib.h>
-#if !GLIB_CHECK_VERSION(2,29,16)
-#undef __GNUC__
-#undef __GNUC_MINOR__
-#define __GNUC__ 2
-#define __GNUC_MINOR__ 6
-#endif
-
-#include "hb-gobject.h"
-
-/*** END file-header ***/
-
-/*** BEGIN file-production ***/
-/* enumerations from "@basename@" */
-/*** END file-production ***/
-
-/*** BEGIN file-tail ***/
-
-#endif
-/*** END file-tail ***/
-
-/*** BEGIN value-header ***/
-GType
-@enum_name@_get_type ()
-{
- static gsize type_id = 0;
-
- if (g_once_init_enter (&type_id))
- {
- static const G@Type@Value values[] = {
-/*** END value-header ***/
-
-/*** BEGIN value-production ***/
- { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
-/*** END value-production ***/
-
-/*** BEGIN value-tail ***/
- { 0, NULL, NULL }
- };
- GType id =
- g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
- g_once_init_leave (&type_id, id);
- }
-
- return type_id;
-}
-
-/*** END value-tail ***/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl b/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl
deleted file mode 100644
index 6dd98f7fed6..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-enums.h.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-/*** BEGIN file-header ***/
-/*
- * Copyright (C) 2013 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
- */
-
-#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-gobject.h> instead."
-#endif
-
-#ifndef HB_GOBJECT_ENUMS_H
-#define HB_GOBJECT_ENUMS_H
-
-#include "hb.h"
-
-#include <glib-object.h>
-
-HB_BEGIN_DECLS
-
-
-/*** END file-header ***/
-
-/*** BEGIN value-header ***/
-HB_EXTERN GType
-@enum_name@_get_type (void) G_GNUC_CONST;
-#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
-
-/*** END value-header ***/
-
-/*** BEGIN file-tail ***/
-
-HB_END_DECLS
-
-#endif /* HB_GOBJECT_ENUMS_H */
-/*** END file-tail ***/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc
deleted file mode 100644
index 332cc84888d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright © 2011 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.hh"
-
-#ifdef HAVE_GOBJECT
-
-
-/**
- * SECTION:hb-gobject
- * @title: hb-gobject
- * @short_description: GObject integration support
- * @include: hb-gobject.h
- *
- * Support for using HarfBuzz with the GObject library to provide
- * type data.
- *
- * The types and functions listed here are solely a linkage between
- * HarfBuzz's public data types and the GTypes used by the GObject framework.
- * HarfBuzz uses GObject introspection to generate its Python bindings
- * (and potentially other language bindings); client programs should never need
- * to access the GObject-integration mechanics.
- *
- * For client programs using the GNOME and GTK software stack, please see the
- * GLib and FreeType integration pages.
- **/
-
-
-/* g++ didn't like older gtype.h gcc-only code path. */
-#include <glib.h>
-#if !GLIB_CHECK_VERSION(2,29,16)
-#undef __GNUC__
-#undef __GNUC_MINOR__
-#define __GNUC__ 2
-#define __GNUC_MINOR__ 6
-#endif
-
-#include "hb-gobject.h"
-
-#define HB_DEFINE_BOXED_TYPE(name,copy_func,free_func) \
-GType \
-hb_gobject_##name##_get_type () \
-{ \
- static gsize type_id = 0; \
- if (g_once_init_enter (&type_id)) { \
- GType id = g_boxed_type_register_static (g_intern_static_string ("hb_" #name "_t"), \
- (GBoxedCopyFunc) copy_func, \
- (GBoxedFreeFunc) free_func); \
- g_once_init_leave (&type_id, id); \
- } \
- return type_id; \
-}
-
-#define HB_DEFINE_OBJECT_TYPE(name) \
- HB_DEFINE_BOXED_TYPE (name, hb_##name##_reference, hb_##name##_destroy)
-
-#define HB_DEFINE_VALUE_TYPE(name) \
- static hb_##name##_t *_hb_##name##_reference (const hb_##name##_t *l) \
- { \
- hb_##name##_t *c = (hb_##name##_t *) hb_calloc (1, sizeof (hb_##name##_t)); \
- if (unlikely (!c)) return nullptr; \
- *c = *l; \
- return c; \
- } \
- static void _hb_##name##_destroy (hb_##name##_t *l) { hb_free (l); } \
- HB_DEFINE_BOXED_TYPE (name, _hb_##name##_reference, _hb_##name##_destroy)
-
-HB_DEFINE_OBJECT_TYPE (buffer)
-HB_DEFINE_OBJECT_TYPE (blob)
-HB_DEFINE_OBJECT_TYPE (draw_funcs)
-HB_DEFINE_OBJECT_TYPE (paint_funcs)
-HB_DEFINE_OBJECT_TYPE (face)
-HB_DEFINE_OBJECT_TYPE (font)
-HB_DEFINE_OBJECT_TYPE (font_funcs)
-HB_DEFINE_OBJECT_TYPE (set)
-HB_DEFINE_OBJECT_TYPE (map)
-HB_DEFINE_OBJECT_TYPE (shape_plan)
-HB_DEFINE_OBJECT_TYPE (unicode_funcs)
-HB_DEFINE_VALUE_TYPE (feature)
-HB_DEFINE_VALUE_TYPE (glyph_info)
-HB_DEFINE_VALUE_TYPE (glyph_position)
-HB_DEFINE_VALUE_TYPE (segment_properties)
-HB_DEFINE_VALUE_TYPE (draw_state)
-HB_DEFINE_VALUE_TYPE (color_stop)
-HB_DEFINE_VALUE_TYPE (color_line)
-HB_DEFINE_VALUE_TYPE (user_data_key)
-
-HB_DEFINE_VALUE_TYPE (ot_var_axis_info)
-HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
-HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h b/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h
deleted file mode 100644
index b7b5f55ce67..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gobject-structs.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 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
- */
-
-#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-gobject.h> instead."
-#endif
-
-#ifndef HB_GOBJECT_STRUCTS_H
-#define HB_GOBJECT_STRUCTS_H
-
-#include "hb.h"
-
-#include <glib-object.h>
-
-HB_BEGIN_DECLS
-
-
-/* Object types */
-
-HB_EXTERN GType
-hb_gobject_blob_get_type (void);
-#define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ())
-
-HB_EXTERN GType
-hb_gobject_buffer_get_type (void);
-#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
-
-HB_EXTERN GType
-hb_gobject_draw_funcs_get_type (void);
-#define HB_GOBJECT_TYPE_DRAW_FUNCS (hb_gobject_draw_funcs_get_type ())
-
-HB_EXTERN GType
-hb_gobject_paint_funcs_get_type (void);
-#define HB_GOBJECT_TYPE_PAINT_FUNCS (hb_gobject_paint_funcs_get_type ())
-
-HB_EXTERN GType
-hb_gobject_face_get_type (void);
-#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
-
-HB_EXTERN GType
-hb_gobject_font_get_type (void);
-#define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ())
-
-HB_EXTERN GType
-hb_gobject_font_funcs_get_type (void);
-#define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ())
-
-HB_EXTERN GType
-hb_gobject_set_get_type (void);
-#define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
-
-HB_EXTERN GType
-hb_gobject_map_get_type (void);
-#define HB_GOBJECT_TYPE_MAP (hb_gobject_map_get_type ())
-
-HB_EXTERN GType
-hb_gobject_shape_plan_get_type (void);
-#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
-
-HB_EXTERN GType
-hb_gobject_unicode_funcs_get_type (void);
-#define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ())
-
-/* Value types */
-
-HB_EXTERN GType
-hb_gobject_feature_get_type (void);
-#define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ())
-
-HB_EXTERN GType
-hb_gobject_glyph_info_get_type (void);
-#define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ())
-
-HB_EXTERN GType
-hb_gobject_glyph_position_get_type (void);
-#define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ())
-
-HB_EXTERN GType
-hb_gobject_segment_properties_get_type (void);
-#define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ())
-
-HB_EXTERN GType
-hb_gobject_draw_state_get_type (void);
-#define HB_GOBJECT_TYPE_DRAW_STATE (hb_gobject_draw_state_get_type ())
-
-HB_EXTERN GType
-hb_gobject_color_stop_get_type (void);
-#define HB_GOBJECT_TYPE_COLOR_STOP (hb_gobject_color_stop_get_type ())
-
-HB_EXTERN GType
-hb_gobject_color_line_get_type (void);
-#define HB_GOBJECT_TYPE_COLOR_LINE (hb_gobject_color_line_get_type ())
-
-HB_EXTERN GType
-hb_gobject_user_data_key_get_type (void);
-#define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ())
-
-HB_EXTERN GType
-hb_gobject_ot_var_axis_info_get_type (void);
-#define HB_GOBJECT_TYPE_OT_VAR_AXIS_INFO (hb_gobject_ot_var_axis_info_get_type ())
-
-HB_EXTERN GType
-hb_gobject_ot_math_glyph_variant_get_type (void);
-#define HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT (hb_gobject_ot_math_glyph_variant_get_type ())
-
-HB_EXTERN GType
-hb_gobject_ot_math_glyph_part_get_type (void);
-#define HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART (hb_gobject_ot_math_glyph_part_get_type ())
-
-
-HB_END_DECLS
-
-#endif /* HB_GOBJECT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-gobject.h b/src/3rdparty/harfbuzz-ng/src/hb-gobject.h
deleted file mode 100644
index 8891aa0ee79..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-gobject.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 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_GOBJECT_H
-#define HB_GOBJECT_H
-#define HB_GOBJECT_H_IN
-
-#include "hb.h"
-
-#include "hb-gobject-enums.h"
-#include "hb-gobject-structs.h"
-
-HB_BEGIN_DECLS
-HB_END_DECLS
-
-#undef HB_GOBJECT_H_IN
-#endif /* HB_GOBJECT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc
deleted file mode 100644
index 9e068f8d84d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright © 2011 Martin Hosken
- * Copyright © 2011 SIL International
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_GRAPHITE2
-
-#include "hb-shaper-impl.hh"
-
-#include "hb-graphite2.h"
-
-#include <graphite2/Segment.h>
-
-#include "hb-ot-layout.h"
-
-
-/**
- * SECTION:hb-graphite2
- * @title: hb-graphite2
- * @short_description: Graphite2 integration
- * @include: hb-graphite2.h
- *
- * Functions for using HarfBuzz with fonts that include Graphite features.
- *
- * For Graphite features to work, you must be sure that HarfBuzz was compiled
- * with the `graphite2` shaping engine enabled. Currently, the default is to
- * not enable `graphite2` shaping.
- **/
-
-
-/*
- * shaper face data
- */
-
-typedef struct hb_graphite2_tablelist_t
-{
- struct hb_graphite2_tablelist_t *next;
- hb_blob_t *blob;
- unsigned int tag;
-} hb_graphite2_tablelist_t;
-
-struct hb_graphite2_face_data_t
-{
- hb_face_t *face;
- gr_face *grface;
- hb_atomic_ptr_t<hb_graphite2_tablelist_t> tlist;
-};
-
-static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len)
-{
- hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
- hb_graphite2_tablelist_t *tlist = face_data->tlist;
-
- hb_blob_t *blob = nullptr;
-
- for (hb_graphite2_tablelist_t *p = tlist; p; p = p->next)
- if (p->tag == tag) {
- blob = p->blob;
- break;
- }
-
- if (unlikely (!blob))
- {
- blob = face_data->face->reference_table (tag);
-
- hb_graphite2_tablelist_t *p = (hb_graphite2_tablelist_t *) hb_calloc (1, sizeof (hb_graphite2_tablelist_t));
- if (unlikely (!p)) {
- hb_blob_destroy (blob);
- return nullptr;
- }
- p->blob = blob;
- p->tag = tag;
-
-retry:
- hb_graphite2_tablelist_t *tlist = face_data->tlist;
- p->next = tlist;
-
- if (unlikely (!face_data->tlist.cmpexch (tlist, p)))
- goto retry;
- }
-
- unsigned int tlen;
- const char *d = hb_blob_get_data (blob, &tlen);
- *len = tlen;
- return d;
-}
-
-hb_graphite2_face_data_t *
-_hb_graphite2_shaper_face_data_create (hb_face_t *face)
-{
- hb_blob_t *silf_blob = face->reference_table (HB_GRAPHITE2_TAG_SILF);
- /* Umm, we just reference the table to check whether it exists.
- * Maybe add better API for this? */
- if (!hb_blob_get_length (silf_blob))
- {
- hb_blob_destroy (silf_blob);
- return nullptr;
- }
- hb_blob_destroy (silf_blob);
-
- hb_graphite2_face_data_t *data = (hb_graphite2_face_data_t *) hb_calloc (1, sizeof (hb_graphite2_face_data_t));
- if (unlikely (!data))
- return nullptr;
-
- data->face = face;
- const gr_face_ops ops = {sizeof(gr_face_ops), &hb_graphite2_get_table, NULL};
- data->grface = gr_make_face_with_ops (data, &ops, gr_face_preloadAll);
-
- if (unlikely (!data->grface)) {
- hb_free (data);
- return nullptr;
- }
-
- return data;
-}
-
-void
-_hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data)
-{
- hb_graphite2_tablelist_t *tlist = data->tlist;
-
- while (tlist)
- {
- hb_graphite2_tablelist_t *old = tlist;
- hb_blob_destroy (tlist->blob);
- tlist = tlist->next;
- hb_free (old);
- }
-
- gr_face_destroy (data->grface);
-
- hb_free (data);
-}
-
-/**
- * hb_graphite2_face_get_gr_face: (skip)
- * @face: @hb_face_t to query
- *
- * Fetches the Graphite2 gr_face corresponding to the specified
- * #hb_face_t face object.
- *
- * Return value: the gr_face found
- *
- * Since: 0.9.10
- */
-gr_face *
-hb_graphite2_face_get_gr_face (hb_face_t *face)
-{
- const hb_graphite2_face_data_t *data = face->data.graphite2;
- return data ? data->grface : nullptr;
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_graphite2_font_data_t {};
-
-hb_graphite2_font_data_t *
-_hb_graphite2_shaper_font_data_create (hb_font_t *font HB_UNUSED)
-{
- return (hb_graphite2_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED)
-{
-}
-
-#ifndef HB_DISABLE_DEPRECATED
-/**
- * hb_graphite2_font_get_gr_font: (skip)
- * @font: An #hb_font_t
- *
- * Always returns `NULL`. Use hb_graphite2_face_get_gr_face() instead.
- *
- * Return value: (nullable): Graphite2 font associated with @font.
- *
- * Since: 0.9.10
- * Deprecated: 1.4.2
- */
-gr_font *
-hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED)
-{
- return nullptr;
-}
-#endif
-
-
-/*
- * shaper
- */
-
-struct hb_graphite2_cluster_t {
- unsigned int base_char;
- unsigned int num_chars;
- unsigned int base_glyph;
- unsigned int num_glyphs;
- unsigned int cluster;
- int advance;
-};
-
-hb_bool_t
-_hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
-{
- hb_face_t *face = font->face;
- gr_face *grface = face->data.graphite2->grface;
-
- const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
- const char *lang_end = lang ? strchr (lang, '-') : nullptr;
- int lang_len = lang_end ? lang_end - lang : -1;
- gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0);
-
- for (unsigned int i = 0; i < num_features; i++)
- {
- const gr_feature_ref *fref = gr_face_find_fref (grface, features[i].tag);
- if (fref)
- gr_fref_set_feature_value (fref, features[i].value, feats);
- }
-
- gr_segment *seg = nullptr;
- const gr_slot *is;
- unsigned int ci = 0, ic = 0;
- unsigned int curradvx = 0, curradvy = 0;
-
- unsigned int scratch_size;
- hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
-
- uint32_t *chars = (uint32_t *) scratch;
-
- for (unsigned int i = 0; i < buffer->len; ++i)
- chars[i] = buffer->info[i].codepoint;
-
- /* TODO ensure_native_direction. */
-
- hb_tag_t script_tag[HB_OT_MAX_TAGS_PER_SCRIPT];
- unsigned int count = HB_OT_MAX_TAGS_PER_SCRIPT;
- hb_ot_tags_from_script_and_language (hb_buffer_get_script (buffer),
- HB_LANGUAGE_INVALID,
- &count,
- script_tag,
- nullptr, nullptr);
-
- seg = gr_make_seg (nullptr, grface,
- count ? script_tag[count - 1] : HB_OT_TAG_DEFAULT_SCRIPT,
- feats,
- gr_utf32, chars, buffer->len,
- 2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
-
- if (unlikely (!seg)) {
- if (feats) gr_featureval_destroy (feats);
- return false;
- }
-
- unsigned int glyph_count = gr_seg_n_slots (seg);
- if (unlikely (!glyph_count)) {
- if (feats) gr_featureval_destroy (feats);
- gr_seg_destroy (seg);
- buffer->len = 0;
- return true;
- }
-
- (void) buffer->ensure (glyph_count);
- scratch = buffer->get_scratch_buffer (&scratch_size);
- while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
- DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)
- {
- if (unlikely (!buffer->ensure (buffer->allocated * 2)))
- {
- if (feats) gr_featureval_destroy (feats);
- gr_seg_destroy (seg);
- return false;
- }
- scratch = buffer->get_scratch_buffer (&scratch_size);
- }
-
-#define ALLOCATE_ARRAY(Type, name, len) \
- Type *name = (Type *) scratch; \
- do { \
- unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
- assert (_consumed <= scratch_size); \
- scratch += _consumed; \
- scratch_size -= _consumed; \
- } while (0)
-
- ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
- ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
-
-#undef ALLOCATE_ARRAY
-
- hb_memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
-
- hb_codepoint_t *pg = gids;
- clusters[0].cluster = buffer->info[0].cluster;
- unsigned int upem = hb_face_get_upem (face);
- float xscale = (float) font->x_scale / upem;
- float yscale = (float) font->y_scale / upem;
- yscale *= yscale / xscale;
- unsigned int curradv = 0;
- if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
- {
- curradv = gr_slot_origin_X(gr_seg_first_slot(seg)) * xscale;
- clusters[0].advance = gr_seg_advance_X(seg) * xscale - curradv;
- }
- else
- clusters[0].advance = 0;
- for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
- {
- unsigned int before = gr_slot_before (is);
- unsigned int after = gr_slot_after (is);
- *pg = gr_slot_gid (is);
- pg++;
- while (clusters[ci].base_char > before && ci)
- {
- clusters[ci-1].num_chars += clusters[ci].num_chars;
- clusters[ci-1].num_glyphs += clusters[ci].num_glyphs;
- clusters[ci-1].advance += clusters[ci].advance;
- ci--;
- }
-
- if (gr_slot_can_insert_before (is) && clusters[ci].num_chars && before >= clusters[ci].base_char + clusters[ci].num_chars)
- {
- hb_graphite2_cluster_t *c = clusters + ci + 1;
- c->base_char = clusters[ci].base_char + clusters[ci].num_chars;
- c->cluster = buffer->info[c->base_char].cluster;
- c->num_chars = before - c->base_char;
- c->base_glyph = ic;
- c->num_glyphs = 0;
- if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
- {
- c->advance = curradv - gr_slot_origin_X(is) * xscale;
- curradv -= c->advance;
- }
- else
- {
- c->advance = 0;
- clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv;
- curradv += clusters[ci].advance;
- }
- ci++;
- }
- clusters[ci].num_glyphs++;
-
- if (clusters[ci].base_char + clusters[ci].num_chars < after + 1)
- clusters[ci].num_chars = after + 1 - clusters[ci].base_char;
- }
-
- if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
- clusters[ci].advance += curradv;
- else
- clusters[ci].advance += gr_seg_advance_X(seg) * xscale - curradv;
- ci++;
-
- for (unsigned int i = 0; i < ci; ++i)
- {
- for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j)
- {
- hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
- info->codepoint = gids[clusters[i].base_glyph + j];
- info->cluster = clusters[i].cluster;
- info->var1.i32 = clusters[i].advance; // all glyphs in the cluster get the same advance
- }
- }
- buffer->len = glyph_count;
-
- /* Positioning. */
- unsigned int currclus = UINT_MAX;
- const hb_glyph_info_t *info = buffer->info;
- hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, nullptr);
- if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
- {
- curradvx = 0;
- for (is = gr_seg_first_slot (seg); is; pPos++, ++info, is = gr_slot_next_in_segment (is))
- {
- pPos->x_offset = gr_slot_origin_X (is) * xscale - curradvx;
- pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy;
- if (info->cluster != currclus) {
- pPos->x_advance = info->var1.i32;
- curradvx += pPos->x_advance;
- currclus = info->cluster;
- } else
- pPos->x_advance = 0.;
-
- pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale;
- curradvy += pPos->y_advance;
- }
- }
- else
- {
- curradvx = gr_seg_advance_X(seg) * xscale;
- for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is))
- {
- if (info->cluster != currclus)
- {
- pPos->x_advance = info->var1.i32;
- curradvx -= pPos->x_advance;
- currclus = info->cluster;
- } else
- pPos->x_advance = 0.;
-
- pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale;
- curradvy -= pPos->y_advance;
- pPos->x_offset = gr_slot_origin_X (is) * xscale - info->var1.i32 - curradvx + pPos->x_advance;
- pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy;
- }
- hb_buffer_reverse_clusters (buffer);
- }
-
- if (feats) gr_featureval_destroy (feats);
- gr_seg_destroy (seg);
-
- buffer->clear_glyph_flags ();
- buffer->unsafe_to_break ();
-
- return true;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h
deleted file mode 100644
index ee9229b8b00..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright © 2011 Martin Hosken
- * Copyright © 2011 SIL International
- *
- * 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.
- */
-
-#ifndef HB_GRAPHITE2_H
-#define HB_GRAPHITE2_H
-
-#include "hb.h"
-
-#include <graphite2/Font.h>
-
-HB_BEGIN_DECLS
-
-/**
- * HB_GRAPHITE2_TAG_SILF:
- *
- * The #hb_tag_t tag for the `Silf` table, which holds Graphite
- * features.
- *
- * For more information, see http://graphite.sil.org/
- *
- **/
-#define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f')
-
-
-HB_EXTERN gr_face *
-hb_graphite2_face_get_gr_face (hb_face_t *face);
-
-#ifndef HB_DISABLE_DEPRECATED
-
-HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face)
-HB_EXTERN gr_font *
-hb_graphite2_font_get_gr_font (hb_font_t *font);
-
-#endif
-
-
-HB_END_DECLS
-
-#endif /* HB_GRAPHITE2_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc b/src/3rdparty/harfbuzz-ng/src/hb-icu.cc
deleted file mode 100644
index e46401f7a61..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-icu.cc
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2009 Keith Stribley
- * Copyright © 2011 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_ICU
-
-#include "hb-icu.h"
-
-#include "hb-machinery.hh"
-
-#include <unicode/uchar.h>
-#include <unicode/unorm2.h>
-#include <unicode/ustring.h>
-#include <unicode/utf16.h>
-#include <unicode/uversion.h>
-
-/* ICU extra semicolon, fixed since 65, https://github.com/unicode-org/icu/commit/480bec3 */
-#if U_ICU_VERSION_MAJOR_NUM < 65 && (defined(__GNUC__) || defined(__clang__))
-#define HB_ICU_EXTRA_SEMI_IGNORED
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wextra-semi-stmt"
-#endif
-
-/**
- * SECTION:hb-icu
- * @title: hb-icu
- * @short_description: ICU integration
- * @include: hb-icu.h
- *
- * Functions for using HarfBuzz with the International Components for Unicode
- * (ICU) library. HarfBuzz supports using ICU to provide Unicode data, by attaching
- * ICU functions to the virtual methods in a #hb_unicode_funcs_t function
- * structure.
- **/
-
-/**
- * hb_icu_script_to_script:
- * @script: The UScriptCode identifier to query
- *
- * Fetches the #hb_script_t script that corresponds to the
- * specified UScriptCode identifier.
- *
- * Return value: the #hb_script_t script found
- *
- **/
-
-hb_script_t
-hb_icu_script_to_script (UScriptCode script)
-{
- if (unlikely (script == USCRIPT_INVALID_CODE))
- return HB_SCRIPT_INVALID;
-
- return hb_script_from_string (uscript_getShortName (script), -1);
-}
-
-/**
- * hb_icu_script_from_script:
- * @script: The #hb_script_t script to query
- *
- * Fetches the UScriptCode identifier that corresponds to the
- * specified #hb_script_t script.
- *
- * Return value: the UScriptCode identifier found
- *
- **/
-UScriptCode
-hb_icu_script_from_script (hb_script_t script)
-{
- if (unlikely (script == HB_SCRIPT_INVALID))
- return USCRIPT_INVALID_CODE;
-
- unsigned int numScriptCode = 1 + u_getIntPropertyMaxValue (UCHAR_SCRIPT);
- for (unsigned int i = 0; i < numScriptCode; i++)
- if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script))
- return (UScriptCode) i;
-
- return USCRIPT_UNKNOWN;
-}
-
-
-static hb_unicode_combining_class_t
-hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-
-{
- return (hb_unicode_combining_class_t) u_getCombiningClass (unicode);
-}
-
-static hb_unicode_general_category_t
-hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- switch (u_getIntPropertyValue(unicode, UCHAR_GENERAL_CATEGORY))
- {
- case U_UNASSIGNED: return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
-
- case U_UPPERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER;
- case U_LOWERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER;
- case U_TITLECASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER;
- case U_MODIFIER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER;
- case U_OTHER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
-
- case U_NON_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK;
- case U_ENCLOSING_MARK: return HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
- case U_COMBINING_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK;
-
- case U_DECIMAL_DIGIT_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER;
- case U_LETTER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER;
- case U_OTHER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER;
-
- case U_SPACE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
- case U_LINE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR;
- case U_PARAGRAPH_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR;
-
- case U_CONTROL_CHAR: return HB_UNICODE_GENERAL_CATEGORY_CONTROL;
- case U_FORMAT_CHAR: return HB_UNICODE_GENERAL_CATEGORY_FORMAT;
- case U_PRIVATE_USE_CHAR: return HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE;
- case U_SURROGATE: return HB_UNICODE_GENERAL_CATEGORY_SURROGATE;
-
-
- case U_DASH_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION;
- case U_START_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION;
- case U_END_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION;
- case U_CONNECTOR_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION;
- case U_OTHER_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION;
-
- case U_MATH_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL;
- case U_CURRENCY_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL;
- case U_MODIFIER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL;
- case U_OTHER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL;
-
- case U_INITIAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION;
- case U_FINAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION;
- }
-
- return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
-}
-
-static hb_codepoint_t
-hb_icu_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return u_charMirror(unicode);
-}
-
-static hb_script_t
-hb_icu_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- UErrorCode status = U_ZERO_ERROR;
- UScriptCode scriptCode = uscript_getScript(unicode, &status);
-
- if (unlikely (U_FAILURE (status)))
- return HB_SCRIPT_UNKNOWN;
-
- return hb_icu_script_to_script (scriptCode);
-}
-
-static hb_bool_t
-hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab,
- void *user_data)
-{
- const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data;
- UChar32 ret = unorm2_composePair (normalizer, a, b);
- if (ret < 0) return false;
- *ab = ret;
- return true;
-}
-
-static hb_bool_t
-hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t ab,
- hb_codepoint_t *a,
- hb_codepoint_t *b,
- void *user_data)
-{
- const UNormalizer2 *normalizer = (const UNormalizer2 *) user_data;
- UChar decomposed[4];
- int len;
- UErrorCode icu_err = U_ZERO_ERROR;
- len = unorm2_getRawDecomposition (normalizer, ab, decomposed,
- ARRAY_LENGTH (decomposed), &icu_err);
- if (U_FAILURE (icu_err) || len < 0) return false;
-
- len = u_countChar32 (decomposed, len);
- if (len == 1)
- {
- U16_GET_UNSAFE (decomposed, 0, *a);
- *b = 0;
- return *a != ab;
- }
- else if (len == 2)
- {
- len = 0;
- U16_NEXT_UNSAFE (decomposed, len, *a);
- U16_NEXT_UNSAFE (decomposed, len, *b);
- }
- return true;
-}
-
-
-static inline void free_static_icu_funcs ();
-
-static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_icu_unicode_funcs_lazy_loader_t>
-{
- static hb_unicode_funcs_t *create ()
- {
- void *user_data = nullptr;
- UErrorCode icu_err = U_ZERO_ERROR;
- user_data = (void *) unorm2_getNFCInstance (&icu_err);
- assert (user_data);
-
- hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
-
- hb_unicode_funcs_set_combining_class_func (funcs, hb_icu_unicode_combining_class, nullptr, nullptr);
- hb_unicode_funcs_set_general_category_func (funcs, hb_icu_unicode_general_category, nullptr, nullptr);
- hb_unicode_funcs_set_mirroring_func (funcs, hb_icu_unicode_mirroring, nullptr, nullptr);
- hb_unicode_funcs_set_script_func (funcs, hb_icu_unicode_script, nullptr, nullptr);
- hb_unicode_funcs_set_compose_func (funcs, hb_icu_unicode_compose, user_data, nullptr);
- hb_unicode_funcs_set_decompose_func (funcs, hb_icu_unicode_decompose, user_data, nullptr);
-
- hb_unicode_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_icu_funcs);
-
- return funcs;
- }
-} static_icu_funcs;
-
-static inline
-void free_static_icu_funcs ()
-{
- static_icu_funcs.free_instance ();
-}
-
-/**
- * hb_icu_get_unicode_funcs:
- *
- * Fetches a Unicode-functions structure that is populated
- * with the appropriate ICU function for each method.
- *
- * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
- *
- * Since: 0.9.38
- **/
-hb_unicode_funcs_t *
-hb_icu_get_unicode_funcs ()
-{
- return static_icu_funcs.get_unconst ();
-}
-
-#ifdef HB_ICU_EXTRA_SEMI_IGNORED
-#pragma GCC diagnostic pop
-#endif
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh b/src/3rdparty/harfbuzz-ng/src/hb-iter.hh
deleted file mode 100644
index b123b2f27cf..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh
+++ /dev/null
@@ -1,1026 +0,0 @@
-/*
- * Copyright © 2018 Google, Inc.
- * Copyright © 2019 Facebook, 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
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_ITER_HH
-#define HB_ITER_HH
-
-#include "hb.hh"
-#include "hb-algs.hh"
-#include "hb-meta.hh"
-
-
-/* Unified iterator object.
- *
- * The goal of this template is to make the same iterator interface
- * available to all types, and make it very easy and compact to use.
- * hb_iter_tator objects are small, light-weight, objects that can be
- * copied by value. If the collection / object being iterated on
- * is writable, then the iterator returns lvalues, otherwise it
- * returns rvalues.
- *
- * If iterator implementation implements operator!=, then it can be
- * used in range-based for loop. That already happens if the iterator
- * is random-access. Otherwise, the range-based for loop incurs
- * one traversal to find end(), which can be avoided if written
- * as a while-style for loop, or if iterator implements a faster
- * __end__() method. */
-
-/*
- * Base classes for iterators.
- */
-
-/* Base class for all iterators. */
-template <typename iter_t, typename Item = typename iter_t::__item_t__>
-struct hb_iter_t
-{
- typedef Item item_t;
- constexpr unsigned get_item_size () const { return hb_static_size (Item); }
- static constexpr bool is_iterator = true;
- static constexpr bool is_random_access_iterator = false;
- static constexpr bool is_sorted_iterator = false;
-
- private:
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
- iter_t* thiz () { return static_cast< iter_t *> (this); }
- public:
-
- /* Operators. */
- iter_t iter () const { return *thiz(); }
- iter_t operator + () const { return *thiz(); }
- iter_t _begin () const { return *thiz(); }
- iter_t begin () const { return _begin (); }
- iter_t _end () const { return thiz()->__end__ (); }
- iter_t end () const { return _end (); }
- explicit operator bool () const { return thiz()->__more__ (); }
- unsigned len () const { return thiz()->__len__ (); }
- /* The following can only be enabled if item_t is reference type. Otherwise
- * it will be returning pointer to temporary rvalue. */
- template <typename T = item_t,
- hb_enable_if (std::is_reference<T>::value)>
- hb_remove_reference<item_t>* operator -> () const { return std::addressof (**thiz()); }
- item_t operator * () const { return thiz()->__item__ (); }
- item_t operator * () { return thiz()->__item__ (); }
- item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
- item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); }
- iter_t& operator += (unsigned count) & { thiz()->__forward__ (count); return *thiz(); }
- iter_t operator += (unsigned count) && { thiz()->__forward__ (count); return *thiz(); }
- iter_t& operator ++ () & { thiz()->__next__ (); return *thiz(); }
- iter_t operator ++ () && { thiz()->__next__ (); return *thiz(); }
- iter_t& operator -= (unsigned count) & { thiz()->__rewind__ (count); return *thiz(); }
- iter_t operator -= (unsigned count) && { thiz()->__rewind__ (count); return *thiz(); }
- iter_t& operator -- () & { thiz()->__prev__ (); return *thiz(); }
- iter_t operator -- () && { thiz()->__prev__ (); return *thiz(); }
- iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; }
- friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; }
- iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; }
- iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; }
- iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; }
- template <typename T>
- iter_t& operator >> (T &v) & { v = **thiz(); ++*thiz(); return *thiz(); }
- template <typename T>
- iter_t operator >> (T &v) && { v = **thiz(); ++*thiz(); return *thiz(); }
- template <typename T>
- iter_t& operator << (const T v) & { **thiz() = v; ++*thiz(); return *thiz(); }
- template <typename T>
- iter_t operator << (const T v) && { **thiz() = v; ++*thiz(); return *thiz(); }
-
- protected:
- hb_iter_t () = default;
- hb_iter_t (const hb_iter_t &o HB_UNUSED) = default;
- hb_iter_t (hb_iter_t &&o HB_UNUSED) = default;
- hb_iter_t& operator = (const hb_iter_t &o HB_UNUSED) = default;
- hb_iter_t& operator = (hb_iter_t &&o HB_UNUSED) = default;
-};
-
-#define HB_ITER_USING(Name) \
- using item_t = typename Name::item_t; \
- using Name::_begin; \
- using Name::begin; \
- using Name::_end; \
- using Name::end; \
- using Name::get_item_size; \
- using Name::is_iterator; \
- using Name::iter; \
- using Name::operator bool; \
- using Name::len; \
- using Name::operator ->; \
- using Name::operator *; \
- using Name::operator []; \
- using Name::operator +=; \
- using Name::operator ++; \
- using Name::operator -=; \
- using Name::operator --; \
- using Name::operator +; \
- using Name::operator -; \
- using Name::operator >>; \
- using Name::operator <<; \
- static_assert (true, "")
-
-/* Returns iterator / item type of a type. */
-template <typename Iterable>
-using hb_iter_type = decltype (hb_deref (hb_declval (Iterable)).iter ());
-template <typename Iterable>
-using hb_item_type = decltype (*hb_deref (hb_declval (Iterable)).iter ());
-
-
-template <typename> struct hb_array_t;
-template <typename> struct hb_sorted_array_t;
-
-struct
-{
- template <typename T> hb_iter_type<T>
- operator () (T&& c) const
- { return hb_deref (std::forward<T> (c)).iter (); }
-
- /* Specialization for C arrays. */
-
- template <typename Type> inline hb_array_t<Type>
- operator () (Type *array, unsigned int length) const
- { return hb_array_t<Type> (array, length); }
-
- template <typename Type, unsigned int length> hb_array_t<Type>
- operator () (Type (&array)[length]) const
- { return hb_array_t<Type> (array, length); }
-
-}
-HB_FUNCOBJ (hb_iter);
-struct
-{
- template <typename T> auto
- impl (T&& c, hb_priority<1>) const HB_RETURN (unsigned, c.len ())
-
- template <typename T> auto
- impl (T&& c, hb_priority<0>) const HB_RETURN (unsigned, c.len)
-
- public:
-
- template <typename T> auto
- operator () (T&& c) const HB_RETURN (unsigned, impl (std::forward<T> (c), hb_prioritize))
-}
-HB_FUNCOBJ (hb_len);
-
-/* Mixin to fill in what the subclass doesn't provide. */
-template <typename iter_t, typename item_t = typename iter_t::__item_t__>
-struct hb_iter_fallback_mixin_t
-{
- private:
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
- iter_t* thiz () { return static_cast< iter_t *> (this); }
- public:
-
- /* Access: Implement __item__(), or __item_at__() if random-access. */
- item_t __item__ () const { return (*thiz())[0]; }
- item_t __item_at__ (unsigned i) const { return *(*thiz() + i); }
-
- /* Termination: Implement __more__(), or __len__() if random-access. */
- bool __more__ () const { return bool (thiz()->len ()); }
- unsigned __len__ () const
- { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; } return l; }
-
- /* Advancing: Implement __next__(), or __forward__() if random-access. */
- void __next__ () { *thiz() += 1; }
- void __forward__ (unsigned n) { while (*thiz() && n--) ++*thiz(); }
-
- /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */
- void __prev__ () { *thiz() -= 1; }
- void __rewind__ (unsigned n) { while (*thiz() && n--) --*thiz(); }
-
- /* Range-based for: Implement __end__() if can be done faster,
- * and operator!=. */
- iter_t __end__ () const
- {
- if (thiz()->is_random_access_iterator)
- return *thiz() + thiz()->len ();
- /* Above expression loops twice. Following loops once. */
- auto it = *thiz();
- while (it) ++it;
- return it;
- }
-
- protected:
- hb_iter_fallback_mixin_t () = default;
- hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
- hb_iter_fallback_mixin_t (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
- hb_iter_fallback_mixin_t& operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
- hb_iter_fallback_mixin_t& operator = (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
-};
-
-template <typename iter_t, typename item_t = typename iter_t::__item_t__>
-struct hb_iter_with_fallback_t :
- hb_iter_t<iter_t, item_t>,
- hb_iter_fallback_mixin_t<iter_t, item_t>
-{
- protected:
- hb_iter_with_fallback_t () = default;
- hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
- hb_iter_with_fallback_t (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
- hb_iter_with_fallback_t& operator = (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
- hb_iter_with_fallback_t& operator = (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
-};
-
-/*
- * Meta-programming predicates.
- */
-
-/* hb_is_iterator() / hb_is_iterator_of() */
-
-template<typename Iter, typename Item>
-struct hb_is_iterator_of
-{
- template <typename Item2 = Item>
- static hb_true_type impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
- static hb_false_type impl (hb_priority<0>, const void *);
-
- public:
- static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value;
-};
-#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value
-#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t)
-#define hb_is_sorted_iterator_of(Iter, Item) (hb_is_iterator_of<Iter, Item>::value && Iter::is_sorted_iterator)
-#define hb_is_sorted_iterator(Iter) hb_is_sorted_iterator_of (Iter, typename Iter::item_t)
-
-/* hb_is_iterable() */
-
-template <typename T>
-struct hb_is_iterable
-{
- private:
-
- template <typename U>
- static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_type ());
-
- template <typename>
- static hb_false_type impl (hb_priority<0>);
-
- public:
- static constexpr bool value = decltype (impl<T> (hb_prioritize))::value;
-};
-#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
-
-/* hb_is_source_of() / hb_is_sink_of() */
-
-template<typename Iter, typename Item>
-struct hb_is_source_of
-{
- private:
- template <typename Iter2 = Iter,
- hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<const Item>))>
- static hb_true_type impl (hb_priority<2>);
- template <typename Iter2 = Iter>
- static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());
- static hb_false_type impl (hb_priority<0>);
-
- public:
- static constexpr bool value = decltype (impl (hb_prioritize))::value;
-};
-#define hb_is_source_of(Iter, Item) hb_is_source_of<Iter, Item>::value
-
-template<typename Iter, typename Item>
-struct hb_is_sink_of
-{
- private:
- template <typename Iter2 = Iter,
- hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<Item>))>
- static hb_true_type impl (hb_priority<2>);
- template <typename Iter2 = Iter>
- static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_type ());
- static hb_false_type impl (hb_priority<0>);
-
- public:
- static constexpr bool value = decltype (impl (hb_prioritize))::value;
-};
-#define hb_is_sink_of(Iter, Item) hb_is_sink_of<Iter, Item>::value
-
-/* This is commonly used, so define: */
-#define hb_is_sorted_source_of(Iter, Item) \
- (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator)
-
-
-/* Range-based 'for' for iterables. */
-
-template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
-static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
-
-template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
-static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
-
-/* begin()/end() are NOT looked up non-ADL. So each namespace must declare them.
- * Do it for namespace OT. */
-namespace OT {
-
-template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
-static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
-
-template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
-static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
-
-}
-
-
-/*
- * Adaptors, combiners, etc.
- */
-
-template <typename Lhs, typename Rhs,
- hb_requires (hb_is_iterator (Lhs))>
-static inline auto
-operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (std::forward<Rhs> (rhs) (std::forward<Lhs> (lhs)))
-
-/* hb_map(), hb_filter(), hb_reduce() */
-
-enum class hb_function_sortedness_t {
- NOT_SORTED,
- RETAINS_SORTING,
- SORTED,
-};
-
-template <typename Iter, typename Proj, hb_function_sortedness_t Sorted,
- hb_requires (hb_is_iterator (Iter))>
-struct hb_map_iter_t :
- hb_iter_t<hb_map_iter_t<Iter, Proj, Sorted>,
- decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))>
-{
- hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {}
-
- typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__;
- static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
- static constexpr bool is_sorted_iterator =
- Sorted == hb_function_sortedness_t::SORTED ? true :
- Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator :
- false;
- __item_t__ __item__ () const { return hb_get (f.get (), *it); }
- __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
- bool __more__ () const { return bool (it); }
- unsigned __len__ () const { return it.len (); }
- void __next__ () { ++it; }
- void __forward__ (unsigned n) { it += n; }
- void __prev__ () { --it; }
- void __rewind__ (unsigned n) { it -= n; }
- hb_map_iter_t __end__ () const { return hb_map_iter_t (it._end (), f); }
- bool operator != (const hb_map_iter_t& o) const
- { return it != o.it; }
-
- private:
- Iter it;
- hb_reference_wrapper<Proj> f;
-};
-
-template <typename Proj, hb_function_sortedness_t Sorted>
-struct hb_map_iter_factory_t
-{
- hb_map_iter_factory_t (Proj f) : f (f) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- hb_map_iter_t<Iter, Proj, Sorted>
- operator () (Iter it)
- { return hb_map_iter_t<Iter, Proj, Sorted> (it, f); }
-
- private:
- Proj f;
-};
-struct
-{
- template <typename Proj>
- hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED>
- operator () (Proj&& f) const
- { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED> (f); }
-}
-HB_FUNCOBJ (hb_map);
-struct
-{
- template <typename Proj>
- hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING>
- operator () (Proj&& f) const
- { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING> (f); }
-}
-HB_FUNCOBJ (hb_map_retains_sorting);
-struct
-{
- template <typename Proj>
- hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED>
- operator () (Proj&& f) const
- { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED> (f); }
-}
-HB_FUNCOBJ (hb_map_sorted);
-
-template <typename Iter, typename Pred, typename Proj,
- hb_requires (hb_is_iterator (Iter))>
-struct hb_filter_iter_t :
- hb_iter_with_fallback_t<hb_filter_iter_t<Iter, Pred, Proj>,
- typename Iter::item_t>
-{
- hb_filter_iter_t (const Iter& it_, Pred p_, Proj f_) : it (it_), p (p_), f (f_)
- { while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; }
-
- typedef typename Iter::item_t __item_t__;
- static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
- __item_t__ __item__ () const { return *it; }
- bool __more__ () const { return bool (it); }
- void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
- void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
- hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it._end (), p, f); }
- bool operator != (const hb_filter_iter_t& o) const
- { return it != o.it; }
-
- private:
- Iter it;
- hb_reference_wrapper<Pred> p;
- hb_reference_wrapper<Proj> f;
-};
-template <typename Pred, typename Proj>
-struct hb_filter_iter_factory_t
-{
- hb_filter_iter_factory_t (Pred p, Proj f) : p (p), f (f) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- hb_filter_iter_t<Iter, Pred, Proj>
- operator () (Iter it)
- { return hb_filter_iter_t<Iter, Pred, Proj> (it, p, f); }
-
- private:
- Pred p;
- Proj f;
-};
-struct
-{
- template <typename Pred = decltype ((hb_identity)),
- typename Proj = decltype ((hb_identity))>
- hb_filter_iter_factory_t<Pred, Proj>
- operator () (Pred&& p = hb_identity, Proj&& f = hb_identity) const
- { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
-}
-HB_FUNCOBJ (hb_filter);
-
-template <typename Redu, typename InitT>
-struct hb_reduce_t
-{
- hb_reduce_t (Redu r, InitT init_value) : r (r), init_value (init_value) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter)),
- typename AccuT = hb_decay<decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>>
- AccuT
- operator () (Iter it)
- {
- AccuT value = init_value;
- for (; it; ++it)
- value = r (value, *it);
- return value;
- }
-
- private:
- Redu r;
- InitT init_value;
-};
-struct
-{
- template <typename Redu, typename InitT>
- hb_reduce_t<Redu, InitT>
- operator () (Redu&& r, InitT init_value) const
- { return hb_reduce_t<Redu, InitT> (r, init_value); }
-}
-HB_FUNCOBJ (hb_reduce);
-
-
-/* hb_zip() */
-
-template <typename A, typename B>
-struct hb_zip_iter_t :
- hb_iter_t<hb_zip_iter_t<A, B>,
- hb_pair_t<typename A::item_t, typename B::item_t>>
-{
- hb_zip_iter_t () {}
- hb_zip_iter_t (const A& a, const B& b) : a (a), b (b) {}
-
- typedef hb_pair_t<typename A::item_t, typename B::item_t> __item_t__;
- static constexpr bool is_random_access_iterator =
- A::is_random_access_iterator &&
- B::is_random_access_iterator;
- /* Note. The following categorization is only valid if A is strictly sorted,
- * ie. does NOT have duplicates. Previously I tried to categorize sortedness
- * more granularly, see commits:
- *
- * 513762849a683914fc266a17ddf38f133cccf072
- * 4d3cf2adb669c345cc43832d11689271995e160a
- *
- * However, that was not enough, since hb_sorted_array_t, hb_sorted_vector_t,
- * SortedArrayOf, etc all needed to be updated to add more variants. At that
- * point I saw it not worth the effort, and instead we now deem all sorted
- * collections as essentially strictly-sorted for the purposes of zip.
- *
- * The above assumption is not as bad as it sounds. Our "sorted" comes with
- * no guarantees. It's just a contract, put in place to help you remember,
- * and think about, whether an iterator you receive is expected to be
- * sorted or not. As such, it's not perfect by definition, and should not
- * be treated so. The inaccuracy here just errs in the direction of being
- * more permissive, so your code compiles instead of erring on the side of
- * marking your zipped iterator unsorted in which case your code won't
- * compile.
- *
- * This semantical limitation does NOT affect logic in any other place I
- * know of as of this writing.
- */
- static constexpr bool is_sorted_iterator = A::is_sorted_iterator;
-
- __item_t__ __item__ () const { return __item_t__ (*a, *b); }
- __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
- bool __more__ () const { return bool (a) && bool (b); }
- unsigned __len__ () const { return hb_min (a.len (), b.len ()); }
- void __next__ () { ++a; ++b; }
- void __forward__ (unsigned n) { a += n; b += n; }
- void __prev__ () { --a; --b; }
- void __rewind__ (unsigned n) { a -= n; b -= n; }
- hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a._end (), b._end ()); }
- /* Note, we should stop if ANY of the iters reaches end. As such two compare
- * unequal if both items are unequal, NOT if either is unequal. */
- bool operator != (const hb_zip_iter_t& o) const
- { return a != o.a && b != o.b; }
-
- private:
- A a;
- B b;
-};
-struct
-{ HB_PARTIALIZE(2);
- template <typename A, typename B,
- hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
- hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
- operator () (A&& a, B&& b) const
- { return hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
-}
-HB_FUNCOBJ (hb_zip);
-
-/* hb_concat() */
-
-template <typename A, typename B>
-struct hb_concat_iter_t :
- hb_iter_t<hb_concat_iter_t<A, B>, typename A::item_t>
-{
- hb_concat_iter_t () {}
- hb_concat_iter_t (A& a, B& b) : a (a), b (b) {}
- hb_concat_iter_t (const A& a, const B& b) : a (a), b (b) {}
-
-
- typedef typename A::item_t __item_t__;
- static constexpr bool is_random_access_iterator =
- A::is_random_access_iterator &&
- B::is_random_access_iterator;
- static constexpr bool is_sorted_iterator = false;
-
- __item_t__ __item__ () const
- {
- if (!a)
- return *b;
- return *a;
- }
-
- __item_t__ __item_at__ (unsigned i) const
- {
- unsigned a_len = a.len ();
- if (i < a_len)
- return a[i];
- return b[i - a_len];
- }
-
- bool __more__ () const { return bool (a) || bool (b); }
-
- unsigned __len__ () const { return a.len () + b.len (); }
-
- void __next__ ()
- {
- if (a)
- ++a;
- else
- ++b;
- }
-
- void __forward__ (unsigned n)
- {
- if (!n) return;
- if (!is_random_access_iterator) {
- while (n-- && *this) {
- (*this)++;
- }
- return;
- }
-
- unsigned a_len = a.len ();
- if (n > a_len) {
- n -= a_len;
- a.__forward__ (a_len);
- b.__forward__ (n);
- } else {
- a.__forward__ (n);
- }
- }
-
- hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a._end (), b._end ()); }
- bool operator != (const hb_concat_iter_t& o) const
- {
- return a != o.a
- || b != o.b;
- }
-
- private:
- A a;
- B b;
-};
-struct
-{ HB_PARTIALIZE(2);
- template <typename A, typename B,
- hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
- hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>>
- operator () (A&& a, B&& b) const
- { return hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
-}
-HB_FUNCOBJ (hb_concat);
-
-/* hb_apply() */
-
-template <typename Appl>
-struct hb_apply_t
-{
- hb_apply_t (Appl a) : a (a) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- void operator () (Iter it)
- {
- for (; it; ++it)
- (void) hb_invoke (a, *it);
- }
-
- private:
- Appl a;
-};
-struct
-{
- template <typename Appl> hb_apply_t<Appl>
- operator () (Appl&& a) const
- { return hb_apply_t<Appl> (a); }
-
- template <typename Appl> hb_apply_t<Appl&>
- operator () (Appl *a) const
- { return hb_apply_t<Appl&> (*a); }
-}
-HB_FUNCOBJ (hb_apply);
-
-/* hb_range()/hb_iota()/hb_repeat() */
-
-template <typename T, typename S>
-struct hb_range_iter_t :
- hb_iter_t<hb_range_iter_t<T, S>, T>
-{
- hb_range_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {}
-
- typedef T __item_t__;
- static constexpr bool is_random_access_iterator = true;
- static constexpr bool is_sorted_iterator = true;
- __item_t__ __item__ () const { return hb_ridentity (v); }
- __item_t__ __item_at__ (unsigned j) const { return v + j * step; }
- bool __more__ () const { return v != end_; }
- unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; }
- void __next__ () { v += step; }
- void __forward__ (unsigned n) { v += n * step; }
- void __prev__ () { v -= step; }
- void __rewind__ (unsigned n) { v -= n * step; }
- hb_range_iter_t __end__ () const { return hb_range_iter_t (end_, end_, step); }
- bool operator != (const hb_range_iter_t& o) const
- { return v != o.v; }
-
- private:
- static inline T end_for (T start, T end_, S step)
- {
- if (!step)
- return end_;
- auto res = (end_ - start) % step;
- if (!res)
- return end_;
- end_ += step - res;
- return end_;
- }
-
- private:
- T v;
- T end_;
- S step;
-};
-struct
-{
- template <typename T = unsigned> hb_range_iter_t<T, unsigned>
- operator () (T end = (unsigned) -1) const
- { return hb_range_iter_t<T, unsigned> (0, end, 1u); }
-
- template <typename T, typename S = unsigned> hb_range_iter_t<T, S>
- operator () (T start, T end, S step = 1u) const
- { return hb_range_iter_t<T, S> (start, end, step); }
-}
-HB_FUNCOBJ (hb_range);
-
-template <typename T, typename S>
-struct hb_iota_iter_t :
- hb_iter_with_fallback_t<hb_iota_iter_t<T, S>, T>
-{
- hb_iota_iter_t (T start, S step) : v (start), step (step) {}
-
- private:
-
- template <typename S2 = S>
- auto
- inc (hb_type_identity<S2> s, hb_priority<1>)
- -> hb_void_t<decltype (hb_invoke (std::forward<S2> (s), hb_declval<T&> ()))>
- { v = hb_invoke (std::forward<S2> (s), v); }
-
- void
- inc (S s, hb_priority<0>)
- { v += s; }
-
- public:
-
- typedef T __item_t__;
- static constexpr bool is_random_access_iterator = true;
- static constexpr bool is_sorted_iterator = true;
- __item_t__ __item__ () const { return hb_ridentity (v); }
- bool __more__ () const { return true; }
- unsigned __len__ () const { return UINT_MAX; }
- void __next__ () { inc (step, hb_prioritize); }
- void __prev__ () { v -= step; }
- hb_iota_iter_t __end__ () const { return *this; }
- bool operator != (const hb_iota_iter_t& o) const { return true; }
-
- private:
- T v;
- S step;
-};
-struct
-{
- template <typename T = unsigned, typename S = unsigned> hb_iota_iter_t<T, S>
- operator () (T start = 0u, S step = 1u) const
- { return hb_iota_iter_t<T, S> (start, step); }
-}
-HB_FUNCOBJ (hb_iota);
-
-template <typename T>
-struct hb_repeat_iter_t :
- hb_iter_t<hb_repeat_iter_t<T>, T>
-{
- hb_repeat_iter_t (T value) : v (value) {}
-
- typedef T __item_t__;
- static constexpr bool is_random_access_iterator = true;
- static constexpr bool is_sorted_iterator = true;
- __item_t__ __item__ () const { return v; }
- __item_t__ __item_at__ (unsigned j) const { return v; }
- bool __more__ () const { return true; }
- unsigned __len__ () const { return UINT_MAX; }
- void __next__ () {}
- void __forward__ (unsigned) {}
- void __prev__ () {}
- void __rewind__ (unsigned) {}
- hb_repeat_iter_t __end__ () const { return *this; }
- bool operator != (const hb_repeat_iter_t& o) const { return true; }
-
- private:
- T v;
-};
-struct
-{
- template <typename T> hb_repeat_iter_t<T>
- operator () (T value) const
- { return hb_repeat_iter_t<T> (value); }
-}
-HB_FUNCOBJ (hb_repeat);
-
-/* hb_enumerate()/hb_take() */
-
-struct
-{
- template <typename Iterable,
- typename Index = unsigned,
- hb_requires (hb_is_iterable (Iterable))>
- auto operator () (Iterable&& it, Index start = 0u) const HB_AUTO_RETURN
- ( hb_zip (hb_iota (start), it) )
-}
-HB_FUNCOBJ (hb_enumerate);
-
-struct
-{ HB_PARTIALIZE(2);
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN
- ( hb_zip (hb_range (count), it) | hb_map (hb_second) )
-
- /* Specialization arrays. */
-
- template <typename Type> inline hb_array_t<Type>
- operator () (hb_array_t<Type> array, unsigned count) const
- { return array.sub_array (0, count); }
-
- template <typename Type> inline hb_sorted_array_t<Type>
- operator () (hb_sorted_array_t<Type> array, unsigned count) const
- { return array.sub_array (0, count); }
-}
-HB_FUNCOBJ (hb_take);
-
-struct
-{ HB_PARTIALIZE(2);
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- auto operator () (Iter it, unsigned count) const HB_AUTO_RETURN
- (
- + hb_iota (it, hb_add (count))
- | hb_map (hb_take (count))
- | hb_take ((hb_len (it) + count - 1) / count)
- )
-}
-HB_FUNCOBJ (hb_chop);
-
-/* hb_sink() */
-
-template <typename Sink>
-struct hb_sink_t
-{
- hb_sink_t (Sink s) : s (s) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- void operator () (Iter it)
- {
- for (; it; ++it)
- s << *it;
- }
-
- private:
- Sink s;
-};
-struct
-{
- template <typename Sink> hb_sink_t<Sink>
- operator () (Sink&& s) const
- { return hb_sink_t<Sink> (s); }
-
- template <typename Sink> hb_sink_t<Sink&>
- operator () (Sink *s) const
- { return hb_sink_t<Sink&> (*s); }
-}
-HB_FUNCOBJ (hb_sink);
-
-/* hb-drain: hb_sink to void / blackhole / /dev/null. */
-
-struct
-{
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- void operator () (Iter it) const
- {
- for (; it; ++it)
- (void) *it;
- }
-}
-HB_FUNCOBJ (hb_drain);
-
-/* hb_unzip(): unzip and sink to two sinks. */
-
-template <typename Sink1, typename Sink2>
-struct hb_unzip_t
-{
- hb_unzip_t (Sink1 s1, Sink2 s2) : s1 (s1), s2 (s2) {}
-
- template <typename Iter,
- hb_requires (hb_is_iterator (Iter))>
- void operator () (Iter it)
- {
- for (; it; ++it)
- {
- const auto &v = *it;
- s1 << v.first;
- s2 << v.second;
- }
- }
-
- private:
- Sink1 s1;
- Sink2 s2;
-};
-struct
-{
- template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2>
- operator () (Sink1&& s1, Sink2&& s2) const
- { return hb_unzip_t<Sink1, Sink2> (s1, s2); }
-
- template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&>
- operator () (Sink1 *s1, Sink2 *s2) const
- { return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); }
-}
-HB_FUNCOBJ (hb_unzip);
-
-
-/* hb-all, hb-any, hb-none. */
-
-struct
-{
- template <typename Iterable,
- typename Pred = decltype ((hb_identity)),
- typename Proj = decltype ((hb_identity)),
- hb_requires (hb_is_iterable (Iterable))>
- bool operator () (Iterable&& c,
- Pred&& p = hb_identity,
- Proj&& f = hb_identity) const
- {
- for (auto it = hb_iter (c); it; ++it)
- if (!hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
- return false;
- return true;
- }
-}
-HB_FUNCOBJ (hb_all);
-struct
-{
- template <typename Iterable,
- typename Pred = decltype ((hb_identity)),
- typename Proj = decltype ((hb_identity)),
- hb_requires (hb_is_iterable (Iterable))>
- bool operator () (Iterable&& c,
- Pred&& p = hb_identity,
- Proj&& f = hb_identity) const
- {
- for (auto it = hb_iter (c); it; ++it)
- if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
- return true;
- return false;
- }
-}
-HB_FUNCOBJ (hb_any);
-struct
-{
- template <typename Iterable,
- typename Pred = decltype ((hb_identity)),
- typename Proj = decltype ((hb_identity)),
- hb_requires (hb_is_iterable (Iterable))>
- bool operator () (Iterable&& c,
- Pred&& p = hb_identity,
- Proj&& f = hb_identity) const
- {
- for (auto it = hb_iter (c); it; ++it)
- if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
- return false;
- return true;
- }
-}
-HB_FUNCOBJ (hb_none);
-
-/*
- * Algorithms operating on iterators.
- */
-
-template <typename C, typename V,
- hb_requires (hb_is_iterable (C))>
-inline void
-hb_fill (C&& c, const V &v)
-{
- for (auto i = hb_iter (c); i; i++)
- *i = v;
-}
-
-template <typename S, typename D>
-inline void
-hb_copy (S&& is, D&& id)
-{
- hb_iter (is) | hb_sink (id);
-}
-
-
-#endif /* HB_ITER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-kern.hh b/src/3rdparty/harfbuzz-ng/src/hb-kern.hh
deleted file mode 100644
index 9ea945caed6..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-kern.hh
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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_KERN_HH
-#define HB_KERN_HH
-
-#include "hb-open-type.hh"
-#include "hb-aat-layout-common.hh"
-#include "hb-ot-layout-gpos-table.hh"
-
-
-namespace OT {
-
-
-template <typename Driver>
-struct hb_kern_machine_t
-{
- hb_kern_machine_t (const Driver &driver_,
- bool crossStream_ = false) :
- driver (driver_),
- crossStream (crossStream_) {}
-
- HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
- void kern (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t kern_mask,
- bool scale = true) const
- {
- if (!buffer->message (font, "start kern"))
- return;
-
- buffer->unsafe_to_concat ();
- OT::hb_ot_apply_context_t c (1, font, buffer);
- c.set_lookup_mask (kern_mask);
- c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
- auto &skippy_iter = c.iter_input;
-
- bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- hb_glyph_position_t *pos = buffer->pos;
- for (unsigned int idx = 0; idx < count;)
- {
- if (!(info[idx].mask & kern_mask))
- {
- idx++;
- continue;
- }
-
- skippy_iter.reset (idx, 1);
- unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
- {
- idx++;
- continue;
- }
-
- unsigned int i = idx;
- unsigned int j = skippy_iter.idx;
-
- hb_position_t kern = driver.get_kerning (info[i].codepoint,
- info[j].codepoint);
-
-
- if (likely (!kern))
- goto skip;
-
- if (horizontal)
- {
- if (scale)
- kern = font->em_scale_x (kern);
- if (crossStream)
- {
- pos[j].y_offset = kern;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- }
- else
- {
- hb_position_t kern1 = kern >> 1;
- hb_position_t kern2 = kern - kern1;
- pos[i].x_advance += kern1;
- pos[j].x_advance += kern2;
- pos[j].x_offset += kern2;
- }
- }
- else
- {
- if (scale)
- kern = font->em_scale_y (kern);
- if (crossStream)
- {
- pos[j].x_offset = kern;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
- }
- else
- {
- hb_position_t kern1 = kern >> 1;
- hb_position_t kern2 = kern - kern1;
- pos[i].y_advance += kern1;
- pos[j].y_advance += kern2;
- pos[j].y_offset += kern2;
- }
- }
-
- buffer->unsafe_to_break (i, j + 1);
-
- skip:
- idx = skippy_iter.idx;
- }
-
- (void) buffer->message (font, "end kern");
- }
-
- const Driver &driver;
- bool crossStream;
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_KERN_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-limits.hh b/src/3rdparty/harfbuzz-ng/src/hb-limits.hh
deleted file mode 100644
index 0f60e9e2101..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-limits.hh
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_LIMITS_HH
-#define HB_LIMITS_HH
-
-#include "hb.hh"
-
-
-#ifndef HB_BUFFER_MAX_LEN_FACTOR
-#define HB_BUFFER_MAX_LEN_FACTOR 64
-#endif
-#ifndef HB_BUFFER_MAX_LEN_MIN
-#define HB_BUFFER_MAX_LEN_MIN 16384
-#endif
-#ifndef HB_BUFFER_MAX_LEN_DEFAULT
-#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
-#endif
-
-#ifndef HB_BUFFER_MAX_OPS_FACTOR
-#define HB_BUFFER_MAX_OPS_FACTOR 1024
-#endif
-#ifndef HB_BUFFER_MAX_OPS_MIN
-#define HB_BUFFER_MAX_OPS_MIN 16384
-#endif
-#ifndef HB_BUFFER_MAX_OPS_DEFAULT
-#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
-#endif
-
-
-#ifndef HB_MAX_NESTING_LEVEL
-#define HB_MAX_NESTING_LEVEL 64
-#endif
-
-
-#ifndef HB_MAX_CONTEXT_LENGTH
-#define HB_MAX_CONTEXT_LENGTH 64
-#endif
-
-#ifndef HB_CLOSURE_MAX_STAGES
-/*
- * The maximum number of times a lookup can be applied during shaping.
- * Used to limit the number of iterations of the closure algorithm.
- * This must be larger than the number of times add_gsub_pause() is
- * called in a collect_features call of any shaper.
- */
-#define HB_CLOSURE_MAX_STAGES 12
-#endif
-
-#ifndef HB_MAX_SCRIPTS
-#define HB_MAX_SCRIPTS 500
-#endif
-
-#ifndef HB_MAX_LANGSYS
-#define HB_MAX_LANGSYS 2000
-#endif
-
-#ifndef HB_MAX_LANGSYS_FEATURE_COUNT
-#define HB_MAX_LANGSYS_FEATURE_COUNT 50000
-#endif
-
-#ifndef HB_MAX_FEATURE_INDICES
-#define HB_MAX_FEATURE_INDICES 1500
-#endif
-
-#ifndef HB_MAX_LOOKUP_VISIT_COUNT
-#define HB_MAX_LOOKUP_VISIT_COUNT 35000
-#endif
-
-
-#ifndef HB_GLYF_MAX_POINTS
-#define HB_GLYF_MAX_POINTS 20000
-#endif
-
-#ifndef HB_GLYF_MAX_EDGE_COUNT
-#define HB_GLYF_MAX_EDGE_COUNT 1024
-#endif
-
-#ifndef HB_CFF_MAX_OPS
-#define HB_CFF_MAX_OPS 10000
-#endif
-
-#ifndef HB_COLRV1_MAX_EDGE_COUNT
-#define HB_COLRV1_MAX_EDGE_COUNT 1024
-#endif
-
-
-#endif /* HB_LIMITS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh
deleted file mode 100644
index 1084725af2a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2012,2018 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_MACHINERY_HH
-#define HB_MACHINERY_HH
-
-#include "hb.hh"
-#include "hb-blob.hh"
-
-#include "hb-dispatch.hh"
-#include "hb-sanitize.hh"
-
-
-/*
- * Casts
- */
-
-/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
- * location pointed to by P plus Ofs bytes. */
-template<typename Type>
-static inline const Type& StructAtOffset(const void *P, unsigned int offset)
-{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
-template<typename Type>
-static inline Type& StructAtOffset(void *P, unsigned int offset)
-{ return * reinterpret_cast<Type*> ((char *) P + offset); }
-template<typename Type>
-static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int offset)
-{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- return * reinterpret_cast<const Type*> ((const char *) P + offset);
-#pragma GCC diagnostic pop
-}
-template<typename Type>
-static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset)
-{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- return * reinterpret_cast<Type*> ((char *) P + offset);
-#pragma GCC diagnostic pop
-}
-
-/* StructAfter<T>(X) returns the struct T& that is placed after X.
- * Works with X of variable size also. X must implement get_size() */
-template<typename Type, typename TObject>
-static inline const Type& StructAfter(const TObject &X)
-{ return StructAtOffset<Type>(&X, X.get_size()); }
-template<typename Type, typename TObject>
-static inline Type& StructAfter(TObject &X)
-{ return StructAtOffset<Type>(&X, X.get_size()); }
-
-
-/*
- * Size checking
- */
-
-/* Size signifying variable-sized array */
-#ifndef HB_VAR_ARRAY
-#define HB_VAR_ARRAY 1
-#endif
-
-/* Check _assertion in a method environment */
-#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
- void _instance_assertion_on_line_##_line () const \
- { static_assert ((_assertion), ""); }
-# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
-# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
-
-/* Check that _code compiles in a method environment */
-#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
- void _compiles_assertion_on_line_##_line () const \
- { _code; }
-# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
-# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
-
-
-#define DEFINE_SIZE_STATIC(size) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \
- unsigned int get_size () const { return (size); } \
- static constexpr unsigned null_size = (size); \
- static constexpr unsigned min_size = (size); \
- static constexpr unsigned static_size = (size)
-
-#define DEFINE_SIZE_UNION(size, _member) \
- DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size) \
- DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)) \
- static constexpr unsigned null_size = (size); \
- static constexpr unsigned min_size = (size)
-
-#define DEFINE_SIZE_MIN(size) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
- static constexpr unsigned null_size = (size); \
- static constexpr unsigned min_size = (size)
-
-#define DEFINE_SIZE_UNBOUNDED(size) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
- static constexpr unsigned min_size = (size)
-
-#define DEFINE_SIZE_ARRAY(size, array) \
- DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
- DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + (HB_VAR_ARRAY+0) * sizeof ((array)[0])) \
- static constexpr unsigned null_size = (size); \
- static constexpr unsigned min_size = (size)
-
-#define DEFINE_SIZE_ARRAY_SIZED(size, array) \
- unsigned int get_size () const { return (size - (array).min_size + (array).get_size ()); } \
- DEFINE_SIZE_ARRAY(size, array)
-
-
-
-/*
- * Lazy loaders.
- *
- * The lazy-loaders are thread-safe pointer-like objects that create their
- * instead on-demand. They also support access to a "data" object that is
- * necessary for creating their instance. The data object, if specified,
- * is accessed via pointer math, located at a location before the position
- * of the loader itself. This avoids having to store a pointer to data
- * for every lazy-loader. Multiple lazy-loaders can access the same data.
- */
-
-template <typename Data, unsigned int WheresData>
-struct hb_data_wrapper_t
-{
- static_assert (WheresData > 0, "");
-
- Data * get_data () const
- { return *(((Data **) (void *) this) - WheresData); }
-
- bool is_inert () const { return !get_data (); }
-
- template <typename Stored, typename Subclass>
- Stored * call_create () const { return Subclass::create (get_data ()); }
-};
-template <>
-struct hb_data_wrapper_t<void, 0>
-{
- bool is_inert () const { return false; }
-
- template <typename Stored, typename Funcs>
- Stored * call_create () const { return Funcs::create (); }
-};
-
-template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
-template <typename T2> struct hb_non_void_t<void, T2> { typedef T2 value; };
-
-template <typename Returned,
- typename Subclass = void,
- typename Data = void,
- unsigned int WheresData = 0,
- typename Stored = Returned>
-struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
-{
- typedef typename hb_non_void_t<Subclass,
- hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored>
- >::value Funcs;
-
- void init0 () {} /* Init, when memory is already set to 0. No-op for us. */
- void init () { instance.set_relaxed (nullptr); }
- void fini () { do_destroy (instance.get_acquire ()); init (); }
-
- void free_instance ()
- {
- retry:
- Stored *p = instance.get_acquire ();
- if (unlikely (p && !cmpexch (p, nullptr)))
- goto retry;
- do_destroy (p);
- }
-
- static void do_destroy (Stored *p)
- {
- if (p && p != const_cast<Stored *> (Funcs::get_null ()))
- Funcs::destroy (p);
- }
-
- const Returned * operator -> () const { return get (); }
- template <typename U = Returned, hb_enable_if (!hb_is_same (U, void))>
- const U & operator * () const { return *get (); }
- explicit operator bool () const
- { return get_stored () != Funcs::get_null (); }
- template <typename C> operator const C * () const { return get (); }
-
- Stored * get_stored () const
- {
- retry:
- Stored *p = this->instance.get_acquire ();
- if (unlikely (!p))
- {
- if (unlikely (this->is_inert ()))
- return const_cast<Stored *> (Funcs::get_null ());
-
- p = this->template call_create<Stored, Funcs> ();
- if (unlikely (!p))
- p = const_cast<Stored *> (Funcs::get_null ());
-
- if (unlikely (!cmpexch (nullptr, p)))
- {
- do_destroy (p);
- goto retry;
- }
- }
- return p;
- }
- Stored * get_stored_relaxed () const
- {
- return this->instance.get_relaxed ();
- }
-
- bool cmpexch (Stored *current, Stored *value) const
- {
- /* This function can only be safely called directly if no
- * other thread is accessing. */
- return this->instance.cmpexch (current, value);
- }
-
- const Returned * get () const { return Funcs::convert (get_stored ()); }
- const Returned * get_relaxed () const { return Funcs::convert (get_stored_relaxed ()); }
- Returned * get_unconst () const { return const_cast<Returned *> (Funcs::convert (get_stored ())); }
-
- /* To be possibly overloaded by subclasses. */
- static Returned* convert (Stored *p) { return p; }
-
- /* By default null/init/fini the object. */
- static const Stored* get_null () { return &Null (Stored); }
- static Stored *create (Data *data)
- {
- Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
- if (likely (p))
- p = new (p) Stored (data);
- return p;
- }
- static Stored *create ()
- {
- Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
- if (likely (p))
- p = new (p) Stored ();
- return p;
- }
- static void destroy (Stored *p)
- {
- p->~Stored ();
- hb_free (p);
- }
-
- private:
- /* Must only have one pointer. */
- hb_atomic_ptr_t<Stored *> instance;
-};
-
-/* Specializations. */
-
-template <typename T, unsigned int WheresFace>
-struct hb_face_lazy_loader_t : hb_lazy_loader_t<T,
- hb_face_lazy_loader_t<T, WheresFace>,
- hb_face_t, WheresFace> {};
-
-template <typename T, unsigned int WheresFace, bool core=false>
-struct hb_table_lazy_loader_t : hb_lazy_loader_t<T,
- hb_table_lazy_loader_t<T, WheresFace, core>,
- hb_face_t, WheresFace,
- hb_blob_t>
-{
- static hb_blob_t *create (hb_face_t *face)
- {
- auto c = hb_sanitize_context_t ();
- if (core)
- c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs
- return c.reference_table<T> (face);
- }
- static void destroy (hb_blob_t *p) { hb_blob_destroy (p); }
-
- static const hb_blob_t *get_null ()
- { return hb_blob_get_empty (); }
-
- static const T* convert (const hb_blob_t *blob)
- { return blob->as<T> (); }
-
- hb_blob_t* get_blob () const { return this->get_stored (); }
-};
-
-#define HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T(Type) \
- template <typename Subclass> \
- struct hb_##Type##_funcs_lazy_loader_t : hb_lazy_loader_t<hb_##Type##_funcs_t, Subclass> \
- { \
- static void destroy (hb_##Type##_funcs_t *p) \
- { hb_##Type##_funcs_destroy (p); } \
- static const hb_##Type##_funcs_t *get_null () \
- { return hb_##Type##_funcs_get_empty (); } \
- }
-
-HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (font);
-HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (unicode);
-HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (draw);
-HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (paint);
-
-#undef HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T
-
-
-#endif /* HB_MACHINERY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-map.cc
deleted file mode 100644
index 5d67cd9a12d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-map.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright © 2018 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-map.hh"
-
-
-/**
- * SECTION:hb-map
- * @title: hb-map
- * @short_description: Object representing integer to integer mapping
- * @include: hb.h
- *
- * Map objects are integer-to-integer hash-maps. Currently they are
- * not used in the HarfBuzz public API, but are provided for client's
- * use if desired.
- **/
-
-
-/**
- * hb_map_create:
- *
- * Creates a new, initially empty map.
- *
- * Return value: (transfer full): The new #hb_map_t
- *
- * Since: 1.7.7
- **/
-hb_map_t *
-hb_map_create ()
-{
- hb_map_t *map;
-
- if (!(map = hb_object_create<hb_map_t> ()))
- return hb_map_get_empty ();
-
- return map;
-}
-
-/**
- * hb_map_get_empty:
- *
- * Fetches the singleton empty #hb_map_t.
- *
- * Return value: (transfer full): The empty #hb_map_t
- *
- * Since: 1.7.7
- **/
-hb_map_t *
-hb_map_get_empty ()
-{
- return const_cast<hb_map_t *> (&Null (hb_map_t));
-}
-
-/**
- * hb_map_reference: (skip)
- * @map: A map
- *
- * Increases the reference count on a map.
- *
- * Return value: (transfer full): The map
- *
- * Since: 1.7.7
- **/
-hb_map_t *
-hb_map_reference (hb_map_t *map)
-{
- return hb_object_reference (map);
-}
-
-/**
- * hb_map_destroy: (skip)
- * @map: A map
- *
- * Decreases the reference count on a map. When
- * the reference count reaches zero, the map is
- * destroyed, freeing all memory.
- *
- * Since: 1.7.7
- **/
-void
-hb_map_destroy (hb_map_t *map)
-{
- if (!hb_object_destroy (map)) return;
-
- hb_free (map);
-}
-
-/**
- * hb_map_set_user_data: (skip)
- * @map: A map
- * @key: The user-data key to set
- * @data: A pointer to the user data to set
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the specified map.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 1.7.7
- **/
-hb_bool_t
-hb_map_set_user_data (hb_map_t *map,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- return hb_object_set_user_data (map, key, data, destroy, replace);
-}
-
-/**
- * hb_map_get_user_data: (skip)
- * @map: A map
- * @key: The user-data key to query
- *
- * Fetches the user data associated with the specified key,
- * attached to the specified map.
- *
- * Return value: (transfer none): A pointer to the user data
- *
- * Since: 1.7.7
- **/
-void *
-hb_map_get_user_data (const hb_map_t *map,
- hb_user_data_key_t *key)
-{
- return hb_object_get_user_data (map, key);
-}
-
-
-/**
- * hb_map_allocation_successful:
- * @map: A map
- *
- * Tests whether memory allocation for a set was successful.
- *
- * Return value: `true` if allocation succeeded, `false` otherwise
- *
- * Since: 1.7.7
- **/
-hb_bool_t
-hb_map_allocation_successful (const hb_map_t *map)
-{
- return map->successful;
-}
-
-/**
- * hb_map_copy:
- * @map: A map
- *
- * Allocate a copy of @map.
- *
- * Return value: (transfer full): Newly-allocated map.
- *
- * Since: 4.4.0
- **/
-hb_map_t *
-hb_map_copy (const hb_map_t *map)
-{
- hb_map_t *copy = hb_map_create ();
- if (unlikely (copy->in_error ()))
- return hb_map_get_empty ();
-
- *copy = *map;
- return copy;
-}
-
-/**
- * hb_map_set:
- * @map: A map
- * @key: The key to store in the map
- * @value: The value to store for @key
- *
- * Stores @key:@value in the map.
- *
- * Since: 1.7.7
- **/
-void
-hb_map_set (hb_map_t *map,
- hb_codepoint_t key,
- hb_codepoint_t value)
-{
- /* Immutable-safe. */
- map->set (key, value);
-}
-
-/**
- * hb_map_get:
- * @map: A map
- * @key: The key to query
- *
- * Fetches the value stored for @key in @map.
- *
- * Since: 1.7.7
- **/
-hb_codepoint_t
-hb_map_get (const hb_map_t *map,
- hb_codepoint_t key)
-{
- return map->get (key);
-}
-
-/**
- * hb_map_del:
- * @map: A map
- * @key: The key to delete
- *
- * Removes @key and its stored value from @map.
- *
- * Since: 1.7.7
- **/
-void
-hb_map_del (hb_map_t *map,
- hb_codepoint_t key)
-{
- /* Immutable-safe. */
- map->del (key);
-}
-
-/**
- * hb_map_has:
- * @map: A map
- * @key: The key to query
- *
- * Tests whether @key is an element of @map.
- *
- * Return value: `true` if @key is found in @map, `false` otherwise
- *
- * Since: 1.7.7
- **/
-hb_bool_t
-hb_map_has (const hb_map_t *map,
- hb_codepoint_t key)
-{
- return map->has (key);
-}
-
-
-/**
- * hb_map_clear:
- * @map: A map
- *
- * Clears out the contents of @map.
- *
- * Since: 1.7.7
- **/
-void
-hb_map_clear (hb_map_t *map)
-{
- return map->clear ();
-}
-
-/**
- * hb_map_is_empty:
- * @map: A map
- *
- * Tests whether @map is empty (contains no elements).
- *
- * Return value: `true` if @map is empty
- *
- * Since: 1.7.7
- **/
-hb_bool_t
-hb_map_is_empty (const hb_map_t *map)
-{
- return map->is_empty ();
-}
-
-/**
- * hb_map_get_population:
- * @map: A map
- *
- * Returns the number of key-value pairs in the map.
- *
- * Return value: The population of @map
- *
- * Since: 1.7.7
- **/
-unsigned int
-hb_map_get_population (const hb_map_t *map)
-{
- return map->get_population ();
-}
-
-/**
- * hb_map_is_equal:
- * @map: A map
- * @other: Another map
- *
- * Tests whether @map and @other are equal (contain the same
- * elements).
- *
- * Return value: `true` if the two maps are equal, `false` otherwise.
- *
- * Since: 4.3.0
- **/
-hb_bool_t
-hb_map_is_equal (const hb_map_t *map,
- const hb_map_t *other)
-{
- return map->is_equal (*other);
-}
-
-/**
- * hb_map_hash:
- * @map: A map
- *
- * Creates a hash representing @map.
- *
- * Return value:
- * A hash of @map.
- *
- * Since: 4.4.0
- **/
-unsigned int
-hb_map_hash (const hb_map_t *map)
-{
- return map->hash ();
-}
-
-/**
- * hb_map_update:
- * @map: A map
- * @other: Another map
- *
- * Add the contents of @other to @map.
- *
- * Since: 7.0.0
- **/
-HB_EXTERN void
-hb_map_update (hb_map_t *map,
- const hb_map_t *other)
-{
- map->update (*other);
-}
-
-/**
- * hb_map_next:
- * @map: A map
- * @idx: (inout): Iterator internal state
- * @key: (out): Key retrieved
- * @value: (out): Value retrieved
- *
- * Fetches the next key/value paire in @map.
- *
- * Set @idx to -1 to get started.
- *
- * If the map is modified during iteration, the behavior is undefined.
- *
- * The order in which the key/values are returned is undefined.
- *
- * Return value: `true` if there was a next value, `false` otherwise
- *
- * Since: 7.0.0
- **/
-hb_bool_t
-hb_map_next (const hb_map_t *map,
- int *idx,
- hb_codepoint_t *key,
- hb_codepoint_t *value)
-{
- return map->next (idx, key, value);
-}
-
-/**
- * hb_map_keys:
- * @map: A map
- * @keys: A set
- *
- * Add the keys of @map to @keys.
- *
- * Since: 7.0.0
- **/
-void
-hb_map_keys (const hb_map_t *map,
- hb_set_t *keys)
-{
- hb_copy (map->keys() , *keys);
-}
-
-/**
- * hb_map_values:
- * @map: A map
- * @values: A set
- *
- * Add the values of @map to @values.
- *
- * Since: 7.0.0
- **/
-void
-hb_map_values (const hb_map_t *map,
- hb_set_t *values)
-{
- hb_copy (map->values() , *values);
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.h b/src/3rdparty/harfbuzz-ng/src/hb-map.h
deleted file mode 100644
index e928628fa7a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-map.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright © 2018 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
- */
-
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb.h> instead."
-#endif
-
-#ifndef HB_MAP_H
-#define HB_MAP_H
-
-#include "hb-common.h"
-#include "hb-set.h"
-
-HB_BEGIN_DECLS
-
-
-/**
- * HB_MAP_VALUE_INVALID:
- *
- * Unset #hb_map_t value.
- *
- * Since: 1.7.7
- */
-#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
-
-/**
- * hb_map_t:
- *
- * Data type for holding integer-to-integer hash maps.
- *
- **/
-typedef struct hb_map_t hb_map_t;
-
-
-HB_EXTERN hb_map_t *
-hb_map_create (void);
-
-HB_EXTERN hb_map_t *
-hb_map_get_empty (void);
-
-HB_EXTERN hb_map_t *
-hb_map_reference (hb_map_t *map);
-
-HB_EXTERN void
-hb_map_destroy (hb_map_t *map);
-
-HB_EXTERN hb_bool_t
-hb_map_set_user_data (hb_map_t *map,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace);
-
-HB_EXTERN void *
-hb_map_get_user_data (const hb_map_t *map,
- hb_user_data_key_t *key);
-
-
-/* Returns false if allocation has failed before */
-HB_EXTERN hb_bool_t
-hb_map_allocation_successful (const hb_map_t *map);
-
-HB_EXTERN hb_map_t *
-hb_map_copy (const hb_map_t *map);
-
-HB_EXTERN void
-hb_map_clear (hb_map_t *map);
-
-HB_EXTERN hb_bool_t
-hb_map_is_empty (const hb_map_t *map);
-
-HB_EXTERN unsigned int
-hb_map_get_population (const hb_map_t *map);
-
-HB_EXTERN hb_bool_t
-hb_map_is_equal (const hb_map_t *map,
- const hb_map_t *other);
-
-HB_EXTERN unsigned int
-hb_map_hash (const hb_map_t *map);
-
-HB_EXTERN void
-hb_map_set (hb_map_t *map,
- hb_codepoint_t key,
- hb_codepoint_t value);
-
-HB_EXTERN hb_codepoint_t
-hb_map_get (const hb_map_t *map,
- hb_codepoint_t key);
-
-HB_EXTERN void
-hb_map_del (hb_map_t *map,
- hb_codepoint_t key);
-
-HB_EXTERN hb_bool_t
-hb_map_has (const hb_map_t *map,
- hb_codepoint_t key);
-
-HB_EXTERN void
-hb_map_update (hb_map_t *map,
- const hb_map_t *other);
-
-/* Pass -1 in for idx to get started. */
-HB_EXTERN hb_bool_t
-hb_map_next (const hb_map_t *map,
- int *idx,
- hb_codepoint_t *key,
- hb_codepoint_t *value);
-
-HB_EXTERN void
-hb_map_keys (const hb_map_t *map,
- hb_set_t *keys);
-
-HB_EXTERN void
-hb_map_values (const hb_map_t *map,
- hb_set_t *values);
-
-HB_END_DECLS
-
-#endif /* HB_MAP_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-map.hh
deleted file mode 100644
index 041b8829afb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-map.hh
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright © 2018 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_MAP_HH
-#define HB_MAP_HH
-
-#include "hb.hh"
-
-#include "hb-set.hh"
-
-
-/*
- * hb_hashmap_t
- */
-
-extern HB_INTERNAL const hb_codepoint_t minus_1;
-
-template <typename K, typename V,
- bool minus_one = false>
-struct hb_hashmap_t
-{
- hb_hashmap_t () { init (); }
- ~hb_hashmap_t () { fini (); }
-
- hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
- hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
- hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); resize (o.population); hb_copy (o, *this); return *this; }
- hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; }
-
- hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
- {
- for (auto&& item : lst)
- set (item.first, item.second);
- }
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
- {
- auto iter = hb_iter (o);
- if (iter.is_random_access_iterator)
- resize (hb_len (iter));
- hb_copy (iter, *this);
- }
-
- struct item_t
- {
- K key;
- uint32_t hash : 30;
- uint32_t is_used_ : 1;
- uint32_t is_tombstone_ : 1;
- V value;
-
- item_t () : key (),
- hash (0),
- is_used_ (false), is_tombstone_ (false),
- value () {}
-
- bool is_used () const { return is_used_; }
- void set_used (bool is_used) { is_used_ = is_used; }
- bool is_tombstone () const { return is_tombstone_; }
- void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
- bool is_real () const { return is_used_ && !is_tombstone_; }
-
- template <bool v = minus_one,
- hb_enable_if (v == false)>
- static inline const V& default_value () { return Null(V); };
- template <bool v = minus_one,
- hb_enable_if (v == true)>
- static inline const V& default_value ()
- {
- static_assert (hb_is_same (V, hb_codepoint_t), "");
- return minus_1;
- };
-
- bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
- bool operator == (const item_t &o) const { return *this == o.key; }
- hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
- hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
-
- uint32_t total_hash () const
- { return (hash * 31) + hb_hash (value); }
- };
-
- hb_object_header_t header;
- unsigned int successful : 1; /* Allocations successful */
- unsigned int population : 31; /* Not including tombstones. */
- unsigned int occupancy; /* Including tombstones. */
- unsigned int mask;
- unsigned int prime;
- item_t *items;
-
- friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
- {
- if (unlikely (!a.successful || !b.successful))
- return;
- unsigned tmp = a.population;
- a.population = b.population;
- b.population = tmp;
- //hb_swap (a.population, b.population);
- hb_swap (a.occupancy, b.occupancy);
- hb_swap (a.mask, b.mask);
- hb_swap (a.prime, b.prime);
- hb_swap (a.items, b.items);
- }
- void init ()
- {
- hb_object_init (this);
-
- successful = true;
- population = occupancy = 0;
- mask = 0;
- prime = 0;
- items = nullptr;
- }
- void fini ()
- {
- hb_object_fini (this);
-
- if (likely (items)) {
- unsigned size = mask + 1;
- for (unsigned i = 0; i < size; i++)
- items[i].~item_t ();
- hb_free (items);
- items = nullptr;
- }
- population = occupancy = 0;
- }
-
- void reset ()
- {
- successful = true;
- clear ();
- }
-
- bool in_error () const { return !successful; }
-
- bool resize (unsigned new_population = 0)
- {
- if (unlikely (!successful)) return false;
-
- if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
-
- unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
- unsigned int new_size = 1u << power;
- item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
- if (unlikely (!new_items))
- {
- successful = false;
- return false;
- }
- for (auto &_ : hb_iter (new_items, new_size))
- new (&_) item_t ();
-
- unsigned int old_size = size ();
- item_t *old_items = items;
-
- /* Switch to new, empty, array. */
- population = occupancy = 0;
- mask = new_size - 1;
- prime = prime_for (power);
- items = new_items;
-
- /* Insert back old items. */
- for (unsigned int i = 0; i < old_size; i++)
- {
- if (old_items[i].is_real ())
- {
- set_with_hash (std::move (old_items[i].key),
- old_items[i].hash,
- std::move (old_items[i].value));
- }
- old_items[i].~item_t ();
- }
-
- hb_free (old_items);
-
- return true;
- }
-
- template <typename KK, typename VV>
- bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
- {
- if (unlikely (!successful)) return false;
- if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
- item_t &item = item_for_hash (key, hash);
-
- if (is_delete && !(item == key))
- return true; /* Trying to delete non-existent key. */
-
- if (item.is_used ())
- {
- occupancy--;
- if (!item.is_tombstone ())
- population--;
- }
-
- item.key = std::forward<KK> (key);
- item.value = std::forward<VV> (value);
- item.hash = hash;
- item.set_used (true);
- item.set_tombstone (is_delete);
-
- occupancy++;
- if (!is_delete)
- population++;
-
- return true;
- }
-
- template <typename VV>
- bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
- template <typename VV>
- bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); }
-
- const V& get_with_hash (const K &key, uint32_t hash) const
- {
- if (unlikely (!items)) return item_t::default_value ();
- auto &item = item_for_hash (key, hash);
- return item.is_real () && item == key ? item.value : item_t::default_value ();
- }
- const V& get (const K &key) const
- {
- if (unlikely (!items)) return item_t::default_value ();
- return get_with_hash (key, hb_hash (key));
- }
-
- void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
-
- /* Has interface. */
- const V& operator [] (K k) const { return get (k); }
- template <typename VV=V>
- bool has (K key, VV **vp = nullptr) const
- {
- if (unlikely (!items))
- return false;
- auto &item = item_for_hash (key, hb_hash (key));
- if (item.is_real () && item == key)
- {
- if (vp) *vp = std::addressof (item.value);
- return true;
- }
- else
- return false;
- }
- /* Projection. */
- V operator () (K k) const { return get (k); }
-
- unsigned size () const { return mask ? mask + 1 : 0; }
-
- void clear ()
- {
- if (unlikely (!successful)) return;
-
- for (auto &_ : hb_iter (items, size ()))
- {
- /* Reconstruct items. */
- _.~item_t ();
- new (&_) item_t ();
- }
-
- population = occupancy = 0;
- }
-
- bool is_empty () const { return population == 0; }
- explicit operator bool () const { return !is_empty (); }
-
- uint32_t hash () const
- {
- return
- + iter_items ()
- | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u)
- ;
- }
-
- bool is_equal (const hb_hashmap_t &other) const
- {
- if (population != other.population) return false;
-
- for (auto pair : iter ())
- if (other.get (pair.first) != pair.second)
- return false;
-
- return true;
- }
- bool operator == (const hb_hashmap_t &other) const { return is_equal (other); }
- bool operator != (const hb_hashmap_t &other) const { return !is_equal (other); }
-
- unsigned int get_population () const { return population; }
-
- void update (const hb_hashmap_t &other)
- {
- if (unlikely (!successful)) return;
-
- hb_copy (other, *this);
- }
-
- /*
- * Iterator
- */
-
- auto iter_items () const HB_AUTO_RETURN
- (
- + hb_iter (items, size ())
- | hb_filter (&item_t::is_real)
- )
- auto iter_ref () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::get_pair_ref)
- )
- auto iter () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::get_pair)
- )
- auto keys_ref () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::key)
- )
- auto keys () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::key)
- | hb_map (hb_ridentity)
- )
- auto values_ref () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::value)
- )
- auto values () const HB_AUTO_RETURN
- (
- + iter_items ()
- | hb_map (&item_t::value)
- | hb_map (hb_ridentity)
- )
-
- /* C iterator. */
- bool next (int *idx,
- K *key,
- V *value) const
- {
- unsigned i = (unsigned) (*idx + 1);
-
- unsigned count = size ();
- while (i < count && !items[i].is_real ())
- i++;
-
- if (i >= count)
- {
- *idx = -1;
- return false;
- }
-
- *key = items[i].key;
- *value = items[i].value;
-
- *idx = (signed) i;
- return true;
- }
-
- /* Sink interface. */
- hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
- { set (v.first, v.second); return *this; }
- hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v)
- { set (v.first, std::move (v.second)); return *this; }
- hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v)
- { set (std::move (v.first), v.second); return *this; }
- hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
- { set (std::move (v.first), std::move (v.second)); return *this; }
-
- item_t& item_for_hash (const K &key, uint32_t hash) const
- {
- hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
- unsigned int i = hash % prime;
- unsigned int step = 0;
- unsigned int tombstone = (unsigned) -1;
- while (items[i].is_used ())
- {
- if (items[i].hash == hash && items[i] == key)
- return items[i];
- if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
- tombstone = i;
- i = (i + ++step) & mask;
- }
- return items[tombstone == (unsigned) -1 ? i : tombstone];
- }
-
- static unsigned int prime_for (unsigned int shift)
- {
- /* Following comment and table copied from glib. */
- /* Each table size has an associated prime modulo (the first prime
- * lower than the table size) used to find the initial bucket. Probing
- * then works modulo 2^n. The prime modulo is necessary to get a
- * good distribution with poor hash functions.
- */
- /* Not declaring static to make all kinds of compilers happy... */
- /*static*/ const unsigned int prime_mod [32] =
- {
- 1, /* For 1 << 0 */
- 2,
- 3,
- 7,
- 13,
- 31,
- 61,
- 127,
- 251,
- 509,
- 1021,
- 2039,
- 4093,
- 8191,
- 16381,
- 32749,
- 65521, /* For 1 << 16 */
- 131071,
- 262139,
- 524287,
- 1048573,
- 2097143,
- 4194301,
- 8388593,
- 16777213,
- 33554393,
- 67108859,
- 134217689,
- 268435399,
- 536870909,
- 1073741789,
- 2147483647 /* For 1 << 31 */
- };
-
- if (unlikely (shift >= ARRAY_LENGTH (prime_mod)))
- return prime_mod[ARRAY_LENGTH (prime_mod) - 1];
-
- return prime_mod[shift];
- }
-};
-
-/*
- * hb_map_t
- */
-
-struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
- hb_codepoint_t,
- true>
-{
- using hashmap = hb_hashmap_t<hb_codepoint_t,
- hb_codepoint_t,
- true>;
-
- ~hb_map_t () = default;
- hb_map_t () : hashmap () {}
- hb_map_t (const hb_map_t &o) : hashmap ((hashmap &) o) {}
- hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {}
- hb_map_t& operator= (const hb_map_t&) = default;
- hb_map_t& operator= (hb_map_t&&) = default;
- hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_map_t (const Iterable &o) : hashmap (o) {}
-};
-
-
-#endif /* HB_MAP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-meta.hh b/src/3rdparty/harfbuzz-ng/src/hb-meta.hh
deleted file mode 100644
index 31aa7fa6f16..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-meta.hh
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright © 2018 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_META_HH
-#define HB_META_HH
-
-#include "hb.hh"
-
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-
-/*
- * C++ template meta-programming & fundamentals used with them.
- */
-
-/* Void! For when we need a expression-type of void. */
-struct hb_empty_t {};
-
-/* https://en.cppreference.com/w/cpp/types/void_t */
-template<typename... Ts> struct _hb_void_t { typedef void type; };
-template<typename... Ts> using hb_void_t = typename _hb_void_t<Ts...>::type;
-
-template<typename Head, typename... Ts> struct _hb_head_t { typedef Head type; };
-template<typename... Ts> using hb_head_t = typename _hb_head_t<Ts...>::type;
-
-template <typename T, T v> struct hb_integral_constant { static constexpr T value = v; };
-template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>;
-using hb_true_type = hb_bool_constant<true>;
-using hb_false_type = hb_bool_constant<false>;
-
-/* Static-assert as expression. */
-template <bool cond> struct static_assert_expr;
-template <> struct static_assert_expr<true> : hb_false_type {};
-#define static_assert_expr(C) static_assert_expr<C>::value
-
-/* Basic type SFINAE. */
-
-template <bool B, typename T = void> struct hb_enable_if {};
-template <typename T> struct hb_enable_if<true, T> { typedef T type; };
-#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
-/* Concepts/Requires alias: */
-#define hb_requires(Cond) hb_enable_if((Cond))
-
-template <typename T, typename T2> struct hb_is_same : hb_false_type {};
-template <typename T> struct hb_is_same<T, T> : hb_true_type {};
-#define hb_is_same(T, T2) hb_is_same<T, T2>::value
-
-/* Function overloading SFINAE and priority. */
-
-#define HB_RETURN(Ret, E) -> hb_head_t<Ret, decltype ((E))> { return (E); }
-#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
-#define HB_VOID_RETURN(E) -> hb_void_t<decltype ((E))> { (E); }
-
-template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
-template <> struct hb_priority<0> {};
-#define hb_prioritize hb_priority<16> ()
-
-#define HB_FUNCOBJ(x) static_const x HB_UNUSED
-
-
-template <typename T> struct hb_type_identity_t { typedef T type; };
-template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
-
-template <typename T> static inline T hb_declval ();
-#define hb_declval(T) (hb_declval<T> ())
-
-template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_false_type {};
-template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_true_type {};
-template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
-
-template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_false_type {};
-template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_true_type {};
-template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_true_type {};
-template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
-template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>;
-template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
-template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference<T> (hb_prioritize));
-template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
-template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
-template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
-
-template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_false_type {};
-template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_true_type {};
-template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
-template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
-template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
-template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
-
-
-template <typename T> using hb_decay = typename std::decay<T>::type;
-
-#define hb_is_convertible(From,To) std::is_convertible<From, To>::value
-
-template <typename From, typename To>
-using hb_is_cr_convertible = hb_bool_constant<
- hb_is_same (hb_decay<From>, hb_decay<To>) &&
- (!std::is_const<From>::value || std::is_const<To>::value) &&
- (!std::is_reference<To>::value || std::is_const<To>::value || std::is_reference<To>::value)
->;
-#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
-
-
-struct
-{
- template <typename T> constexpr auto
- operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
-
- template <typename T> constexpr auto
- operator () (T *v) const HB_AUTO_RETURN (*v)
-
- template <typename T> constexpr auto
- operator () (const hb::shared_ptr<T>& v) const HB_AUTO_RETURN (*v)
-
- template <typename T> constexpr auto
- operator () (hb::shared_ptr<T>& v) const HB_AUTO_RETURN (*v)
-
- template <typename T> constexpr auto
- operator () (const hb::unique_ptr<T>& v) const HB_AUTO_RETURN (*v)
-
- template <typename T> constexpr auto
- operator () (hb::unique_ptr<T>& v) const HB_AUTO_RETURN (*v)
-}
-HB_FUNCOBJ (hb_deref);
-
-template <typename T>
-struct hb_reference_wrapper
-{
- hb_reference_wrapper (T v) : v (v) {}
- bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
- bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
- operator T () const { return v; }
- T get () const { return v; }
- T v;
-};
-template <typename T>
-struct hb_reference_wrapper<T&>
-{
- hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
- bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
- bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
- operator T& () const { return *v; }
- T& get () const { return *v; }
- T* v;
-};
-
-
-/* Type traits */
-
-template <typename T> struct hb_int_min;
-template <> struct hb_int_min<char> : hb_integral_constant<char, CHAR_MIN> {};
-template <> struct hb_int_min<signed char> : hb_integral_constant<signed char, SCHAR_MIN> {};
-template <> struct hb_int_min<unsigned char> : hb_integral_constant<unsigned char, 0> {};
-template <> struct hb_int_min<signed short> : hb_integral_constant<signed short, SHRT_MIN> {};
-template <> struct hb_int_min<unsigned short> : hb_integral_constant<unsigned short, 0> {};
-template <> struct hb_int_min<signed int> : hb_integral_constant<signed int, INT_MIN> {};
-template <> struct hb_int_min<unsigned int> : hb_integral_constant<unsigned int, 0> {};
-template <> struct hb_int_min<signed long> : hb_integral_constant<signed long, LONG_MIN> {};
-template <> struct hb_int_min<unsigned long> : hb_integral_constant<unsigned long, 0> {};
-template <> struct hb_int_min<signed long long> : hb_integral_constant<signed long long, LLONG_MIN> {};
-template <> struct hb_int_min<unsigned long long> : hb_integral_constant<unsigned long long, 0> {};
-template <typename T> struct hb_int_min<T *> : hb_integral_constant<T *, nullptr> {};
-#define hb_int_min(T) hb_int_min<T>::value
-template <typename T> struct hb_int_max;
-template <> struct hb_int_max<char> : hb_integral_constant<char, CHAR_MAX> {};
-template <> struct hb_int_max<signed char> : hb_integral_constant<signed char, SCHAR_MAX> {};
-template <> struct hb_int_max<unsigned char> : hb_integral_constant<unsigned char, UCHAR_MAX> {};
-template <> struct hb_int_max<signed short> : hb_integral_constant<signed short, SHRT_MAX> {};
-template <> struct hb_int_max<unsigned short> : hb_integral_constant<unsigned short, USHRT_MAX> {};
-template <> struct hb_int_max<signed int> : hb_integral_constant<signed int, INT_MAX> {};
-template <> struct hb_int_max<unsigned int> : hb_integral_constant<unsigned int, UINT_MAX> {};
-template <> struct hb_int_max<signed long> : hb_integral_constant<signed long, LONG_MAX> {};
-template <> struct hb_int_max<unsigned long> : hb_integral_constant<unsigned long, ULONG_MAX> {};
-template <> struct hb_int_max<signed long long> : hb_integral_constant<signed long long, LLONG_MAX> {};
-template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {};
-#define hb_int_max(T) hb_int_max<T>::value
-
-#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
-#define hb_is_trivially_copyable(T) __has_trivial_copy(T)
-#define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T)
-#define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
-#define hb_is_trivially_copy_constructible(T) __has_trivial_copy_constructor(T)
-#define hb_is_trivially_destructible(T) __has_trivial_destructor(T)
-#else
-#define hb_is_trivially_copyable(T) std::is_trivially_copyable<T>::value
-#define hb_is_trivially_copy_assignable(T) std::is_trivially_copy_assignable<T>::value
-#define hb_is_trivially_constructible(T) std::is_trivially_constructible<T>::value
-#define hb_is_trivially_copy_constructible(T) std::is_trivially_copy_constructible<T>::value
-#define hb_is_trivially_destructible(T) std::is_trivially_destructible<T>::value
-#endif
-
-/* Class traits. */
-
-#define HB_DELETE_COPY_ASSIGN(TypeName) \
- TypeName(const TypeName&) = delete; \
- void operator=(const TypeName&) = delete
-#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \
- TypeName() = delete; \
- TypeName(const TypeName&) = delete; \
- void operator=(const TypeName&) = delete
-
-/* hb_unwrap_type (T)
- * If T has no T::type, returns T. Otherwise calls itself on T::type recursively.
- */
-
-template <typename T, typename>
-struct _hb_unwrap_type : hb_type_identity_t<T> {};
-template <typename T>
-struct _hb_unwrap_type<T, hb_void_t<typename T::type>> : _hb_unwrap_type<typename T::type, void> {};
-template <typename T>
-using hb_unwrap_type = _hb_unwrap_type<T, void>;
-#define hb_unwrap_type(T) typename hb_unwrap_type<T>::type
-
-#endif /* HB_META_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ms-feature-ranges.hh b/src/3rdparty/harfbuzz-ng/src/hb-ms-feature-ranges.hh
deleted file mode 100644
index f7649ab76e4..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ms-feature-ranges.hh
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright © 2011,2012,2013 Google, Inc.
- * Copyright © 2021 Khaled Hosny
- *
- * 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_MS_FEATURE_RANGES_HH
-#define HB_MS_FEATURE_RANGES_HH
-
-#include "hb.hh"
-
-/* Variations of this code exist in hb-coretext.cc as well
- * as hb-aat-map.cc... */
-
-typedef struct hb_ms_feature_t {
- uint32_t tag_le;
- uint32_t value;
-} hb_ms_feature_t;
-
-typedef struct hb_ms_features_t {
- hb_ms_feature_t *features;
- uint32_t num_features;
-} hb_ms_features_t;
-
-struct hb_ms_active_feature_t {
- hb_ms_feature_t fea;
- unsigned int order;
-
- HB_INTERNAL static int cmp (const void *pa, const void *pb) {
- const auto *a = (const hb_ms_active_feature_t *) pa;
- const auto *b = (const hb_ms_active_feature_t *) pb;
- return a->fea.tag_le < b->fea.tag_le ? -1 : a->fea.tag_le > b->fea.tag_le ? 1 :
- a->order < b->order ? -1 : a->order > b->order ? 1 :
- a->fea.value < b->fea.value ? -1 : a->fea.value > b->fea.value ? 1 :
- 0;
- }
- bool operator== (const hb_ms_active_feature_t& f) const
- { return cmp (this, &f) == 0; }
-};
-
-struct hb_ms_feature_event_t {
- unsigned int index;
- bool start;
- hb_ms_active_feature_t feature;
-
- HB_INTERNAL static int cmp (const void *pa, const void *pb)
- {
- const auto *a = (const hb_ms_feature_event_t *) pa;
- const auto *b = (const hb_ms_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 :
- hb_ms_active_feature_t::cmp (&a->feature, &b->feature);
- }
-};
-
-struct hb_ms_range_record_t {
- hb_ms_features_t features;
- unsigned int index_first; /* == start */
- unsigned int index_last; /* == end - 1 */
-};
-
-static inline bool
-hb_ms_setup_features (const hb_feature_t *features,
- unsigned int num_features,
- hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */
- hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
-{
- feature_records.shrink(0);
- range_records.shrink(0);
-
- /* Sort features by start/end events. */
- hb_vector_t<hb_ms_feature_event_t> feature_events;
- for (unsigned int i = 0; i < num_features; i++)
- {
- hb_ms_active_feature_t feature;
- feature.fea.tag_le = hb_uint32_swap (features[i].tag);
- feature.fea.value = features[i].value;
- feature.order = i;
-
- hb_ms_feature_event_t *event;
-
- event = feature_events.push ();
- event->index = features[i].start;
- event->start = true;
- event->feature = feature;
-
- event = feature_events.push ();
- event->index = features[i].end;
- event->start = false;
- event->feature = feature;
- }
- feature_events.qsort ();
- /* Add a strategic final event. */
- {
- hb_ms_active_feature_t feature;
- feature.fea.tag_le = 0;
- feature.fea.value = 0;
- feature.order = num_features + 1;
-
- auto *event = feature_events.push ();
- event->index = 0; /* This value does magic. */
- event->start = false;
- event->feature = feature;
- }
-
- /* Scan events and save features for each range. */
- hb_vector_t<hb_ms_active_feature_t> active_features;
- unsigned int last_index = 0;
- for (unsigned int i = 0; i < feature_events.length; i++)
- {
- auto *event = &feature_events[i];
-
- if (event->index != last_index)
- {
- /* Save a snapshot of active features and the range. */
- auto *range = range_records.push ();
- auto offset = feature_records.length;
-
- active_features.qsort ();
- for (unsigned int j = 0; j < active_features.length; j++)
- {
- if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
- {
- feature_records.push (active_features[j].fea);
- }
- else
- {
- /* Overrides value for existing feature. */
- feature_records[feature_records.length - 1].value = active_features[j].fea.value;
- }
- }
-
- /* Will convert to pointer after all is ready, since feature_records.array
- * may move as we grow it. */
- range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
- range->features.num_features = feature_records.length - offset;
- range->index_first = last_index;
- range->index_last = event->index - 1;
-
- last_index = event->index;
- }
-
- if (event->start)
- {
- active_features.push (event->feature);
- }
- else
- {
- auto *feature = active_features.lsearch (event->feature);
- if (feature)
- active_features.remove_ordered (feature - active_features.arrayZ);
- }
- }
-
- if (!range_records.length) /* No active feature found. */
- num_features = 0;
-
- /* Fixup the pointers. */
- for (unsigned int i = 0; i < range_records.length; i++)
- {
- auto *range = &range_records[i];
- range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
- }
-
- return !!num_features;
-}
-
-static inline void
-hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records,
- hb_vector_t<hb_ms_range_record_t> &range_records,
- unsigned int chars_offset,
- unsigned int chars_len,
- uint16_t *log_clusters,
- hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */
- hb_vector_t<uint32_t> &range_counts /* OUT */)
-{
- range_features.shrink (0);
- range_counts.shrink (0);
-
- auto *last_range = &range_records[0];
- for (unsigned int i = chars_offset; i < chars_len; i++)
- {
- auto *range = last_range;
- while (log_clusters[i] < range->index_first)
- range--;
- while (log_clusters[i] > range->index_last)
- range++;
- if (!range_features.length ||
- &range->features != range_features[range_features.length - 1])
- {
- auto **features = range_features.push ();
- auto *c = range_counts.push ();
- if (unlikely (!features || !c))
- {
- range_features.shrink (0);
- range_counts.shrink (0);
- break;
- }
- *features = &range->features;
- *c = 1;
- }
- else
- {
- range_counts[range_counts.length - 1]++;
- }
-
- last_range = range;
- }
-}
-
-#endif /* HB_MS_FEATURE_RANGES_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-multimap.hh b/src/3rdparty/harfbuzz-ng/src/hb-multimap.hh
deleted file mode 100644
index b4a8cc62a3e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-multimap.hh
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_MULTIMAP_HH
-#define HB_MULTIMAP_HH
-
-#include "hb.hh"
-#include "hb-map.hh"
-#include "hb-vector.hh"
-
-
-/*
- * hb_multimap_t
- */
-
-struct hb_multimap_t
-{
- void add (hb_codepoint_t k, hb_codepoint_t v)
- {
- hb_codepoint_t *i;
- if (multiples_indices.has (k, &i))
- {
- multiples_values[*i].push (v);
- return;
- }
-
- hb_codepoint_t *old_v;
- if (singulars.has (k, &old_v))
- {
- hb_codepoint_t old = *old_v;
- singulars.del (k);
-
- multiples_indices.set (k, multiples_values.length);
- auto *vec = multiples_values.push ();
-
- vec->push (old);
- vec->push (v);
-
- return;
- }
-
- singulars.set (k, v);
- }
-
- hb_array_t<const hb_codepoint_t> get (hb_codepoint_t k) const
- {
- const hb_codepoint_t *v;
- if (singulars.has (k, &v))
- return hb_array (v, 1);
-
- hb_codepoint_t *i;
- if (multiples_indices.has (k, &i))
- return multiples_values[*i].as_array ();
-
- return hb_array_t<const hb_codepoint_t> ();
- }
-
- bool in_error () const
- {
- return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error ();
- }
-
- protected:
- hb_map_t singulars;
- hb_map_t multiples_indices;
- hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values;
-};
-
-
-
-#endif /* HB_MULTIMAP_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
index e329d9864f1..49ed10e08a6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
@@ -29,17 +29,18 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_MUTEX_HH
-#define HB_MUTEX_HH
+#ifndef HB_MUTEX_PRIVATE_HH
+#define HB_MUTEX_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
/* mutex */
/* We need external help for these */
-#if defined(hb_mutex_impl_init) \
+#if defined(HB_MUTEX_IMPL_INIT) \
+ && defined(hb_mutex_impl_init) \
&& defined(hb_mutex_impl_lock) \
&& defined(hb_mutex_impl_unlock) \
&& defined(hb_mutex_impl_finish)
@@ -47,42 +48,72 @@
/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
-#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#include <windows.h>
+typedef CRITICAL_SECTION hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT {0}
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0)
+#else
+#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
+#endif
+#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
+#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
+#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
+
+
+#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
#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, 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)
-#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32)
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
-typedef CRITICAL_SECTION hb_mutex_impl_t;
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
-#define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0)
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
#else
-#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
#endif
-#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
-#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
-#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
+
+/* This actually is not a totally awful implementation. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
+#define hb_mutex_impl_init(M) *(M) = 0
+#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
+#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
#elif !defined(HB_NO_MT)
-#include <mutex>
-typedef std::mutex hb_mutex_impl_t;
-#define hb_mutex_impl_init(M) HB_STMT_START { new (M) hb_mutex_impl_t; } HB_STMT_END
-#define hb_mutex_impl_lock(M) (M)->lock ()
-#define hb_mutex_impl_unlock(M) (M)->unlock ()
-#define hb_mutex_impl_finish(M) HB_STMT_START { (M)->~hb_mutex_impl_t(); } HB_STMT_END
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
+#define hb_mutex_impl_init(M) *(M) = 0
+#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
+#define hb_mutex_impl_unlock(M) (*(M))--;
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
-#else /* defined(HB_NO_MT) */
+#else /* HB_NO_MT */
typedef int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT 0
#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END
#define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END
#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END
@@ -92,31 +123,19 @@ typedef int hb_mutex_impl_t;
#endif
+#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
+
struct hb_mutex_t
{
- /* Create space for, but do not initialize m. */
- alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)];
-
- hb_mutex_t () { init (); }
- ~hb_mutex_t () { fini (); }
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- void init () { hb_mutex_impl_init ((hb_mutex_impl_t *) m); }
- void lock () { hb_mutex_impl_lock ((hb_mutex_impl_t *) m); }
- void unlock () { hb_mutex_impl_unlock ((hb_mutex_impl_t *) m); }
- void fini () { hb_mutex_impl_finish ((hb_mutex_impl_t *) m); }
-#pragma GCC diagnostic pop
-};
+ /* TODO Add tracing. */
-struct hb_lock_t
-{
- hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); }
- hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); }
- ~hb_lock_t () { if (mutex) mutex->unlock (); }
- private:
- hb_mutex_t *mutex;
+ hb_mutex_impl_t m;
+
+ inline void init (void) { hb_mutex_impl_init (&m); }
+ inline void lock (void) { hb_mutex_impl_lock (&m); }
+ inline void unlock (void) { hb_mutex_impl_unlock (&m); }
+ inline void finish (void) { hb_mutex_impl_finish (&m); }
};
-#endif /* HB_MUTEX_HH */
+#endif /* HB_MUTEX_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-null.hh b/src/3rdparty/harfbuzz-ng/src/hb-null.hh
deleted file mode 100644
index 0d7f4da79e7..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-null.hh
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright © 2018 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_NULL_HH
-#define HB_NULL_HH
-
-#include "hb.hh"
-#include "hb-meta.hh"
-
-
-/*
- * Static pools
- */
-
-/* Global nul-content Null pool. Enlarge as necessary. */
-
-#define HB_NULL_POOL_SIZE 448
-
-template <typename T, typename>
-struct _hb_has_min_size : hb_false_type {};
-template <typename T>
-struct _hb_has_min_size<T, hb_void_t<decltype (T::min_size)>>
- : hb_true_type {};
-template <typename T>
-using hb_has_min_size = _hb_has_min_size<T, void>;
-#define hb_has_min_size(T) hb_has_min_size<T>::value
-
-template <typename T, typename>
-struct _hb_has_null_size : hb_false_type {};
-template <typename T>
-struct _hb_has_null_size<T, hb_void_t<decltype (T::null_size)>>
- : hb_true_type {};
-template <typename T>
-using hb_has_null_size = _hb_has_null_size<T, void>;
-#define hb_has_null_size(T) hb_has_null_size<T>::value
-
-/* Use SFINAE to sniff whether T has min_size; in which case return the larger
- * of sizeof(T) and T::null_size, otherwise return sizeof(T).
- *
- * The main purpose of this is to let structs communicate that they are not nullable,
- * by defining min_size but *not* null_size. */
-
-/* The hard way...
- * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
- */
-
-template <typename T, typename>
-struct _hb_null_size : hb_integral_constant<unsigned, sizeof (T)> {};
-template <typename T>
-struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>>
- : hb_integral_constant<unsigned,
- (sizeof (T) > T::null_size ? sizeof (T) : T::null_size)> {};
-template <typename T>
-using hb_null_size = _hb_null_size<T, void>;
-#define hb_null_size(T) hb_null_size<T>::value
-
-/* These doesn't belong here, but since is copy/paste from above, put it here. */
-
-/* hb_static_size (T)
- * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */
-
-template <typename T, typename>
-struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {};
-template <typename T>
-struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {};
-template <typename T>
-using hb_static_size = _hb_static_size<T, void>;
-#define hb_static_size(T) hb_static_size<T>::value
-
-template <typename T, typename>
-struct _hb_min_size : hb_integral_constant<unsigned, sizeof (T)> {};
-template <typename T>
-struct _hb_min_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::min_size> {};
-template <typename T>
-using hb_min_size = _hb_min_size<T, void>;
-#define hb_min_size(T) hb_min_size<T>::value
-
-
-/*
- * Null()
- */
-
-extern HB_INTERNAL
-uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
-
-/* Generic nul-content Null objects. */
-template <typename Type>
-struct Null {
- static Type const & get_null ()
- {
- static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
- return *reinterpret_cast<Type const *> (_hb_NullPool);
- }
-};
-template <typename QType>
-struct NullHelper
-{
- typedef hb_remove_const<hb_remove_reference<QType>> Type;
- static const Type & get_null () { return Null<Type>::get_null (); }
-};
-#define Null(Type) NullHelper<Type>::get_null ()
-
-/* Specializations for arbitrary-content Null objects expressed in bytes. */
-#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \
- } /* Close namespace. */ \
- extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)]; \
- template <> \
- struct Null<Namespace::Type> { \
- static Namespace::Type const & get_null () { \
- return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \
- } \
- }; \
- namespace Namespace { \
- static_assert (true, "") /* Require semicolon after. */
-#define DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1(Namespace, Type, Size) \
- } /* Close namespace. */ \
- extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Size]; \
- template <typename Spec> \
- struct Null<Namespace::Type<Spec>> { \
- static Namespace::Type<Spec> const & get_null () { \
- return *reinterpret_cast<const Namespace::Type<Spec> *> (_hb_Null_##Namespace##_##Type); \
- } \
- }; \
- namespace Namespace { \
- static_assert (true, "") /* Require semicolon after. */
-#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
- const unsigned char _hb_Null_##Namespace##_##Type[sizeof (_hb_Null_##Namespace##_##Type)]
-
-/* Specializations for arbitrary-content Null objects expressed as struct initializer. */
-#define DECLARE_NULL_INSTANCE(Type) \
- extern HB_INTERNAL const Type _hb_Null_##Type; \
- template <> \
- struct Null<Type> { \
- static Type const & get_null () { \
- return _hb_Null_##Type; \
- } \
- }; \
- static_assert (true, "") /* Require semicolon after. */
-#define DEFINE_NULL_INSTANCE(Type) \
- const Type _hb_Null_##Type
-
-/* Global writable pool. Enlarge as necessary. */
-
-/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool
- * for correct operation. It only exist to catch and divert program logic bugs instead of
- * causing bad memory access. So, races there are not actually introducing incorrectness
- * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
-extern HB_INTERNAL
-/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
-
-/* CRAP pool: Common Region for Access Protection. */
-template <typename Type>
-static inline Type& Crap () {
- static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
- Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
- memcpy (obj, &Null (Type), sizeof (*obj));
- return *obj;
-}
-template <typename QType>
-struct CrapHelper
-{
- typedef hb_remove_const<hb_remove_reference<QType>> Type;
- static Type & get_crap () { return Crap<Type> (); }
-};
-#define Crap(Type) CrapHelper<Type>::get_crap ()
-
-template <typename Type>
-struct CrapOrNullHelper {
- static Type & get () { return Crap (Type); }
-};
-template <typename Type>
-struct CrapOrNullHelper<const Type> {
- static const Type & get () { return Null (Type); }
-};
-#define CrapOrNull(Type) CrapOrNullHelper<Type>::get ()
-
-
-/*
- * hb_nonnull_ptr_t
- */
-
-template <typename P>
-struct hb_nonnull_ptr_t
-{
- typedef hb_remove_pointer<P> T;
-
- hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {}
- T * operator = (T *v_) { return v = v_; }
- T * operator -> () const { return get (); }
- T & operator * () const { return *get (); }
- T ** operator & () const { return &v; }
- /* Only auto-cast to const types. */
- template <typename C> operator const C * () const { return get (); }
- operator const char * () const { return (const char *) get (); }
- T * get () const { return v ? v : const_cast<T *> (&Null (T)); }
- T * get_raw () const { return v; }
-
- private:
- T *v;
-};
-
-
-#endif /* HB_NULL_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh
deleted file mode 100644
index ec68c3a7281..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh
+++ /dev/null
@@ -1,237 +0,0 @@
-
-#line 1 "hb-number-parser.rl"
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- *
- */
-
-#ifndef HB_NUMBER_PARSER_HH
-#define HB_NUMBER_PARSER_HH
-
-#include "hb.hh"
-
-
-#line 32 "hb-number-parser.hh"
-static const unsigned char _double_parser_trans_keys[] = {
- 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
- 46u, 101u, 0
-};
-
-static const char _double_parser_key_spans[] = {
- 0, 15, 12, 10, 15, 10, 54, 10,
- 56
-};
-
-static const unsigned char _double_parser_index_offsets[] = {
- 0, 0, 16, 29, 40, 56, 67, 122,
- 133
-};
-
-static const char _double_parser_indicies[] = {
- 0, 1, 2, 3, 1, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 1, 3, 1, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 1, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 1, 6, 1, 7, 1, 1, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8,
- 1, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 1, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 9, 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, 1, 1, 1, 1, 1,
- 1, 9, 1, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 1, 3, 1,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 9, 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, 1,
- 1, 1, 1, 1, 1, 9, 1, 0
-};
-
-static const char _double_parser_trans_targs[] = {
- 2, 0, 2, 3, 8, 6, 5, 5,
- 7, 4
-};
-
-static const char _double_parser_trans_actions[] = {
- 0, 0, 1, 0, 2, 3, 0, 4,
- 5, 0
-};
-
-static const int double_parser_start = 1;
-static const int double_parser_first_final = 6;
-static const int double_parser_error = 0;
-
-static const int double_parser_en_main = 1;
-
-
-#line 68 "hb-number-parser.rl"
-
-
-/* Works only for n < 512 */
-static inline double
-_pow10 (unsigned exponent)
-{
- static const double _powers_of_10[] =
- {
- 1.0e+256,
- 1.0e+128,
- 1.0e+64,
- 1.0e+32,
- 1.0e+16,
- 1.0e+8,
- 10000.,
- 100.,
- 10.
- };
- unsigned mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
- double result = 1;
- for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
- if (exponent & mask) result *= *power;
- return result;
-}
-
-/* a variant of strtod that also gets end of buffer in its second argument */
-static inline double
-strtod_rl (const char *p, const char **end_ptr /* IN/OUT */)
-{
- double value = 0;
- double frac = 0;
- double frac_count = 0;
- unsigned exp = 0;
- bool neg = false, exp_neg = false, exp_overflow = false;
- const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 2^52-1 */
- const unsigned MAX_EXP = 0x7FFu; /* 2^11-1 */
-
- const char *pe = *end_ptr;
- while (p < pe && ISSPACE (*p))
- p++;
-
- int cs;
-
-#line 132 "hb-number-parser.hh"
- {
- cs = double_parser_start;
- }
-
-#line 135 "hb-number-parser.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
-_resume:
- _keys = _double_parser_trans_keys + (cs<<1);
- _inds = _double_parser_indicies + _double_parser_index_offsets[cs];
-
- _slen = _double_parser_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
- (*p) <= _keys[1] ?
- (*p) - _keys[0] : _slen ];
-
- cs = _double_parser_trans_targs[_trans];
-
- if ( _double_parser_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _double_parser_trans_actions[_trans] ) {
- case 1:
-#line 37 "hb-number-parser.rl"
- { neg = true; }
- break;
- case 4:
-#line 38 "hb-number-parser.rl"
- { exp_neg = true; }
- break;
- case 2:
-#line 40 "hb-number-parser.rl"
- {
- value = value * 10. + ((*p) - '0');
-}
- break;
- case 3:
-#line 43 "hb-number-parser.rl"
- {
- if (likely (frac <= MAX_FRACT / 10))
- {
- frac = frac * 10. + ((*p) - '0');
- ++frac_count;
- }
-}
- break;
- case 5:
-#line 50 "hb-number-parser.rl"
- {
- if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
- exp = exp * 10 + ((*p) - '0');
- else
- exp_overflow = true;
-}
- break;
-#line 187 "hb-number-parser.hh"
- }
-
-_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- _out: {}
- }
-
-#line 113 "hb-number-parser.rl"
-
-
- *end_ptr = p;
-
- if (frac_count) value += frac / _pow10 (frac_count);
- if (neg) value *= -1.;
-
- if (unlikely (exp_overflow))
- {
- if (value == 0) return value;
- if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
- else return neg ? -DBL_MAX : DBL_MAX;
- }
-
- if (exp)
- {
- if (exp_neg) value /= _pow10 (exp);
- else value *= _pow10 (exp);
- }
-
- return value;
-}
-
-#endif /* HB_NUMBER_PARSER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number.cc b/src/3rdparty/harfbuzz-ng/src/hb-number.cc
deleted file mode 100644
index c52b284e1d2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-number.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- *
- */
-
-#include "hb.hh"
-#include "hb-number.hh"
-#include "hb-number-parser.hh"
-
-template<typename T, typename Func>
-static bool
-_parse_number (const char **pp, const char *end, T *pv,
- bool whole_buffer, Func f)
-{
- char buf[32];
- unsigned len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned) (end - *pp));
- strncpy (buf, *pp, len);
- buf[len] = '\0';
-
- char *p = buf;
- char *pend = p;
-
- errno = 0;
- *pv = f (p, &pend);
- if (unlikely (errno || p == pend ||
- /* Check if consumed whole buffer if is requested */
- (whole_buffer && pend - p != end - *pp)))
- return false;
-
- *pp += pend - p;
- return true;
-}
-
-bool
-hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
-{
- return _parse_number<int> (pp, end, pv, whole_buffer,
- [] (const char *p, char **end)
- { return strtol (p, end, 10); });
-}
-
-bool
-hb_parse_uint (const char **pp, const char *end, unsigned *pv,
- bool whole_buffer, int base)
-{
- return _parse_number<unsigned> (pp, end, pv, whole_buffer,
- [base] (const char *p, char **end)
- { return strtoul (p, end, base); });
-}
-
-bool
-hb_parse_double (const char **pp, const char *end, double *pv, bool whole_buffer)
-{
- const char *pend = end;
- *pv = strtod_rl (*pp, &pend);
- if (unlikely (*pp == pend)) return false;
- *pp = pend;
- return !whole_buffer || end == pend;
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number.hh b/src/3rdparty/harfbuzz-ng/src/hb-number.hh
deleted file mode 100644
index 14d1260aa3d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-number.hh
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- *
- */
-
-#ifndef HB_NUMBER_HH
-#define HB_NUMBER_HH
-
-HB_INTERNAL bool
-hb_parse_int (const char **pp, const char *end, int *pv,
- bool whole_buffer = false);
-
-HB_INTERNAL bool
-hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
- bool whole_buffer = false, int base = 10);
-
-HB_INTERNAL bool
-hb_parse_double (const char **pp, const char *end, double *pv,
- bool whole_buffer = false);
-
-#endif /* HB_NUMBER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
new file mode 100644
index 00000000000..baa1f8f05cc
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2007 Chris Wilson
+ * Copyright © 2009,2010 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Contributor(s):
+ * Chris Wilson <[email protected]>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OBJECT_PRIVATE_HH
+#define HB_OBJECT_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-debug.hh"
+
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
+
+
+/* reference_count */
+
+#define HB_REFERENCE_COUNT_INERT_VALUE -1
+#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
+#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
+
+struct hb_reference_count_t
+{
+ hb_atomic_int_t ref_count;
+
+ inline void init (int v) { ref_count.set_unsafe (v); }
+ inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
+ inline int inc (void) { return ref_count.inc (); }
+ inline int dec (void) { return ref_count.dec (); }
+ inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
+
+ inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
+ inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
+};
+
+
+/* user_data */
+
+#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
+struct hb_user_data_array_t
+{
+ struct hb_user_data_item_t {
+ hb_user_data_key_t *key;
+ void *data;
+ hb_destroy_func_t destroy;
+
+ inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
+ inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
+
+ void finish (void) { if (destroy) destroy (data); }
+ };
+
+ hb_mutex_t lock;
+ hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
+
+ inline void init (void) { lock.init (); items.init (); }
+
+ HB_INTERNAL bool set (hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+ HB_INTERNAL void *get (hb_user_data_key_t *key);
+
+ inline void finish (void) { items.finish (lock); lock.finish (); }
+};
+
+
+/* object_header */
+
+struct hb_object_header_t
+{
+ hb_reference_count_t ref_count;
+ hb_user_data_array_t user_data;
+
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
+
+ private:
+ ASSERT_POD ();
+};
+
+
+/* object */
+
+template <typename Type>
+static inline void hb_object_trace (const Type *obj, const char *function)
+{
+ DEBUG_MSG (OBJECT, (void *) obj,
+ "%s refcount=%d",
+ function,
+ obj ? obj->header.ref_count.get_unsafe () : 0);
+}
+
+template <typename Type>
+static inline Type *hb_object_create (void)
+{
+ Type *obj = (Type *) calloc (1, sizeof (Type));
+
+ if (unlikely (!obj))
+ return obj;
+
+ hb_object_init (obj);
+ hb_object_trace (obj, HB_FUNC);
+ return obj;
+}
+template <typename Type>
+static inline void hb_object_init (Type *obj)
+{
+ obj->header.ref_count.init (1);
+ obj->header.user_data.init ();
+}
+template <typename Type>
+static inline bool hb_object_is_inert (const Type *obj)
+{
+ return unlikely (obj->header.ref_count.is_inert ());
+}
+template <typename Type>
+static inline bool hb_object_is_valid (const Type *obj)
+{
+ return likely (obj->header.ref_count.is_valid ());
+}
+template <typename Type>
+static inline Type *hb_object_reference (Type *obj)
+{
+ hb_object_trace (obj, HB_FUNC);
+ if (unlikely (!obj || hb_object_is_inert (obj)))
+ return obj;
+ assert (hb_object_is_valid (obj));
+ obj->header.ref_count.inc ();
+ return obj;
+}
+template <typename Type>
+static inline bool hb_object_destroy (Type *obj)
+{
+ hb_object_trace (obj, HB_FUNC);
+ if (unlikely (!obj || hb_object_is_inert (obj)))
+ return false;
+ assert (hb_object_is_valid (obj));
+ if (obj->header.ref_count.dec () != 1)
+ return false;
+
+ obj->header.ref_count.finish (); /* Do this before user_data */
+ obj->header.user_data.finish ();
+ return true;
+}
+template <typename Type>
+static inline bool hb_object_set_user_data (Type *obj,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ if (unlikely (!obj || hb_object_is_inert (obj)))
+ return false;
+ assert (hb_object_is_valid (obj));
+ return obj->header.user_data.set (key, data, destroy, replace);
+}
+
+template <typename Type>
+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 nullptr;
+ assert (hb_object_is_valid (obj));
+ return obj->header.user_data.get (key);
+}
+
+
+#endif /* HB_OBJECT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object.hh b/src/3rdparty/harfbuzz-ng/src/hb-object.hh
deleted file mode 100644
index e2c2c3394cb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-object.hh
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright © 2007 Chris Wilson
- * Copyright © 2009,2010 Red Hat, Inc.
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Contributor(s):
- * Chris Wilson <[email protected]>
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OBJECT_HH
-#define HB_OBJECT_HH
-
-#include "hb.hh"
-#include "hb-atomic.hh"
-#include "hb-mutex.hh"
-#include "hb-vector.hh"
-
-
-/*
- * Lockable set
- */
-
-template <typename item_t, typename lock_t>
-struct hb_lockable_set_t
-{
- hb_vector_t<item_t> items;
-
- void init () { items.init (); }
-
- template <typename T>
- item_t *replace_or_insert (T v, lock_t &l, bool replace)
- {
- l.lock ();
- item_t *item = items.lsearch (v);
- if (item) {
- if (replace) {
- item_t old = *item;
- *item = v;
- l.unlock ();
- old.fini ();
- }
- else {
- item = nullptr;
- l.unlock ();
- }
- } else {
- item = items.push (v);
- l.unlock ();
- }
- return items.in_error () ? nullptr : item;
- }
-
- template <typename T>
- void remove (T v, lock_t &l)
- {
- l.lock ();
- item_t *item = items.lsearch (v);
- if (item)
- {
- item_t old = *item;
- *item = std::move (items.tail ());
- items.pop ();
- l.unlock ();
- old.fini ();
- } else {
- l.unlock ();
- }
- }
-
- template <typename T>
- bool find (T v, item_t *i, lock_t &l)
- {
- l.lock ();
- item_t *item = items.lsearch (v);
- if (item)
- *i = *item;
- l.unlock ();
- return !!item;
- }
-
- template <typename T>
- item_t *find_or_insert (T v, lock_t &l)
- {
- l.lock ();
- item_t *item = items.find (v);
- if (!item) {
- item = items.push (v);
- }
- l.unlock ();
- return item;
- }
-
- void fini (lock_t &l)
- {
- if (!items.length)
- {
- /* No need to lock. */
- items.fini ();
- return;
- }
- l.lock ();
- while (items.length)
- {
- item_t old = items.tail ();
- items.pop ();
- l.unlock ();
- old.fini ();
- l.lock ();
- }
- items.fini ();
- l.unlock ();
- }
-
-};
-
-
-/*
- * Reference-count.
- */
-
-struct hb_reference_count_t
-{
- mutable hb_atomic_int_t ref_count;
-
- void init (int v = 1) { ref_count = v; }
- int get_relaxed () const { return ref_count; }
- int inc () const { return ref_count.inc (); }
- int dec () const { return ref_count.dec (); }
- void fini () { ref_count = -0x0000DEAD; }
-
- bool is_inert () const { return !ref_count; }
- bool is_valid () const { return ref_count > 0; }
-};
-
-
-/* user_data */
-
-struct hb_user_data_array_t
-{
- struct hb_user_data_item_t {
- hb_user_data_key_t *key;
- void *data;
- hb_destroy_func_t destroy;
-
- bool operator == (const hb_user_data_key_t *other_key) const { return key == other_key; }
- bool operator == (const hb_user_data_item_t &other) const { return key == other.key; }
-
- void fini () { if (destroy) destroy (data); }
- };
-
- hb_mutex_t lock;
- hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
-
- void init () { lock.init (); items.init (); }
-
- void fini () { items.fini (lock); lock.fini (); }
-
- bool set (hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
- {
- if (!key)
- return false;
-
- if (replace) {
- if (!data && !destroy) {
- items.remove (key, lock);
- return true;
- }
- }
- hb_user_data_item_t item = {key, data, destroy};
- bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
-
- return ret;
- }
-
- void *get (hb_user_data_key_t *key)
- {
- hb_user_data_item_t item = {nullptr, nullptr, nullptr};
-
- return items.find (key, &item, lock) ? item.data : nullptr;
- }
-};
-
-
-/*
- * Object header
- */
-
-struct hb_object_header_t
-{
- hb_reference_count_t ref_count;
- mutable hb_atomic_int_t writable = 0;
- hb_atomic_ptr_t<hb_user_data_array_t> user_data;
-
- bool is_inert () const { return !ref_count.get_relaxed (); }
-};
-#define HB_OBJECT_HEADER_STATIC {}
-
-
-/*
- * Object
- */
-
-template <typename Type>
-static inline void hb_object_trace (const Type *obj, const char *function)
-{
- DEBUG_MSG (OBJECT, (void *) obj,
- "%s refcount=%d",
- function,
- obj ? obj->header.ref_count.get_relaxed () : 0);
-}
-
-template <typename Type, typename ...Ts>
-static inline Type *hb_object_create (Ts... ds)
-{
- Type *obj = (Type *) hb_calloc (1, sizeof (Type));
-
- if (unlikely (!obj))
- return obj;
-
- new (obj) Type (std::forward<Ts> (ds)...);
-
- hb_object_init (obj);
- hb_object_trace (obj, HB_FUNC);
-
- return obj;
-}
-template <typename Type>
-static inline void hb_object_init (Type *obj)
-{
- obj->header.ref_count.init ();
- obj->header.writable = true;
- obj->header.user_data.init ();
-}
-template <typename Type>
-static inline bool hb_object_is_valid (const Type *obj)
-{
- return likely (obj->header.ref_count.is_valid ());
-}
-template <typename Type>
-static inline bool hb_object_is_immutable (const Type *obj)
-{
- return !obj->header.writable;
-}
-template <typename Type>
-static inline void hb_object_make_immutable (const Type *obj)
-{
- obj->header.writable = false;
-}
-template <typename Type>
-static inline Type *hb_object_reference (Type *obj)
-{
- hb_object_trace (obj, HB_FUNC);
- if (unlikely (!obj || obj->header.is_inert ()))
- return obj;
- assert (hb_object_is_valid (obj));
- obj->header.ref_count.inc ();
- return obj;
-}
-template <typename Type>
-static inline bool hb_object_destroy (Type *obj)
-{
- hb_object_trace (obj, HB_FUNC);
- if (unlikely (!obj || obj->header.is_inert ()))
- return false;
- assert (hb_object_is_valid (obj));
- if (obj->header.ref_count.dec () != 1)
- return false;
-
- hb_object_fini (obj);
-
- if (!std::is_trivially_destructible<Type>::value)
- obj->~Type ();
-
- return true;
-}
-template <typename Type>
-static inline void hb_object_fini (Type *obj)
-{
- obj->header.ref_count.fini (); /* Do this before user_data */
- hb_user_data_array_t *user_data = obj->header.user_data.get_acquire ();
- if (user_data)
- {
- user_data->fini ();
- hb_free (user_data);
- obj->header.user_data.set_relaxed (nullptr);
- }
-}
-template <typename Type>
-static inline bool hb_object_set_user_data (Type *obj,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- if (unlikely (!obj || obj->header.is_inert ()))
- return false;
- assert (hb_object_is_valid (obj));
-
-retry:
- hb_user_data_array_t *user_data = obj->header.user_data.get_acquire ();
- if (unlikely (!user_data))
- {
- user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1);
- if (unlikely (!user_data))
- return false;
- user_data->init ();
- if (unlikely (!obj->header.user_data.cmpexch (nullptr, user_data)))
- {
- user_data->fini ();
- hb_free (user_data);
- goto retry;
- }
- }
-
- return user_data->set (key, data, destroy, replace);
-}
-
-template <typename Type>
-static inline void *hb_object_get_user_data (Type *obj,
- hb_user_data_key_t *key)
-{
- if (unlikely (!obj || obj->header.is_inert ()))
- return nullptr;
- assert (hb_object_is_valid (obj));
- hb_user_data_array_t *user_data = obj->header.user_data.get_acquire ();
- if (!user_data)
- return nullptr;
- return user_data->get (key);
-}
-
-
-#endif /* HB_OBJECT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
new file mode 100644
index 00000000000..644e0b40f6f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
@@ -0,0 +1,280 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_FILE_PRIVATE_HH
+#define HB_OPEN_FILE_PRIVATE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ *
+ * The OpenType Font File
+ *
+ */
+
+
+/*
+ * Organization of an OpenType Font
+ */
+
+struct OpenTypeFontFile;
+struct OffsetTable;
+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);
+ return_trace (c->check_struct (this));
+ }
+
+ Tag tag; /* 4-byte identifier. */
+ CheckSum checkSum; /* CheckSum for this table. */
+ UINT32 offset; /* Offset from beginning of TrueType font
+ * file. */
+ UINT32 length; /* Length of this table. */
+ public:
+ DEFINE_SIZE_STATIC (16);
+} OpenTypeTable;
+
+typedef struct OffsetTable
+{
+ friend struct OpenTypeFontFile;
+
+ inline unsigned int get_table_count (void) const
+ { return tables.len; }
+ inline const TableRecord& get_table (unsigned int i) const
+ {
+ 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);
+ /* 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
+ {
+ unsigned int table_index;
+ find_table_index (tag, &table_index);
+ return get_table (table_index);
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && tables.sanitize (c));
+ }
+
+ protected:
+ Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
+ BinSearchArrayOf<TableRecord>
+ tables;
+ public:
+ DEFINE_SIZE_ARRAY (12, tables);
+} OpenTypeFontFace;
+
+
+/*
+ * TrueType Collections
+ */
+
+struct TTCHeaderVersion1
+{
+ friend struct TTCHeader;
+
+ inline unsigned int get_face_count (void) const { return table.len; }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (table.sanitize (c, this));
+ }
+
+ protected:
+ Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
+ FixedVersion<>version; /* Version of the TTC Header (1.0),
+ * 0x00010000u */
+ ArrayOf<LOffsetTo<OffsetTable>, UINT32>
+ table; /* Array of offsets to the OffsetTable for each font
+ * from the beginning of the file */
+ public:
+ DEFINE_SIZE_ARRAY (12, table);
+};
+
+struct TTCHeader
+{
+ friend struct OpenTypeFontFile;
+
+ private:
+
+ inline unsigned int get_face_count (void) const
+ {
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return u.version1.get_face_count ();
+ default:return 0;
+ }
+ }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const
+ {
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return u.version1.get_face (i);
+ default:return Null(OpenTypeFontFace);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
+ switch (u.header.version.major) {
+ case 2: /* version 2 is compatible with version 1 */
+ case 1: return_trace (u.version1.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ struct {
+ Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
+ FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0),
+ * 0x00010000u or 0x00020000u */
+ } header;
+ TTCHeaderVersion1 version1;
+ } u;
+};
+
+
+/*
+ * OpenType Font File
+ */
+
+struct OpenTypeFontFile
+{
+ static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
+
+ static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
+ static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
+ static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */
+ static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
+ static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
+
+ inline hb_tag_t get_tag (void) const { return u.tag; }
+
+ inline unsigned int get_face_count (void) const
+ {
+ switch (u.tag) {
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return 1;
+ case TTCTag: return u.ttcHeader.get_face_count ();
+ default: return 0;
+ }
+ }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const
+ {
+ switch (u.tag) {
+ /* Note: for non-collection SFNT data we ignore index. This is because
+ * Apple dfont container is a container of SFNT's. So each SFNT is a
+ * non-TTC, but the index is more than zero. */
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return u.fontFace;
+ case TTCTag: return u.ttcHeader.get_face (i);
+ default: return Null(OpenTypeFontFace);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!u.tag.sanitize (c))) return_trace (false);
+ switch (u.tag) {
+ case CFFTag: /* All the non-collection tags */
+ case TrueTag:
+ case Typ1Tag:
+ case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
+ case TTCTag: return_trace (u.ttcHeader.sanitize (c));
+ default: return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ Tag tag; /* 4-byte identifier. */
+ OpenTypeFontFace fontFace;
+ TTCHeader ttcHeader;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (4, tag);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OPEN_FILE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh
deleted file mode 100644
index 13570a46e0c..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-file.hh
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OPEN_FILE_HH
-#define HB_OPEN_FILE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-head-table.hh"
-
-
-namespace OT {
-
-/*
- *
- * The OpenType Font File
- *
- */
-
-
-/*
- * Organization of an OpenType Font
- */
-
-struct OpenTypeFontFile;
-struct OpenTypeOffsetTable;
-struct TTCHeader;
-
-
-typedef struct TableRecord
-{
- int cmp (Tag t) const { return -t.cmp (tag); }
-
- HB_INTERNAL static int cmp (const void *pa, const void *pb)
- {
- const TableRecord *a = (const TableRecord *) pa;
- const TableRecord *b = (const TableRecord *) pb;
- return b->cmp (a->tag);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- Tag tag; /* 4-byte identifier. */
- CheckSum checkSum; /* CheckSum for this table. */
- Offset32 offset; /* Offset from beginning of TrueType font
- * file. */
- HBUINT32 length; /* Length of this table. */
- public:
- DEFINE_SIZE_STATIC (16);
-} OpenTypeTable;
-
-typedef struct OpenTypeOffsetTable
-{
- friend struct OpenTypeFontFile;
-
- unsigned int get_table_count () const { return tables.len; }
- const TableRecord& get_table (unsigned int i) const
- { return tables[i]; }
- 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)
- {
- + tables.as_array ().sub_array (start_offset, table_count)
- | hb_map (&TableRecord::tag)
- | hb_sink (hb_array (table_tags, *table_count))
- ;
- }
- return tables.len;
- }
- bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
- {
- Tag t;
- t = tag;
- /* Use lfind for small fonts; there are fonts that have unsorted table entries;
- * those tend to work in other tools, so tolerate them.
- * https://github.com/harfbuzz/harfbuzz/issues/3065 */
- if (tables.len < 16)
- return tables.lfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
- else
- return tables.bfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
- }
- const TableRecord& get_table_by_tag (hb_tag_t tag) const
- {
- unsigned int table_index;
- find_table_index (tag, &table_index);
- return get_table (table_index);
- }
-
- public:
-
- template <typename Iterator,
- hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))>
- bool serialize (hb_serialize_context_t *c,
- hb_tag_t sfnt_tag,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- /* Alloc 12 for the OTHeader. */
- if (unlikely (!c->extend_min (this))) return_trace (false);
- /* Write sfntVersion (bytes 0..3). */
- sfnt_version = sfnt_tag;
- /* Take space for numTables, searchRange, entrySelector, RangeShift
- * and the TableRecords themselves. */
- unsigned num_items = it.len ();
- if (unlikely (!tables.serialize (c, num_items))) return_trace (false);
-
- const char *dir_end = (const char *) c->head;
- HBUINT32 *checksum_adjustment = nullptr;
-
- /* Write OffsetTables, alloc for and write actual table blobs. */
- unsigned i = 0;
- for (hb_pair_t<hb_tag_t, hb_blob_t*> entry : it)
- {
- hb_blob_t *blob = entry.second;
- unsigned len = blob->length;
-
- /* Allocate room for the table and copy it. */
- char *start = (char *) c->allocate_size<void> (len);
- if (unlikely (!start)) return false;
-
- TableRecord &rec = tables.arrayZ[i];
- rec.tag = entry.first;
- rec.length = len;
- rec.offset = 0;
- if (unlikely (!c->check_assign (rec.offset,
- (unsigned) ((char *) start - (char *) this),
- HB_SERIALIZE_ERROR_OFFSET_OVERFLOW)))
- return_trace (false);
-
- if (likely (len))
- hb_memcpy (start, blob->data, len);
-
- /* 4-byte alignment. */
- c->align (4);
- const char *end = (const char *) c->head;
-
- if (entry.first == HB_OT_TAG_head &&
- (unsigned) (end - start) >= head::static_size)
- {
- head *h = (head *) start;
- checksum_adjustment = &h->checkSumAdjustment;
- *checksum_adjustment = 0;
- }
-
- rec.checkSum.set_for_data (start, end - start);
- i++;
- }
-
- tables.qsort ();
-
- if (checksum_adjustment)
- {
- CheckSum checksum;
-
- /* The following line is a slower version of the following block. */
- //checksum.set_for_data (this, (const char *) c->head - (const char *) this);
- checksum.set_for_data (this, dir_end - (const char *) this);
- for (unsigned int i = 0; i < num_items; i++)
- {
- TableRecord &rec = tables.arrayZ[i];
- checksum = checksum + rec.checkSum;
- }
-
- *checksum_adjustment = 0xB1B0AFBAu - checksum;
- }
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && tables.sanitize (c));
- }
-
- protected:
- Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
- BinSearchArrayOf<TableRecord>
- tables;
- public:
- DEFINE_SIZE_ARRAY (12, tables);
-} OpenTypeFontFace;
-
-
-/*
- * TrueType Collections
- */
-
-struct TTCHeaderVersion1
-{
- friend struct TTCHeader;
-
- unsigned int get_face_count () const { return table.len; }
- const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (table.sanitize (c, this));
- }
-
- protected:
- Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
- FixedVersion<>version; /* Version of the TTC Header (1.0),
- * 0x00010000u */
- Array32Of<Offset32To<OpenTypeOffsetTable>>
- table; /* Array of offsets to the OffsetTable for each font
- * from the beginning of the file */
- public:
- DEFINE_SIZE_ARRAY (12, table);
-};
-
-struct TTCHeader
-{
- friend struct OpenTypeFontFile;
-
- private:
-
- unsigned int get_face_count () const
- {
- switch (u.header.version.major) {
- case 2: /* version 2 is compatible with version 1 */
- case 1: return u.version1.get_face_count ();
- default:return 0;
- }
- }
- const OpenTypeFontFace& get_face (unsigned int i) const
- {
- switch (u.header.version.major) {
- case 2: /* version 2 is compatible with version 1 */
- case 1: return u.version1.get_face (i);
- default:return Null (OpenTypeFontFace);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
- switch (u.header.version.major) {
- case 2: /* version 2 is compatible with version 1 */
- case 1: return_trace (u.version1.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- union {
- struct {
- Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
- FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0),
- * 0x00010000u or 0x00020000u */
- } header;
- TTCHeaderVersion1 version1;
- } u;
-};
-
-/*
- * Mac Resource Fork
- *
- * http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
- */
-
-struct ResourceRecord
-{
- const OpenTypeFontFace & get_face (const void *data_base) const
- { return * reinterpret_cast<const OpenTypeFontFace *> ((data_base+offset).arrayZ); }
-
- bool sanitize (hb_sanitize_context_t *c,
- const void *data_base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- offset.sanitize (c, data_base) &&
- get_face (data_base).sanitize (c));
- }
-
- protected:
- HBUINT16 id; /* Resource ID. */
- HBINT16 nameOffset; /* Offset from beginning of resource name list
- * to resource name, -1 means there is none. */
- HBUINT8 attrs; /* Resource attributes */
- NNOffset24To<Array32Of<HBUINT8>>
- offset; /* Offset from beginning of data block to
- * data for this resource */
- HBUINT32 reserved; /* Reserved for handle to resource */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-#define HB_TAG_sfnt HB_TAG ('s','f','n','t')
-
-struct ResourceTypeRecord
-{
- unsigned int get_resource_count () const
- { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; }
-
- bool is_sfnt () const { return tag == HB_TAG_sfnt; }
-
- const ResourceRecord& get_resource_record (unsigned int i,
- const void *type_base) const
- { return (type_base+resourcesZ).as_array (get_resource_count ())[i]; }
-
- bool sanitize (hb_sanitize_context_t *c,
- const void *type_base,
- const void *data_base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- resourcesZ.sanitize (c, type_base,
- get_resource_count (),
- data_base));
- }
-
- protected:
- Tag tag; /* Resource type. */
- HBUINT16 resCountM1; /* Number of resources minus 1. */
- NNOffset16To<UnsizedArrayOf<ResourceRecord>>
- resourcesZ; /* Offset from beginning of resource type list
- * to reference item list for this type. */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct ResourceMap
-{
- unsigned int get_face_count () const
- {
- unsigned int count = get_type_count ();
- for (unsigned int i = 0; i < count; i++)
- {
- const ResourceTypeRecord& type = get_type_record (i);
- if (type.is_sfnt ())
- return type.get_resource_count ();
- }
- return 0;
- }
-
- const OpenTypeFontFace& get_face (unsigned int idx,
- const void *data_base) const
- {
- unsigned int count = get_type_count ();
- for (unsigned int i = 0; i < count; i++)
- {
- const ResourceTypeRecord& type = get_type_record (i);
- /* The check for idx < count is here because ResourceRecord is NOT null-safe.
- * Because an offset of 0 there does NOT mean null. */
- if (type.is_sfnt () && idx < type.get_resource_count ())
- return type.get_resource_record (idx, &(this+typeList)).get_face (data_base);
- }
- return Null (OpenTypeFontFace);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- typeList.sanitize (c, this,
- &(this+typeList),
- data_base));
- }
-
- private:
- unsigned int get_type_count () const { return (this+typeList).lenM1 + 1; }
-
- const ResourceTypeRecord& get_type_record (unsigned int i) const
- { return (this+typeList)[i]; }
-
- protected:
- HBUINT8 reserved0[16]; /* Reserved for copy of resource header */
- HBUINT32 reserved1; /* Reserved for handle to next resource map */
- HBUINT16 resreved2; /* Reserved for file reference number */
- HBUINT16 attrs; /* Resource fork attribute */
- NNOffset16To<ArrayOfM1<ResourceTypeRecord>>
- typeList; /* Offset from beginning of map to
- * resource type list */
- Offset16 nameList; /* Offset from beginning of map to
- * resource name list */
- public:
- DEFINE_SIZE_STATIC (28);
-};
-
-struct ResourceForkHeader
-{
- unsigned int get_face_count () const
- { return (this+map).get_face_count (); }
-
- const OpenTypeFontFace& get_face (unsigned int idx,
- unsigned int *base_offset = nullptr) const
- {
- const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data));
- if (base_offset)
- *base_offset = (const char *) &face - (const char *) this;
- return face;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- data.sanitize (c, this, dataLen) &&
- map.sanitize (c, this, &(this+data)));
- }
-
- protected:
- NNOffset32To<UnsizedArrayOf<HBUINT8>>
- data; /* Offset from beginning of resource fork
- * to resource data */
- NNOffset32To<ResourceMap >
- map; /* Offset from beginning of resource fork
- * to resource map */
- HBUINT32 dataLen; /* Length of resource data */
- HBUINT32 mapLen; /* Length of resource map */
- public:
- DEFINE_SIZE_STATIC (16);
-};
-
-/*
- * OpenType Font File
- */
-
-struct OpenTypeFontFile
-{
- enum {
- CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
- TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
- TTCTag = HB_TAG ('t','t','c','f'), /* TrueType Collection */
- DFontTag = HB_TAG ( 0 , 0 , 1 , 0 ), /* DFont Mac Resource Fork */
- TrueTag = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */
- Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */
- };
-
- hb_tag_t get_tag () const { return u.tag; }
-
- unsigned int get_face_count () const
- {
- switch (u.tag) {
- case CFFTag: /* All the non-collection tags */
- case TrueTag:
- case Typ1Tag:
- case TrueTypeTag: return 1;
- case TTCTag: return u.ttcHeader.get_face_count ();
- case DFontTag: return u.rfHeader.get_face_count ();
- default: return 0;
- }
- }
- const OpenTypeFontFace& get_face (unsigned int i, unsigned int *base_offset = nullptr) const
- {
- if (base_offset)
- *base_offset = 0;
- switch (u.tag) {
- /* Note: for non-collection SFNT data we ignore index. This is because
- * Apple dfont container is a container of SFNT's. So each SFNT is a
- * non-TTC, but the index is more than zero. */
- case CFFTag: /* All the non-collection tags */
- case TrueTag:
- case Typ1Tag:
- case TrueTypeTag: return u.fontFace;
- case TTCTag: return u.ttcHeader.get_face (i);
- case DFontTag: return u.rfHeader.get_face (i, base_offset);
- default: return Null (OpenTypeFontFace);
- }
- }
-
- template <typename Iterator,
- hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))>
- bool serialize_single (hb_serialize_context_t *c,
- hb_tag_t sfnt_tag,
- Iterator items)
- {
- TRACE_SERIALIZE (this);
- assert (sfnt_tag != TTCTag);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- return_trace (u.fontFace.serialize (c, sfnt_tag, items));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!u.tag.sanitize (c))) return_trace (false);
- switch (u.tag) {
- case CFFTag: /* All the non-collection tags */
- case TrueTag:
- case Typ1Tag:
- case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
- case TTCTag: return_trace (u.ttcHeader.sanitize (c));
- case DFontTag: return_trace (u.rfHeader.sanitize (c));
- default: return_trace (true);
- }
- }
-
- protected:
- union {
- Tag tag; /* 4-byte identifier. */
- OpenTypeFontFace fontFace;
- TTCHeader ttcHeader;
- ResourceForkHeader rfHeader;
- } u;
- public:
- DEFINE_SIZE_UNION (4, tag);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OPEN_FILE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
new file mode 100644
index 00000000000..2f4e1b9e9e9
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -0,0 +1,1184 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_TYPE_PRIVATE_HH
+#define HB_OPEN_TYPE_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-debug.hh"
+#include "hb-face-private.hh"
+
+
+namespace OT {
+
+
+
+/*
+ * Casts
+ */
+
+/* Cast to struct T, reference to reference */
+template<typename Type, typename TObject>
+static inline const Type& CastR(const TObject &X)
+{ return reinterpret_cast<const Type&> (X); }
+template<typename Type, typename TObject>
+static inline Type& CastR(TObject &X)
+{ return reinterpret_cast<Type&> (X); }
+
+/* Cast to struct T, pointer to pointer */
+template<typename Type, typename TObject>
+static inline const Type* CastP(const TObject *X)
+{ return reinterpret_cast<const Type*> (X); }
+template<typename Type, typename TObject>
+static inline Type* CastP(TObject *X)
+{ return reinterpret_cast<Type*> (X); }
+
+/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
+ * location pointed to by P plus Ofs bytes. */
+template<typename Type>
+static inline const Type& StructAtOffset(const void *P, unsigned int offset)
+{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
+template<typename Type>
+static inline Type& StructAtOffset(void *P, unsigned int offset)
+{ return * reinterpret_cast<Type*> ((char *) P + offset); }
+
+/* StructAfter<T>(X) returns the struct T& that is placed after X.
+ * Works with X of variable size also. X must implement get_size() */
+template<typename Type, typename TObject>
+static inline const Type& StructAfter(const TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+template<typename Type, typename TObject>
+static inline Type& StructAfter(TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+
+
+
+/*
+ * Size checking
+ */
+
+/* Check _assertion in a method environment */
+#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
+ inline void _instance_assertion_on_line_##_line (void) const \
+ { \
+ static_assert ((_assertion), ""); \
+ ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
+ }
+# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
+# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
+
+/* Check that _code compiles in a method environment */
+#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
+ inline void _compiles_assertion_on_line_##_line (void) const \
+ { _code; }
+# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
+# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
+
+
+#define DEFINE_SIZE_STATIC(size) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
+ static const unsigned int static_size = (size); \
+ static const unsigned int min_size = (size); \
+ inline unsigned int get_size (void) const { return (size); }
+
+#define DEFINE_SIZE_UNION(size, _member) \
+ DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_MIN(size) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY(size, array) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
+ DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+ static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
+ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
+ DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+ static const unsigned int min_size = (size)
+
+
+
+/*
+ * Null objects
+ */
+
+/* Global nul-content Null pool. Enlarge as necessary. */
+
+#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) {
+ 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. */
+#define DEFINE_NULL_DATA(Type, data) \
+static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
+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 */ \
+static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.")
+
+/* Accessor macro. */
+#define Null(Type) Null<Type>()
+
+
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+ static const unsigned int max_debug_depth = MaxDebugDepth;
+ typedef Return return_t;
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
+ static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
+};
+
+
+/*
+ * Sanitize
+ */
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 32
+#endif
+
+struct hb_sanitize_context_t :
+ hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
+{
+ inline hb_sanitize_context_t (void) :
+ debug_depth (0),
+ start (nullptr), end (nullptr),
+ writable (false), edit_count (0),
+ blob (nullptr) {}
+
+ inline const char *get_name (void) { return "SANITIZE"; }
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format)
+ { return format->sanitize (this); }
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
+ static return_t default_return_value (void) { return true; }
+ static return_t no_dispatch_return_value (void) { return false; }
+ bool stop_sublookup_iteration (const return_t r) const { return !r; }
+
+ inline void init (hb_blob_t *b)
+ {
+ this->blob = hb_blob_reference (b);
+ this->writable = false;
+ }
+
+ inline void start_processing (void)
+ {
+ 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;
+ this->debug_depth = 0;
+
+ DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
+ "start [%p..%p] (%lu bytes)",
+ this->start, this->end,
+ (unsigned long) (this->end - this->start));
+ }
+
+ inline void end_processing (void)
+ {
+ DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
+ "end [%p..%p] %u edit requests",
+ this->start, this->end, this->edit_count);
+
+ hb_blob_destroy (this->blob);
+ this->blob = nullptr;
+ this->start = this->end = nullptr;
+ }
+
+ inline bool check_range (const void *base, unsigned int len) const
+ {
+ const char *p = (const char *) base;
+ bool ok = this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len;
+
+ DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+ "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
+ p, p + len, len,
+ this->start, this->end,
+ ok ? "OK" : "OUT-OF-RANGE");
+
+ return likely (ok);
+ }
+
+ inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
+ {
+ const char *p = (const char *) base;
+ bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
+ unsigned int array_size = record_size * len;
+ bool ok = !overflows && this->check_range (base, array_size);
+
+ DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+ "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s",
+ p, p + (record_size * len), record_size, len, (unsigned int) array_size,
+ this->start, this->end,
+ overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE");
+
+ return likely (ok);
+ }
+
+ template <typename Type>
+ inline bool check_struct (const Type *obj) const
+ {
+ return likely (this->check_range (obj, obj->min_size));
+ }
+
+ inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
+ {
+ if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+ return false;
+
+ const char *p = (const char *) base;
+ this->edit_count++;
+
+ DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+ "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+ this->edit_count,
+ p, p + len, len,
+ this->start, this->end,
+ this->writable ? "GRANTED" : "DENIED");
+
+ return this->writable;
+ }
+
+ template <typename Type, typename ValueType>
+ inline bool try_set (const Type *obj, const ValueType &v) {
+ if (this->may_edit (obj, obj->static_size)) {
+ const_cast<Type *> (obj)->set (v);
+ return true;
+ }
+ return false;
+ }
+
+ mutable unsigned int debug_depth;
+ const char *start, *end;
+ bool writable;
+ unsigned int edit_count;
+ hb_blob_t *blob;
+};
+
+
+
+/* Template to sanitize an object. */
+template <typename Type>
+struct Sanitizer
+{
+ static hb_blob_t *sanitize (hb_blob_t *blob) {
+ hb_sanitize_context_t c[1];
+ bool sane;
+
+ /* TODO is_sane() stuff */
+
+ c->init (blob);
+
+ retry:
+ DEBUG_MSG_FUNC (SANITIZE, c->start, "start");
+
+ c->start_processing ();
+
+ if (unlikely (!c->start)) {
+ c->end_processing ();
+ return blob;
+ }
+
+ Type *t = CastP<Type> (const_cast<char *> (c->start));
+
+ sane = t->sanitize (c);
+ if (sane) {
+ if (c->edit_count) {
+ DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count);
+
+ /* sanitize again to ensure no toe-stepping */
+ c->edit_count = 0;
+ sane = t->sanitize (c);
+ if (c->edit_count) {
+ DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count);
+ sane = false;
+ }
+ }
+ } else {
+ unsigned int edit_count = c->edit_count;
+ if (edit_count && !c->writable) {
+ c->start = hb_blob_get_data_writable (blob, nullptr);
+ c->end = c->start + hb_blob_get_length (blob);
+
+ if (c->start) {
+ c->writable = true;
+ /* ok, we made it writable by relocating. try again */
+ DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
+ goto retry;
+ }
+ }
+ }
+
+ c->end_processing ();
+
+ DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
+ if (sane)
+ return blob;
+ else {
+ hb_blob_destroy (blob);
+ return hb_blob_get_empty ();
+ }
+ }
+
+ static const Type* lock_instance (hb_blob_t *blob) {
+ hb_blob_make_immutable (blob);
+ const char *base = hb_blob_get_data (blob, nullptr);
+ return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
+ }
+};
+
+
+
+/*
+ * Serialize
+ */
+
+
+struct hb_serialize_context_t
+{
+ inline hb_serialize_context_t (void *start_, unsigned int size)
+ {
+ this->start = (char *) start_;
+ this->end = this->start + size;
+
+ this->ran_out_of_room = false;
+ this->head = this->start;
+ this->debug_depth = 0;
+ }
+
+ template <typename Type>
+ inline Type *start_serialize (void)
+ {
+ DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+ "start [%p..%p] (%lu bytes)",
+ this->start, this->end,
+ (unsigned long) (this->end - this->start));
+
+ return start_embed<Type> ();
+ }
+
+ inline void end_serialize (void)
+ {
+ DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+ "end [%p..%p] serialized %d bytes; %s",
+ this->start, this->end,
+ (int) (this->head - this->start),
+ this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
+
+ }
+
+ template <typename Type>
+ inline Type *copy (void)
+ {
+ assert (!this->ran_out_of_room);
+ unsigned int len = this->head - this->start;
+ void *p = malloc (len);
+ if (p)
+ memcpy (p, this->start, len);
+ return reinterpret_cast<Type *> (p);
+ }
+
+ template <typename Type>
+ inline Type *allocate_size (unsigned int size)
+ {
+ if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
+ this->ran_out_of_room = true;
+ return nullptr;
+ }
+ memset (this->head, 0, size);
+ char *ret = this->head;
+ this->head += size;
+ return reinterpret_cast<Type *> (ret);
+ }
+
+ template <typename Type>
+ inline Type *allocate_min (void)
+ {
+ return this->allocate_size<Type> (Type::min_size);
+ }
+
+ template <typename Type>
+ inline Type *start_embed (void)
+ {
+ Type *ret = reinterpret_cast<Type *> (this->head);
+ return ret;
+ }
+
+ template <typename Type>
+ inline Type *embed (const Type &obj)
+ {
+ unsigned int size = obj.get_size ();
+ Type *ret = this->allocate_size<Type> (size);
+ if (unlikely (!ret)) return nullptr;
+ memcpy (ret, obj, size);
+ return ret;
+ }
+
+ template <typename Type>
+ inline Type *extend_min (Type &obj)
+ {
+ 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 nullptr;
+ return reinterpret_cast<Type *> (&obj);
+ }
+
+ template <typename Type>
+ inline Type *extend (Type &obj)
+ {
+ 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 nullptr;
+ return reinterpret_cast<Type *> (&obj);
+ }
+
+ inline void truncate (void *new_head)
+ {
+ assert (this->start < new_head && new_head <= this->head);
+ this->head = (char *) new_head;
+ }
+
+ unsigned int debug_depth;
+ char *start, *end, *head;
+ bool ran_out_of_room;
+};
+
+template <typename Type>
+struct Supplier
+{
+ inline Supplier (const Type *array, unsigned int len_)
+ {
+ head = array;
+ len = len_;
+ }
+ inline const Type operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len)) return Type ();
+ return head[i];
+ }
+
+ inline void advance (unsigned int count)
+ {
+ if (unlikely (count > len))
+ count = len;
+ len -= count;
+ head += count;
+ }
+
+ private:
+ inline Supplier (const Supplier<Type> &); /* Disallow copy */
+ inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
+
+ unsigned int len;
+ const Type *head;
+};
+
+
+
+
+/*
+ *
+ * The OpenType Font File: Data Types
+ */
+
+
+/* "The following data types are used in the OpenType font file.
+ * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
+
+/*
+ * Int types
+ */
+
+
+template <typename Type, int Bytes> struct BEInt;
+
+template <typename Type>
+struct BEInt<Type, 1>
+{
+ public:
+ inline void set (Type V)
+ {
+ v = V;
+ }
+ inline operator Type (void) const
+ {
+ return v;
+ }
+ private: uint8_t v;
+};
+template <typename Type>
+struct BEInt<Type, 2>
+{
+ public:
+ inline void set (Type V)
+ {
+ v[0] = (V >> 8) & 0xFF;
+ v[1] = (V ) & 0xFF;
+ }
+ inline operator Type (void) const
+ {
+ return (v[0] << 8)
+ + (v[1] );
+ }
+ private: uint8_t v[2];
+};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+ public:
+ inline void set (Type V)
+ {
+ v[0] = (V >> 16) & 0xFF;
+ v[1] = (V >> 8) & 0xFF;
+ v[2] = (V ) & 0xFF;
+ }
+ inline operator Type (void) const
+ {
+ return (v[0] << 16)
+ + (v[1] << 8)
+ + (v[2] );
+ }
+ private: uint8_t v[3];
+};
+template <typename Type>
+struct BEInt<Type, 4>
+{
+ public:
+ inline void set (Type V)
+ {
+ v[0] = (V >> 24) & 0xFF;
+ v[1] = (V >> 16) & 0xFF;
+ v[2] = (V >> 8) & 0xFF;
+ v[3] = (V ) & 0xFF;
+ }
+ inline operator Type (void) const
+ {
+ return (v[0] << 24)
+ + (v[1] << 16)
+ + (v[2] << 8)
+ + (v[3] );
+ }
+ private: uint8_t v[4];
+};
+
+/* Integer types in big-endian order and no alignment requirement */
+template <typename Type, unsigned int Size>
+struct IntType
+{
+ inline void set (Type i) { v.set (i); }
+ inline operator Type(void) const { return v; }
+ 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); }
+ template <typename Type2>
+ inline int cmp (Type2 a) const
+ {
+ Type b = v;
+ if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
+ return (int) a - (int) b;
+ else
+ return a < b ? -1 : a == b ? 0 : +1;
+ }
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this)));
+ }
+ protected:
+ BEInt<Type, Size> v;
+ public:
+ DEFINE_SIZE_STATIC (Size);
+};
+
+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 (INT16) that describes a quantity in FUnits. */
+typedef INT16 FWORD;
+
+/* 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 : INT16
+{
+ //inline float to_float (void) const { return ???; }
+ //inline void set_float (float f) { v.set (f * ???); }
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+/* 32-bit signed fixed-point number (16.16). */
+struct Fixed: INT32
+{
+ //inline float to_float (void) const { return ???; }
+ //inline void set_float (float f) { v.set (f * ???); }
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+/* Date represented in number of seconds since 12:00 midnight, January 1,
+ * 1904. The value is represented as a signed 64-bit integer. */
+struct LONGDATETIME
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this)));
+ }
+ protected:
+ 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 : 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); }
+ inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+DEFINE_NULL_DATA (Tag, " ");
+
+/* Glyph index number, same as uint16 (length = 16 bits) */
+typedef UINT16 GlyphID;
+
+/* Script/language-system/feature index */
+struct Index : UINT16 {
+ static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
+};
+DEFINE_NULL_DATA (Index, "\xff\xff");
+
+/* Offset, Null offset = 0 */
+template <typename Type>
+struct Offset : Type
+{
+ inline bool is_null (void) const { return 0 == *this; }
+ public:
+ DEFINE_SIZE_STATIC (sizeof(Type));
+};
+
+typedef Offset<UINT16> Offset16;
+typedef Offset<UINT32> Offset32;
+
+
+/* CheckSum */
+struct CheckSum : UINT32
+{
+ /* This is reference implementation from the spec. */
+ static inline uint32_t CalcTableChecksum (const UINT32 *Table, uint32_t Length)
+ {
+ uint32_t Sum = 0L;
+ const UINT32 *EndPtr = Table+((Length+3) & ~3) / UINT32::static_size;
+
+ while (Table < EndPtr)
+ Sum += *Table++;
+ return Sum;
+ }
+
+ /* 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 UINT32 *) data, length)); }
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+/*
+ * Version Numbers
+ */
+
+template <typename FixedType=UINT16>
+struct FixedVersion
+{
+ inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ FixedType major;
+ FixedType minor;
+ public:
+ DEFINE_SIZE_STATIC (2 * sizeof(FixedType));
+};
+
+
+
+/*
+ * Template subclasses of Offset that do the dereferencing.
+ * Use: (base+offset)
+ */
+
+template <typename Type, typename OffsetType=UINT16>
+struct OffsetTo : Offset<OffsetType>
+{
+ inline const Type& operator () (const void *base) const
+ {
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return Null(Type);
+ return StructAtOffset<Type> (base, offset);
+ }
+
+ inline Type& serialize (hb_serialize_context_t *c, const void *base)
+ {
+ Type *t = c->start_embed<Type> ();
+ this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+ return *t;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return_trace (false);
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return_trace (true);
+ if (unlikely (!c->check_range (base, offset))) return_trace (false);
+ const Type &obj = StructAtOffset<Type> (base, offset);
+ return_trace (likely (obj.sanitize (c)) || neuter (c));
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return_trace (false);
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return_trace (true);
+ if (unlikely (!c->check_range (base, offset))) return_trace (false);
+ const Type &obj = StructAtOffset<Type> (base, offset);
+ return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
+ }
+
+ /* Set the offset to Null */
+ inline bool neuter (hb_sanitize_context_t *c) const {
+ return c->try_set (this, 0);
+ }
+ 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>
+static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
+
+
+/*
+ * Array Types
+ */
+
+/* An array with a number of elements. */
+template <typename Type, typename LenType=UINT16>
+struct ArrayOf
+{
+ const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
+ {
+ unsigned int count = len;
+ if (unlikely (start_offset > count))
+ count = 0;
+ else
+ count -= start_offset;
+ count = MIN (count, *pcount);
+ *pcount = count;
+ return array + start_offset;
+ }
+
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len)) return Null(Type);
+ return array[i];
+ }
+ inline Type& operator [] (unsigned int i)
+ {
+ return array[i];
+ }
+ inline unsigned int get_size (void) const
+ { return len.static_size + len * Type::static_size; }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ len.set (items_len); /* TODO(serialize) Overflow? */
+ if (unlikely (!c->extend (*this))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<Type> &items,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!serialize (c, items_len))) return_trace (false);
+ for (unsigned int i = 0; i < items_len; i++)
+ array[i] = items[i];
+ items.advance (items_len);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return_trace (false);
+
+ /* Note: for structs that do not reference other structs,
+ * we do not need to call their sanitize() as we already did
+ * a bound check on the aggregate array size. We just include
+ * a small unreachable expression to make sure the structs
+ * pointed to do have a simple sanitize(), ie. they do not
+ * reference other structs via offsets.
+ */
+ (void) (false && array[0].sanitize (c));
+
+ return_trace (true);
+ }
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return_trace (false);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!array[i].sanitize (c, base)))
+ return_trace (false);
+ return_trace (true);
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return_trace (false);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!array[i].sanitize (c, base, user_data)))
+ return_trace (false);
+ return_trace (true);
+ }
+
+ template <typename SearchType>
+ inline int lsearch (const SearchType &x) const
+ {
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!this->array[i].cmp (x))
+ return i;
+ return -1;
+ }
+
+ private:
+ inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
+ }
+
+ public:
+ LenType len;
+ Type array[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+};
+template <typename Type> struct LArrayOf : ArrayOf<Type, UINT32> {};
+
+/* Array of Offset's */
+template <typename Type, typename OffsetType=UINT16>
+struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
+
+/* Array of offsets relative to the beginning of the array itself. */
+template <typename Type>
+struct OffsetListOf : OffsetArrayOf<Type>
+{
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= this->len)) return Null(Type);
+ return this+this->array[i];
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (OffsetArrayOf<Type>::sanitize (c, this));
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data));
+ }
+};
+
+
+/* An array starting at second element. */
+template <typename Type, typename LenType=UINT16>
+struct HeadlessArrayOf
+{
+ inline const Type& operator [] (unsigned int i) const
+ {
+ if (unlikely (i >= len || !i)) return Null(Type);
+ return array[i-1];
+ }
+ inline unsigned int get_size (void) const
+ { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<Type> &items,
+ unsigned int items_len)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ len.set (items_len); /* TODO(serialize) Overflow? */
+ if (unlikely (!items_len)) return_trace (true);
+ if (unlikely (!c->extend (*this))) return_trace (false);
+ for (unsigned int i = 0; i < items_len - 1; i++)
+ array[i] = items[i];
+ items.advance (items_len - 1);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c))) return_trace (false);
+
+ /* Note: for structs that do not reference other structs,
+ * we do not need to call their sanitize() as we already did
+ * a bound check on the aggregate array size. We just include
+ * a small unreachable expression to make sure the structs
+ * pointed to do have a simple sanitize(), ie. they do not
+ * reference other structs via offsets.
+ */
+ (void) (false && array[0].sanitize (c));
+
+ 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:
+ DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+};
+
+
+/*
+ * 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 = array[mid].cmp (x);
+ if (c < 0)
+ max = mid - 1;
+ else if (c > 0)
+ min = mid + 1;
+ else
+ return mid;
+ }
+ return -1;
+ }
+};
+
+/*
+ * 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 */
+
+
+#endif /* HB_OPEN_TYPE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
deleted file mode 100644
index 4c9bfebcec1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OPEN_TYPE_HH
-#define HB_OPEN_TYPE_HH
-
-#include "hb.hh"
-#include "hb-blob.hh"
-#include "hb-face.hh"
-#include "hb-machinery.hh"
-#include "hb-meta.hh"
-#include "hb-subset.hh"
-
-
-namespace OT {
-
-
-/*
- *
- * The OpenType Font File: Data Types
- */
-
-
-/* "The following data types are used in the OpenType font file.
- * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
-
-/*
- * Int types
- */
-
-/* Integer types in big-endian order and no alignment requirement */
-template <typename Type,
- unsigned int Size = sizeof (Type)>
-struct IntType
-{
- typedef Type type;
-
- IntType () = default;
- explicit constexpr IntType (Type V) : v {V} {}
- IntType& operator = (Type i) { v = i; return *this; }
- /* For reason we define cast out operator for signed/unsigned, instead of Type, see:
- * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */
- operator typename std::conditional<std::is_signed<Type>::value, signed, unsigned>::type () const { return v; }
-
- bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
- bool operator != (const IntType &o) const { return !(*this == o); }
-
- IntType& operator += (unsigned count) { *this = *this + count; return *this; }
- IntType& operator -= (unsigned count) { *this = *this - count; return *this; }
- IntType& operator ++ () { *this += 1; return *this; }
- IntType& operator -- () { *this -= 1; return *this; }
- IntType operator ++ (int) { IntType c (*this); ++*this; return c; }
- IntType operator -- (int) { IntType c (*this); --*this; return c; }
-
- HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
- { return b->cmp (*a); }
- HB_INTERNAL static int cmp (const void *a, const void *b)
- {
- IntType *pa = (IntType *) a;
- IntType *pb = (IntType *) b;
-
- return pb->cmp (*pa);
- }
- template <typename Type2,
- hb_enable_if (std::is_integral<Type2>::value &&
- sizeof (Type2) < sizeof (int) &&
- sizeof (Type) < sizeof (int))>
- int cmp (Type2 a) const
- {
- Type b = v;
- return (int) a - (int) b;
- }
- template <typename Type2,
- hb_enable_if (hb_is_convertible (Type2, Type))>
- int cmp (Type2 a) const
- {
- Type b = v;
- return a < b ? -1 : a == b ? 0 : +1;
- }
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
- protected:
- BEInt<Type, Size> v;
- public:
- DEFINE_SIZE_STATIC (Size);
-};
-
-typedef IntType<uint8_t> HBUINT8; /* 8-bit unsigned integer. */
-typedef IntType<int8_t> HBINT8; /* 8-bit signed integer. */
-typedef IntType<uint16_t> HBUINT16; /* 16-bit unsigned integer. */
-typedef IntType<int16_t> HBINT16; /* 16-bit signed integer. */
-typedef IntType<uint32_t> HBUINT32; /* 32-bit unsigned integer. */
-typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */
-/* Note: we cannot defined a signed HBINT24 because there's no corresponding C type.
- * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */
-typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
-
-/* 15-bit unsigned number; top bit used for extension. */
-struct HBUINT15 : HBUINT16
-{
- /* TODO Flesh out; actually mask top bit. */
- HBUINT15& operator = (uint16_t i ) { HBUINT16::operator= (i); return *this; }
- public:
- DEFINE_SIZE_STATIC (2);
-};
-
-/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
-typedef HBINT16 FWORD;
-
-/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */
-typedef HBINT32 FWORD32;
-
-/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
-typedef HBUINT16 UFWORD;
-
-template <typename Type, unsigned fraction_bits>
-struct HBFixed : Type
-{
- static constexpr float shift = (float) (1 << fraction_bits);
- static_assert (Type::static_size * 8 > fraction_bits, "");
-
- operator signed () const = delete;
- operator unsigned () const = delete;
- typename Type::type to_int () const { return Type::v; }
- void set_int (typename Type::type i ) { Type::v = i; }
- float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; }
- void set_float (float f) { Type::v = roundf (f * shift); }
- public:
- DEFINE_SIZE_STATIC (Type::static_size);
-};
-
-/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
-using F2DOT14 = HBFixed<HBINT16, 14>;
-using F4DOT12 = HBFixed<HBINT16, 12>;
-using F6DOT10 = HBFixed<HBINT16, 10>;
-
-/* 32-bit signed fixed-point number (16.16). */
-using F16DOT16 = HBFixed<HBINT32, 16>;
-
-/* Date represented in number of seconds since 12:00 midnight, January 1,
- * 1904. The value is represented as a signed 64-bit integer. */
-struct LONGDATETIME
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
- protected:
- HBINT32 major;
- HBUINT32 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 : HBUINT32
-{
- Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; }
- /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
- operator const char* () const { return reinterpret_cast<const char *> (this); }
- operator char* () { return reinterpret_cast<char *> (this); }
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-/* Glyph index number, same as uint16 (length = 16 bits) */
-struct HBGlyphID16 : HBUINT16
-{
- HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
-};
-struct HBGlyphID24 : HBUINT24
-{
- HBGlyphID24& operator = (uint32_t i) { HBUINT24::operator= (i); return *this; }
-};
-
-/* Script/language-system/feature index */
-struct Index : HBUINT16 {
- static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFu;
- Index& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
-};
-DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
-
-typedef Index NameID;
-
-struct VarIdx : HBUINT32 {
- static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu;
- static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, "");
- static uint32_t add (uint32_t i, unsigned short v)
- {
- if (i == NO_VARIATION) return i;
- return i + v;
- }
- VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
-};
-DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx);
-
-/* Offset, Null offset = 0 */
-template <typename Type, bool has_null=true>
-struct Offset : Type
-{
- Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; }
-
- typedef Type type;
-
- bool is_null () const { return has_null && 0 == *this; }
-
- public:
- DEFINE_SIZE_STATIC (sizeof (Type));
-};
-
-typedef Offset<HBUINT16> Offset16;
-typedef Offset<HBUINT24> Offset24;
-typedef Offset<HBUINT32> Offset32;
-
-
-/* CheckSum */
-struct CheckSum : HBUINT32
-{
- CheckSum& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
-
- /* This is reference implementation from the spec. */
- static uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
- {
- uint32_t Sum = 0L;
- assert (0 == (Length & 3));
- const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size;
-
- while (Table < EndPtr)
- Sum += *Table++;
- return Sum;
- }
-
- /* Note: data should be 4byte aligned and have 4byte padding at the end. */
- void set_for_data (const void *data, unsigned int length)
- { *this = CalcTableChecksum ((const HBUINT32 *) data, length); }
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-
-/*
- * Version Numbers
- */
-
-template <typename FixedType=HBUINT16>
-struct FixedVersion
-{
- uint32_t to_int () const { return (major << (sizeof (FixedType) * 8)) + minor; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- FixedType major;
- FixedType minor;
- public:
- DEFINE_SIZE_STATIC (2 * sizeof (FixedType));
-};
-
-
-/*
- * Template subclasses of Offset that do the dereferencing.
- * Use: (base+offset)
- */
-
-template <typename Type, bool has_null>
-struct _hb_has_null
-{
- static const Type *get_null () { return nullptr; }
- static Type *get_crap () { return nullptr; }
-};
-template <typename Type>
-struct _hb_has_null<Type, true>
-{
- static const Type *get_null () { return &Null (Type); }
- static Type *get_crap () { return &Crap (Type); }
-};
-
-template <typename Type, typename OffsetType, bool has_null=true>
-struct OffsetTo : Offset<OffsetType, has_null>
-{
- // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time.
- static_assert (has_null == false ||
- (hb_has_null_size (Type) || !hb_has_min_size (Type)), "");
-
- HB_DELETE_COPY_ASSIGN (OffsetTo);
- OffsetTo () = default;
-
- OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; }
-
- const Type& operator () (const void *base) const
- {
- if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null ();
- return StructAtOffset<const Type> (base, *this);
- }
- Type& operator () (void *base) const
- {
- if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_crap ();
- return StructAtOffset<Type> (base, *this);
- }
-
- template <typename Base,
- hb_enable_if (hb_is_convertible (const Base, const void *))>
- friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
- template <typename Base,
- hb_enable_if (hb_is_convertible (const Base, const void *))>
- friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
- template <typename Base,
- hb_enable_if (hb_is_convertible (Base, void *))>
- friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
- template <typename Base,
- hb_enable_if (hb_is_convertible (Base, void *))>
- friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
-
-
- template <typename ...Ts>
- bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src,
- const void *src_base, Ts&&... ds)
- {
- *this = 0;
- if (src.is_null ())
- return false;
-
- auto *s = c->serializer;
-
- s->push ();
-
- bool ret = c->dispatch (src_base+src, std::forward<Ts> (ds)...);
-
- if (ret || !has_null)
- s->add_link (*this, s->pop_pack ());
- else
- s->pop_discard ();
-
- return ret;
- }
-
-
- template <typename ...Ts>
- bool serialize_serialize (hb_serialize_context_t *c, Ts&&... ds)
- {
- *this = 0;
-
- Type* obj = c->push<Type> ();
- bool ret = obj->serialize (c, std::forward<Ts> (ds)...);
-
- if (ret)
- c->add_link (*this, c->pop_pack ());
- else
- c->pop_discard ();
-
- return ret;
- }
-
- /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
- /* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029
- * Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&...
- */
- template <typename ...Ts>
- bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src,
- const void *src_base, unsigned dst_bias,
- hb_serialize_context_t::whence_t whence,
- Ts&&... ds)
- {
- *this = 0;
- if (src.is_null ())
- return false;
-
- c->push ();
-
- bool ret = c->copy (src_base+src, std::forward<Ts> (ds)...);
-
- c->add_link (*this, c->pop_pack (), whence, dst_bias);
-
- return ret;
- }
-
- bool serialize_copy (hb_serialize_context_t *c, const OffsetTo& src,
- const void *src_base, unsigned dst_bias = 0)
- { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); }
-
- bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this))) return_trace (false);
- if (unlikely (this->is_null ())) return_trace (true);
- if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false);
- return_trace (true);
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- return_trace (sanitize_shallow (c, base) &&
- (this->is_null () ||
- c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) ||
- neuter (c)));
- }
-
- /* Set the offset to Null */
- bool neuter (hb_sanitize_context_t *c) const
- {
- if (!has_null) return false;
- return c->try_set (this, 0);
- }
- DEFINE_SIZE_STATIC (sizeof (OffsetType));
-};
-/* Partial specializations. */
-template <typename Type, bool has_null=true> using Offset16To = OffsetTo<Type, HBUINT16, has_null>;
-template <typename Type, bool has_null=true> using Offset24To = OffsetTo<Type, HBUINT24, has_null>;
-template <typename Type, bool has_null=true> using Offset32To = OffsetTo<Type, HBUINT32, has_null>;
-
-template <typename Type, typename OffsetType> using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
-template <typename Type> using NNOffset16To = Offset16To<Type, false>;
-template <typename Type> using NNOffset24To = Offset24To<Type, false>;
-template <typename Type> using NNOffset32To = Offset32To<Type, false>;
-
-
-/*
- * Array Types
- */
-
-template <typename Type>
-struct UnsizedArrayOf
-{
- typedef Type item_t;
- static constexpr unsigned item_size = hb_static_size (Type);
-
- HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
-
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- const Type *p = &arrayZ[i];
- if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */
- _hb_compiler_memory_r_barrier ();
- return *p;
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- Type *p = &arrayZ[i];
- if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */
- _hb_compiler_memory_r_barrier ();
- return *p;
- }
-
- unsigned int get_size (unsigned int len) const
- { return len * Type::static_size; }
-
- template <typename T> operator T * () { return arrayZ; }
- template <typename T> operator const T * () const { return arrayZ; }
- hb_array_t<Type> as_array (unsigned int len)
- { return hb_array (arrayZ, len); }
- hb_array_t<const Type> as_array (unsigned int len) const
- { return hb_array (arrayZ, len); }
-
- template <typename T>
- Type &lsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
- { return *as_array (len).lsearch (x, &not_found); }
- template <typename T>
- const Type &lsearch (unsigned int len, const T &x, const Type &not_found = Null (Type)) const
- { return *as_array (len).lsearch (x, &not_found); }
- template <typename T>
- bool lfind (unsigned int len, const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- { return as_array (len).lfind (x, i, not_found, to_store); }
-
- void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
- { as_array (len).qsort (start, end); }
-
- bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false);
- return_trace (true);
- }
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, Type))>
- bool serialize (hb_serialize_context_t *c, Iterator items)
- {
- TRACE_SERIALIZE (this);
- unsigned count = hb_len (items);
- if (unlikely (!serialize (c, count, false))) return_trace (false);
- /* TODO Umm. Just exhaust the iterator instead? Being extra
- * cautious right now.. */
- for (unsigned i = 0; i < count; i++, ++items)
- arrayZ[i] = *items;
- return_trace (true);
- }
-
- UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!as_array (count).copy (c))) return_trace (nullptr);
- return_trace (out);
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
- if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
- return_trace (false);
- return_trace (true);
- }
-
- bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_array (arrayZ, count));
- }
-
- public:
- Type arrayZ[HB_VAR_ARRAY];
- public:
- DEFINE_SIZE_UNBOUNDED (0);
-};
-
-/* Unsized array of offset's */
-template <typename Type, typename OffsetType, bool has_null=true>
-using UnsizedArray16OfOffsetTo = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>;
-
-/* Unsized array of offsets relative to the beginning of the array itself. */
-template <typename Type, typename OffsetType, bool has_null=true>
-struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
-{
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i];
- if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */
- _hb_compiler_memory_r_barrier ();
- return this+*p;
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i];
- if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */
- _hb_compiler_memory_r_barrier ();
- return this+*p;
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
- ::sanitize (c, count, this, std::forward<Ts> (ds)...)));
- }
-};
-
-/* An array with sorted elements. Supports binary searching. */
-template <typename Type>
-struct SortedUnsizedArrayOf : UnsizedArrayOf<Type>
-{
- hb_sorted_array_t<Type> as_array (unsigned int len)
- { return hb_sorted_array (this->arrayZ, len); }
- hb_sorted_array_t<const Type> as_array (unsigned int len) const
- { return hb_sorted_array (this->arrayZ, len); }
- operator hb_sorted_array_t<Type> () { return as_array (); }
- operator hb_sorted_array_t<const Type> () const { return as_array (); }
-
- template <typename T>
- Type &bsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
- { return *as_array (len).bsearch (x, &not_found); }
- template <typename T>
- const Type &bsearch (unsigned int len, const T &x, const Type &not_found = Null (Type)) const
- { return *as_array (len).bsearch (x, &not_found); }
- template <typename T>
- bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- { return as_array (len).bfind (x, i, not_found, to_store); }
-};
-
-
-/* An array with a number of elements. */
-template <typename Type, typename LenType>
-struct ArrayOf
-{
- typedef Type item_t;
- static constexpr unsigned item_size = hb_static_size (Type);
-
- HB_DELETE_CREATE_COPY_ASSIGN (ArrayOf);
-
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= len)) return Null (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i];
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= len)) return Crap (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i];
- }
-
- unsigned int get_size () const
- { return len.static_size + len * Type::static_size; }
-
- explicit operator bool () const { return len; }
-
- void pop () { len--; }
-
- hb_array_t< Type> as_array () { return hb_array (arrayZ, len); }
- hb_array_t<const Type> as_array () const { return hb_array (arrayZ, len); }
-
- /* Iterator. */
- typedef hb_array_t<const Type> iter_t;
- typedef hb_array_t< Type> writer_t;
- iter_t iter () const { return as_array (); }
- writer_t writer () { return as_array (); }
- operator iter_t () const { return iter (); }
- operator writer_t () { return writer (); }
-
- /* Faster range-based for loop. */
- const Type *begin () const { return arrayZ; }
- const Type *end () const { return arrayZ + len; }
-
- template <typename T>
- Type &lsearch (const T &x, Type &not_found = Crap (Type))
- { return *as_array ().lsearch (x, &not_found); }
- template <typename T>
- const Type &lsearch (const T &x, const Type &not_found = Null (Type)) const
- { return *as_array ().lsearch (x, &not_found); }
- template <typename T>
- bool lfind (const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- { return as_array ().lfind (x, i, not_found, to_store); }
-
- void qsort ()
- { as_array ().qsort (); }
-
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
- return_trace (true);
- }
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, Type))>
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
- {
- TRACE_SERIALIZE (this);
- unsigned count = hb_len (items);
- if (unlikely (!serialize (c, count, false))) return_trace (false);
- /* TODO Umm. Just exhaust the iterator instead? Being extra
- * cautious right now.. */
- for (unsigned i = 0; i < count; i++, ++items)
- arrayZ[i] = *items;
- return_trace (true);
- }
-
- Type* serialize_append (hb_serialize_context_t *c)
- {
- TRACE_SERIALIZE (this);
- len++;
- if (unlikely (!len || !c->extend (this)))
- {
- len--;
- return_trace (nullptr);
- }
- return_trace (&arrayZ[len - 1]);
- }
-
- ArrayOf* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!c->extend_min (out))) return_trace (nullptr);
- c->check_assign (out->len, len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!as_array ().copy (c))) return_trace (nullptr);
- return_trace (out);
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
- return_trace (false);
- return_trace (true);
- }
-
- bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
- }
-
- public:
- LenType len;
- Type arrayZ[HB_VAR_ARRAY];
- public:
- DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
-};
-template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>;
-template <typename Type> using Array24Of = ArrayOf<Type, HBUINT24>;
-template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>;
-using PString = ArrayOf<HBUINT8, HBUINT8>;
-
-/* Array of Offset's */
-template <typename Type> using Array16OfOffset16To = ArrayOf<OffsetTo<Type, HBUINT16>, HBUINT16>;
-template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT16>;
-template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
-
-/* Array of offsets relative to the beginning of the array itself. */
-template <typename Type, typename OffsetType>
-struct List16OfOffsetTo : ArrayOf<OffsetTo<Type, OffsetType>, HBUINT16>
-{
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= this->len)) return Null (Type);
- _hb_compiler_memory_r_barrier ();
- return this+this->arrayZ[i];
- }
- const Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= this->len)) return Crap (Type);
- _hb_compiler_memory_r_barrier ();
- return this+this->arrayZ[i];
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- struct List16OfOffsetTo *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
- unsigned int count = this->len;
- for (unsigned int i = 0; i < count; i++)
- out->arrayZ[i].serialize_subset (c, this->arrayZ[i], this, out);
- return_trace (true);
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- return_trace ((Array16Of<OffsetTo<Type, OffsetType>>::sanitize (c, this, std::forward<Ts> (ds)...)));
- }
-};
-
-template <typename Type>
-using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>;
-
-/* An array starting at second element. */
-template <typename Type, typename LenType=HBUINT16>
-struct HeadlessArrayOf
-{
- static constexpr unsigned item_size = Type::static_size;
-
- HB_DELETE_CREATE_COPY_ASSIGN (HeadlessArrayOf);
-
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= lenP1 || !i)) return Null (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i-1];
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= lenP1 || !i)) return Crap (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i-1];
- }
- unsigned int get_size () const
- { return lenP1.static_size + get_length () * Type::static_size; }
-
- unsigned get_length () const { return lenP1 ? lenP1 - 1 : 0; }
-
- hb_array_t< Type> as_array () { return hb_array (arrayZ, get_length ()); }
- hb_array_t<const Type> as_array () const { return hb_array (arrayZ, get_length ()); }
-
- /* Iterator. */
- typedef hb_array_t<const Type> iter_t;
- typedef hb_array_t< Type> writer_t;
- iter_t iter () const { return as_array (); }
- writer_t writer () { return as_array (); }
- operator iter_t () const { return iter (); }
- operator writer_t () { return writer (); }
-
- /* Faster range-based for loop. */
- const Type *begin () const { return arrayZ; }
- const Type *end () const { return arrayZ + get_length (); }
-
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
- return_trace (true);
- }
- template <typename Iterator,
- hb_requires (hb_is_source_of (Iterator, Type))>
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
- {
- TRACE_SERIALIZE (this);
- unsigned count = hb_len (items);
- if (unlikely (!serialize (c, count, false))) return_trace (false);
- /* TODO Umm. Just exhaust the iterator instead? Being extra
- * cautious right now.. */
- for (unsigned i = 0; i < count; i++, ++items)
- arrayZ[i] = *items;
- return_trace (true);
- }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
- unsigned int count = get_length ();
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
- return_trace (false);
- return_trace (true);
- }
-
- private:
- bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (lenP1.sanitize (c) &&
- (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
- }
-
- public:
- LenType lenP1;
- Type arrayZ[HB_VAR_ARRAY];
- public:
- DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
-};
-
-/* An array storing length-1. */
-template <typename Type, typename LenType=HBUINT16>
-struct ArrayOfM1
-{
- HB_DELETE_CREATE_COPY_ASSIGN (ArrayOfM1);
-
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i > lenM1)) return Null (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i];
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i > lenM1)) return Crap (Type);
- _hb_compiler_memory_r_barrier ();
- return arrayZ[i];
- }
- unsigned int get_size () const
- { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
- unsigned int count = lenM1 + 1;
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
- return_trace (false);
- return_trace (true);
- }
-
- private:
- bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (lenM1.sanitize (c) &&
- (c->check_array (arrayZ, lenM1 + 1)));
- }
-
- public:
- LenType lenM1;
- Type arrayZ[HB_VAR_ARRAY];
- public:
- DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
-};
-
-/* An array with sorted elements. Supports binary searching. */
-template <typename Type, typename LenType>
-struct SortedArrayOf : ArrayOf<Type, LenType>
-{
- hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->len); }
- hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->len); }
-
- /* Iterator. */
- typedef hb_sorted_array_t<const Type> iter_t;
- typedef hb_sorted_array_t< Type> writer_t;
- iter_t iter () const { return as_array (); }
- writer_t writer () { return as_array (); }
- operator iter_t () const { return iter (); }
- operator writer_t () { return writer (); }
-
- /* Faster range-based for loop. */
- const Type *begin () const { return this->arrayZ; }
- const Type *end () const { return this->arrayZ + this->len; }
-
- bool serialize (hb_serialize_context_t *c, unsigned int items_len)
- {
- TRACE_SERIALIZE (this);
- bool ret = ArrayOf<Type, LenType>::serialize (c, items_len);
- return_trace (ret);
- }
- template <typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, Type))>
- bool serialize (hb_serialize_context_t *c, Iterator items)
- {
- TRACE_SERIALIZE (this);
- bool ret = ArrayOf<Type, LenType>::serialize (c, items);
- return_trace (ret);
- }
-
- template <typename T>
- Type &bsearch (const T &x, Type &not_found = Crap (Type))
- { return *as_array ().bsearch (x, &not_found); }
- template <typename T>
- const Type &bsearch (const T &x, const Type &not_found = Null (Type)) const
- { return *as_array ().bsearch (x, &not_found); }
- template <typename T>
- bool bfind (const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- { return as_array ().bfind (x, i, not_found, to_store); }
-};
-
-template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>;
-template <typename Type> using SortedArray24Of = SortedArrayOf<Type, HBUINT24>;
-template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>;
-
-/*
- * Binary-search arrays
- */
-
-template <typename LenType=HBUINT16>
-struct BinSearchHeader
-{
- operator uint32_t () const { return len; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- BinSearchHeader& operator = (unsigned int v)
- {
- len = v;
- assert (len == v);
- entrySelector = hb_max (1u, hb_bit_storage (v)) - 1;
- searchRange = 16 * (1u << entrySelector);
- rangeShift = v * 16 > searchRange
- ? 16 * v - searchRange
- : 0;
- return *this;
- }
-
- protected:
- LenType len;
- LenType searchRange;
- LenType entrySelector;
- LenType rangeShift;
-
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-template <typename Type, typename LenType=HBUINT16>
-using BinSearchArrayOf = SortedArrayOf<Type, BinSearchHeader<LenType>>;
-
-
-struct VarSizedBinSearchHeader
-{
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */
- HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */
- HBUINT16 searchRange; /* The value of unitSize times the largest power of 2
- * that is less than or equal to the value of nUnits. */
- HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than
- * or equal to the value of nUnits. */
- HBUINT16 rangeShift; /* The value of unitSize times the difference of the
- * value of nUnits minus the largest power of 2 less
- * than or equal to the value of nUnits. */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-template <typename Type>
-struct VarSizedBinSearchArrayOf
-{
- static constexpr unsigned item_size = Type::static_size;
-
- HB_DELETE_CREATE_COPY_ASSIGN (VarSizedBinSearchArrayOf);
-
- bool last_is_terminator () const
- {
- if (unlikely (!header.nUnits)) return false;
-
- /* Gah.
- *
- * "The number of termination values that need to be included is table-specific.
- * The value that indicates binary search termination is 0xFFFF." */
- const HBUINT16 *words = &StructAtOffset<HBUINT16> (&bytesZ, (header.nUnits - 1) * header.unitSize);
- unsigned int count = Type::TerminationWordCount;
- for (unsigned int i = 0; i < count; i++)
- if (words[i] != 0xFFFFu)
- return false;
- return true;
- }
-
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= get_length ())) return Null (Type);
- _hb_compiler_memory_r_barrier ();
- return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
- }
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= get_length ())) return Crap (Type);
- _hb_compiler_memory_r_barrier ();
- return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
- }
- unsigned int get_length () const
- { return header.nUnits - last_is_terminator (); }
- unsigned int get_size () const
- { return header.static_size + header.nUnits * header.unitSize; }
-
- template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
- unsigned int count = get_length ();
- for (unsigned int i = 0; i < count; i++)
- if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
- return_trace (false);
- return_trace (true);
- }
-
- template <typename T>
- const Type *bsearch (const T &key) const
- {
- unsigned pos;
- return hb_bsearch_impl (&pos,
- key,
- (const void *) bytesZ,
- get_length (),
- header.unitSize,
- _hb_cmp_method<T, Type>)
- ? (const Type *) (((const char *) &bytesZ) + (pos * header.unitSize))
- : nullptr;
- }
-
- private:
- bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (header.sanitize (c) &&
- Type::static_size <= header.unitSize &&
- c->check_range (bytesZ.arrayZ,
- header.nUnits,
- header.unitSize));
- }
-
- protected:
- VarSizedBinSearchHeader header;
- UnsizedArrayOf<HBUINT8> bytesZ;
- public:
- DEFINE_SIZE_ARRAY (10, bytesZ);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OPEN_TYPE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh
new file mode 100644
index 00000000000..415625e5f80
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh
@@ -0,0 +1,471 @@
+/*
+ * Copyright © 2016 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): Seigo Nonaka
+ */
+
+#ifndef HB_OT_CBDT_TABLE_HH
+#define HB_OT_CBDT_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+namespace OT {
+
+struct SmallGlyphMetrics
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ inline void get_extents (hb_glyph_extents_t *extents) const
+ {
+ extents->x_bearing = bearingX;
+ extents->y_bearing = bearingY;
+ extents->width = width;
+ extents->height = -height;
+ }
+
+ UINT8 height;
+ UINT8 width;
+ INT8 bearingX;
+ INT8 bearingY;
+ UINT8 advance;
+
+ DEFINE_SIZE_STATIC(5);
+};
+
+struct BigGlyphMetrics : SmallGlyphMetrics
+{
+ INT8 vertBearingX;
+ INT8 vertBearingY;
+ UINT8 vertAdvance;
+
+ DEFINE_SIZE_STATIC(8);
+};
+
+struct SBitLineMetrics
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ 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);
+};
+
+
+/*
+ * Index Subtables.
+ */
+
+struct IndexSubtableHeader
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ UINT16 indexFormat;
+ UINT16 imageFormat;
+ UINT32 imageDataOffset;
+
+ DEFINE_SIZE_STATIC(8);
+};
+
+template <typename OffsetType>
+struct IndexSubtableFormat1Or3
+{
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
+ }
+
+ bool get_image_data (unsigned int idx,
+ unsigned int *offset,
+ unsigned int *length) const
+ {
+ if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
+ return false;
+
+ *offset = header.imageDataOffset + offsetArrayZ[idx];
+ *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
+ return true;
+ }
+
+ IndexSubtableHeader header;
+ Offset<OffsetType> offsetArrayZ[VAR];
+
+ DEFINE_SIZE_ARRAY(8, offsetArrayZ);
+};
+
+struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<UINT32> {};
+struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<UINT16> {};
+
+struct IndexSubtable
+{
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.header.sanitize (c)) return_trace (false);
+ switch (u.header.indexFormat) {
+ case 1: return_trace (u.format1.sanitize (c, glyph_count));
+ case 3: return_trace (u.format3.sanitize (c, glyph_count));
+ default:return_trace (true);
+ }
+ }
+
+ inline bool get_extents (hb_glyph_extents_t *extents) const
+ {
+ switch (u.header.indexFormat) {
+ case 2: case 5: /* TODO */
+ case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
+ default:return (false);
+ }
+ }
+
+ bool get_image_data (unsigned int idx,
+ unsigned int *offset,
+ unsigned int *length,
+ unsigned int *format) const
+ {
+ *format = u.header.imageFormat;
+ switch (u.header.indexFormat) {
+ case 1: return u.format1.get_image_data (idx, offset, length);
+ case 3: return u.format3.get_image_data (idx, offset, length);
+ default: return false;
+ }
+ }
+
+ protected:
+ union {
+ IndexSubtableHeader header;
+ IndexSubtableFormat1 format1;
+ IndexSubtableFormat3 format3;
+ /* TODO: Format 2, 4, 5. */
+ } u;
+ public:
+ DEFINE_SIZE_UNION (8, header);
+};
+
+struct IndexSubtableRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ firstGlyphIndex <= lastGlyphIndex &&
+ offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
+ }
+
+ inline bool get_extents (hb_glyph_extents_t *extents) const
+ {
+ return (this+offsetToSubtable).get_extents (extents);
+ }
+
+ bool get_image_data (unsigned int gid,
+ unsigned int *offset,
+ unsigned int *length,
+ unsigned int *format) const
+ {
+ if (gid < firstGlyphIndex || gid > lastGlyphIndex)
+ {
+ return false;
+ }
+ return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
+ offset, length, format);
+ }
+
+ UINT16 firstGlyphIndex;
+ UINT16 lastGlyphIndex;
+ LOffsetTo<IndexSubtable> offsetToSubtable;
+
+ DEFINE_SIZE_STATIC(8);
+};
+
+struct IndexSubtableArray
+{
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
+ return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
+ return_trace (false);
+ return_trace (true);
+ }
+
+ public:
+ const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
+ {
+ for (unsigned int i = 0; i < numTables; ++i)
+ {
+ unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
+ unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
+ if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
+ return &indexSubtablesZ[i];
+ }
+ }
+ return nullptr;
+ }
+
+ protected:
+ IndexSubtableRecord indexSubtablesZ[VAR];
+
+ public:
+ DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
+};
+
+struct BitmapSizeTable
+{
+ friend struct CBLC;
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
+ c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
+ horizontal.sanitize (c) &&
+ vertical.sanitize (c));
+ }
+
+ const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
+ {
+ return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
+ }
+
+ protected:
+ LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
+ UINT32 indexTablesSize;
+ UINT32 numberOfIndexSubtables;
+ UINT32 colorRef;
+ SBitLineMetrics horizontal;
+ SBitLineMetrics vertical;
+ UINT16 startGlyphIndex;
+ UINT16 endGlyphIndex;
+ UINT8 ppemX;
+ UINT8 ppemY;
+ UINT8 bitDepth;
+ INT8 flags;
+
+ public:
+ DEFINE_SIZE_STATIC(48);
+};
+
+
+/*
+ * Glyph Bitmap Data Formats.
+ */
+
+struct GlyphBitmapDataFormat17
+{
+ SmallGlyphMetrics glyphMetrics;
+ UINT32 dataLen;
+ UINT8 dataZ[VAR];
+
+ DEFINE_SIZE_ARRAY(9, dataZ);
+};
+
+
+/*
+ * CBLC -- Color Bitmap Location Table
+ */
+
+#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+
+struct CBLC
+{
+ friend struct CBDT;
+
+ static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ likely (version.major == 2 || version.major == 3) &&
+ sizeTables.sanitize (c, this));
+ }
+
+ protected:
+ const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
+ unsigned int *x_ppem, unsigned int *y_ppem) const
+ {
+ /* TODO: Make it possible to select strike. */
+
+ unsigned int count = sizeTables.len;
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
+ unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
+ if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
+ {
+ *x_ppem = sizeTables[i].ppemX;
+ *y_ppem = sizeTables[i].ppemY;
+ return sizeTables[i].find_table (glyph, this);
+ }
+ }
+
+ return nullptr;
+ }
+
+ protected:
+ FixedVersion<> version;
+ LArrayOf<BitmapSizeTable> sizeTables;
+
+ public:
+ DEFINE_SIZE_ARRAY(8, sizeTables);
+};
+
+/*
+ * CBDT -- Color Bitmap Data Table
+ */
+#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
+
+struct CBDT
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ 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;
+ UINT8 dataZ[VAR];
+
+ public:
+ DEFINE_SIZE_ARRAY(4, dataZ);
+};
+
+} /* namespace OT */
+
+#endif /* HB_OT_CBDT_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh
deleted file mode 100644
index f22824fc699..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-#ifndef HB_OT_CFF_COMMON_HH
-#define HB_OT_CFF_COMMON_HH
-
-#include "hb-open-type.hh"
-#include "hb-bimap.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-cff-interp-dict-common.hh"
-#include "hb-subset-plan.hh"
-
-namespace CFF {
-
-using namespace OT;
-
-#define CFF_UNDEF_CODE 0xFFFFFFFF
-
-using objidx_t = hb_serialize_context_t::objidx_t;
-using whence_t = hb_serialize_context_t::whence_t;
-
-/* utility macro */
-template<typename Type>
-static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset)
-{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
-
-struct code_pair_t
-{
- hb_codepoint_t code;
- hb_codepoint_t glyph;
-};
-
-using str_buff_t = hb_vector_t<unsigned char>;
-using str_buff_vec_t = hb_vector_t<str_buff_t>;
-
-/* CFF INDEX */
-template <typename COUNT>
-struct CFFIndex
-{
- unsigned int offset_array_size () const
- { return offSize * (count + 1); }
-
- CFFIndex *copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- unsigned int size = get_size ();
- CFFIndex *out = c->allocate_size<CFFIndex> (size, false);
- if (likely (out))
- hb_memcpy (out, this, size);
- return_trace (out);
- }
-
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- bool serialize (hb_serialize_context_t *c,
- const Iterable &iterable)
- {
- TRACE_SERIALIZE (this);
- auto it = hb_iter (iterable);
- serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
- for (const auto &_ : +it)
- hb_iter (_).copy (c);
- return_trace (true);
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize_header (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
-
- unsigned total = + it | hb_reduce (hb_add, 0);
- unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
-
- /* serialize CFFIndex header */
- if (unlikely (!c->extend_min (this))) return_trace (false);
- this->count = it.len ();
- if (!this->count) return_trace (true);
- if (unlikely (!c->extend (this->offSize))) return_trace (false);
- this->offSize = off_size;
- if (unlikely (!c->allocate_size<HBUINT8> (off_size * (this->count + 1), false)))
- return_trace (false);
-
- /* serialize indices */
- unsigned int offset = 1;
- unsigned int i = 0;
- for (unsigned _ : +it)
- {
- set_offset_at (i++, offset);
- offset += _;
- }
- set_offset_at (i, offset);
-
- return_trace (true);
- }
-
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- static unsigned total_size (const Iterable &iterable)
- {
- auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
- if (!it) return 0;
-
- unsigned total = + it | hb_reduce (hb_add, 0);
- unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
-
- return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
- }
-
- void set_offset_at (unsigned int index, unsigned int offset)
- {
- assert (index <= count);
- HBUINT8 *p = offsets + offSize * index + offSize;
- unsigned int size = offSize;
- for (; size; size--)
- {
- --p;
- *p = offset & 0xFF;
- offset >>= 8;
- }
- }
-
- private:
- unsigned int offset_at (unsigned int index) const
- {
- assert (index <= count);
-
- unsigned int size = offSize;
- const HBUINT8 *p = offsets + size * index;
- switch (size)
- {
- case 1: return * (HBUINT8 *) p;
- case 2: return * (HBUINT16 *) p;
- case 3: return * (HBUINT24 *) p;
- case 4: return * (HBUINT32 *) p;
- default: return 0;
- }
- }
-
- unsigned int length_at (unsigned int index) const
- {
- unsigned offset0 = offset_at (index);
- unsigned offset1 = offset_at (index + 1);
- if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
- return 0;
- return offset1 - offset0;
- }
-
- const unsigned char *data_base () const
- { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
- public:
-
- hb_ubytes_t operator [] (unsigned int index) const
- {
- if (unlikely (index >= count)) return hb_ubytes_t ();
- _hb_compiler_memory_r_barrier ();
- unsigned length = length_at (index);
- if (unlikely (!length)) return hb_ubytes_t ();
- return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
- }
-
- unsigned int get_size () const
- {
- if (count)
- return min_size + offSize.static_size + offset_array_size () + (offset_at (count) - 1);
- return min_size; /* empty CFFIndex contains count only */
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (count == 0 || /* empty INDEX */
- (count < count + 1u &&
- c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
- c->check_array (offsets, offSize, count + 1u) &&
- c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
- }
-
- public:
- COUNT count; /* Number of object data. Note there are (count+1) offsets */
- private:
- HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
- HBUINT8 offsets[HB_VAR_ARRAY];
- /* The array of (count + 1) offsets into objects array (1-base). */
- /* HBUINT8 data[HB_VAR_ARRAY]; Object data */
- public:
- DEFINE_SIZE_MIN (COUNT::static_size);
-};
-
-template <typename COUNT, typename TYPE>
-struct CFFIndexOf : CFFIndex<COUNT>
-{
- template <typename DATA, typename PARAM1, typename PARAM2>
- bool serialize (hb_serialize_context_t *c,
- unsigned int offSize_,
- const DATA *dataArray,
- unsigned int dataArrayLen,
- const hb_vector_t<unsigned int> &dataSizeArray,
- const PARAM1 &param1,
- const PARAM2 &param2)
- {
- TRACE_SERIALIZE (this);
- /* serialize CFFIndex header */
- if (unlikely (!c->extend_min (this))) return_trace (false);
- this->count = dataArrayLen;
- this->offSize = offSize_;
- if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false)))
- return_trace (false);
-
- /* serialize indices */
- unsigned int offset = 1;
- unsigned int i = 0;
- for (; i < dataArrayLen; i++)
- {
- this->set_offset_at (i, offset);
- offset += dataSizeArray[i];
- }
- this->set_offset_at (i, offset);
-
- /* serialize data */
- for (unsigned int i = 0; i < dataArrayLen; i++)
- {
- TYPE *dest = c->start_embed<TYPE> ();
- if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2)))
- return_trace (false);
- }
- return_trace (true);
- }
-};
-
-/* Top Dict, Font Dict, Private Dict */
-struct Dict : UnsizedByteStr
-{
- template <typename DICTVAL, typename OP_SERIALIZER, typename ...Ts>
- bool serialize (hb_serialize_context_t *c,
- const DICTVAL &dictval,
- OP_SERIALIZER& opszr,
- Ts&&... ds)
- {
- TRACE_SERIALIZE (this);
- for (unsigned int i = 0; i < dictval.get_count (); i++)
- if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...)))
- return_trace (false);
-
- return_trace (true);
- }
-
- template <typename T, typename V>
- static bool serialize_int_op (hb_serialize_context_t *c, op_code_t op, V value, op_code_t intOp)
- {
- if (unlikely ((!serialize_int<T, V> (c, intOp, value))))
- return false;
-
- TRACE_SERIALIZE (this);
- /* serialize the opcode */
- HBUINT8 *p = c->allocate_size<HBUINT8> (OpCode_Size (op), false);
- if (unlikely (!p)) return_trace (false);
- if (Is_OpCode_ESC (op))
- {
- *p = OpCode_escape;
- op = Unmake_OpCode_ESC (op);
- p++;
- }
- *p = op;
- return_trace (true);
- }
-
- template <typename V>
- static bool serialize_int4_op (hb_serialize_context_t *c, op_code_t op, V value)
- { return serialize_int_op<HBINT32> (c, op, value, OpCode_longintdict); }
-
- template <typename V>
- static bool serialize_int2_op (hb_serialize_context_t *c, op_code_t op, V value)
- { return serialize_int_op<HBINT16> (c, op, value, OpCode_shortint); }
-
- template <typename T, int int_op>
- static bool serialize_link_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence)
- {
- T &ofs = *(T *) (c->head + OpCode_Size (int_op));
- if (unlikely (!serialize_int_op<T> (c, op, 0, int_op))) return false;
- c->add_link (ofs, link, whence);
- return true;
- }
-
- static bool serialize_link4_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
- { return serialize_link_op<HBINT32, OpCode_longintdict> (c, op, link, whence); }
-
- static bool serialize_link2_op (hb_serialize_context_t *c, op_code_t op, objidx_t link, whence_t whence = whence_t::Head)
- { return serialize_link_op<HBINT16, OpCode_shortint> (c, op, link, whence); }
-};
-
-struct TopDict : Dict {};
-struct FontDict : Dict {};
-struct PrivateDict : Dict {};
-
-struct table_info_t
-{
- void init () { offset = size = 0; link = 0; }
-
- unsigned int offset;
- unsigned int size;
- objidx_t link;
-};
-
-template <typename COUNT>
-struct FDArray : CFFIndexOf<COUNT, FontDict>
-{
- template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- OP_SERIALIZER& opszr)
- {
- TRACE_SERIALIZE (this);
-
- /* serialize INDEX data */
- hb_vector_t<unsigned> sizes;
- c->push ();
- + it
- | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_)
- {
- FontDict *dict = c->start_embed<FontDict> ();
- dict->serialize (c, _.first, opszr, _.second);
- return c->head - (const char*)dict;
- })
- | hb_sink (sizes)
- ;
- c->pop_pack (false);
-
- /* serialize INDEX header */
- return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes)));
- }
-};
-
-/* FDSelect */
-struct FDSelect0 {
- bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!(c->check_struct (this))))
- return_trace (false);
- if (unlikely (!c->check_array (fds, c->get_num_glyphs ())))
- return_trace (false);
-
- return_trace (true);
- }
-
- hb_codepoint_t get_fd (hb_codepoint_t glyph) const
- { return (hb_codepoint_t) fds[glyph]; }
-
- unsigned int get_size (unsigned int num_glyphs) const
- { return HBUINT8::static_size * num_glyphs; }
-
- HBUINT8 fds[HB_VAR_ARRAY];
-
- DEFINE_SIZE_MIN (0);
-};
-
-template <typename GID_TYPE, typename FD_TYPE>
-struct FDSelect3_4_Range
-{
- bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
- {
- TRACE_SANITIZE (this);
- return_trace (first < c->get_num_glyphs () && (fd < fdcount));
- }
-
- GID_TYPE first;
- FD_TYPE fd;
- public:
- DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
-};
-
-template <typename GID_TYPE, typename FD_TYPE>
-struct FDSelect3_4
-{
- unsigned int get_size () const
- { return GID_TYPE::static_size * 2 + ranges.get_size (); }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this) || !ranges.sanitize (c, nullptr, fdcount) ||
- (nRanges () == 0) || ranges[0].first != 0))
- return_trace (false);
-
- for (unsigned int i = 1; i < nRanges (); i++)
- if (unlikely (ranges[i - 1].first >= ranges[i].first))
- return_trace (false);
-
- if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
- return_trace (false);
-
- return_trace (true);
- }
-
- static int _cmp_range (const void *_key, const void *_item)
- {
- hb_codepoint_t glyph = * (hb_codepoint_t *) _key;
- FDSelect3_4_Range<GID_TYPE, FD_TYPE> *range = (FDSelect3_4_Range<GID_TYPE, FD_TYPE> *) _item;
-
- if (glyph < range[0].first) return -1;
- if (glyph < range[1].first) return 0;
- return +1;
- }
-
- hb_codepoint_t get_fd (hb_codepoint_t glyph) const
- {
- auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
- return range ? range->fd : ranges[nRanges () - 1].fd;
- }
-
- GID_TYPE &nRanges () { return ranges.len; }
- GID_TYPE nRanges () const { return ranges.len; }
- GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
- const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
-
- ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
- /* GID_TYPE sentinel */
-
- DEFINE_SIZE_ARRAY (GID_TYPE::static_size, ranges);
-};
-
-typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
-typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
-
-struct FDSelect
-{
- bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
- {
- TRACE_SERIALIZE (this);
- unsigned int size = src.get_size (num_glyphs);
- FDSelect *dest = c->allocate_size<FDSelect> (size, false);
- if (unlikely (!dest)) return_trace (false);
- hb_memcpy (dest, &src, size);
- return_trace (true);
- }
-
- unsigned int get_size (unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: return format.static_size + u.format0.get_size (num_glyphs);
- case 3: return format.static_size + u.format3.get_size ();
- default:return 0;
- }
- }
-
- hb_codepoint_t get_fd (hb_codepoint_t glyph) const
- {
- if (this == &Null (FDSelect)) return 0;
-
- switch (format)
- {
- case 0: return u.format0.get_fd (glyph);
- case 3: return u.format3.get_fd (glyph);
- default:return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (format)
- {
- case 0: return_trace (u.format0.sanitize (c, fdcount));
- case 3: return_trace (u.format3.sanitize (c, fdcount));
- default:return_trace (false);
- }
- }
-
- HBUINT8 format;
- union {
- FDSelect0 format0;
- FDSelect3 format3;
- } u;
- public:
- DEFINE_SIZE_MIN (1);
-};
-
-template <typename COUNT>
-struct Subrs : CFFIndex<COUNT>
-{
- typedef COUNT count_type;
- typedef CFFIndex<COUNT> SUPER;
-};
-
-} /* namespace CFF */
-
-#endif /* HB_OT_CFF_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh
deleted file mode 100644
index 65d56ae18b5..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright © 2019 Adobe, 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_OT_CFF1_STD_STR_HH
-#if 0 /* Make checks happy. */
-#define HB_OT_CFF1_STD_STR_HH
-#include "hb.hh"
-#endif
-
-_S(".notdef")
-_S("space")
-_S("exclam")
-_S("quotedbl")
-_S("numbersign")
-_S("dollar")
-_S("percent")
-_S("ampersand")
-_S("quoteright")
-_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("quoteleft")
-_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("exclamdown")
-_S("cent")
-_S("sterling")
-_S("fraction")
-_S("yen")
-_S("florin")
-_S("section")
-_S("currency")
-_S("quotesingle")
-_S("quotedblleft")
-_S("guillemotleft")
-_S("guilsinglleft")
-_S("guilsinglright")
-_S("fi")
-_S("fl")
-_S("endash")
-_S("dagger")
-_S("daggerdbl")
-_S("periodcentered")
-_S("paragraph")
-_S("bullet")
-_S("quotesinglbase")
-_S("quotedblbase")
-_S("quotedblright")
-_S("guillemotright")
-_S("ellipsis")
-_S("perthousand")
-_S("questiondown")
-_S("grave")
-_S("acute")
-_S("circumflex")
-_S("tilde")
-_S("macron")
-_S("breve")
-_S("dotaccent")
-_S("dieresis")
-_S("ring")
-_S("cedilla")
-_S("hungarumlaut")
-_S("ogonek")
-_S("caron")
-_S("emdash")
-_S("AE")
-_S("ordfeminine")
-_S("Lslash")
-_S("Oslash")
-_S("OE")
-_S("ordmasculine")
-_S("ae")
-_S("dotlessi")
-_S("lslash")
-_S("oslash")
-_S("oe")
-_S("germandbls")
-_S("onesuperior")
-_S("logicalnot")
-_S("mu")
-_S("trademark")
-_S("Eth")
-_S("onehalf")
-_S("plusminus")
-_S("Thorn")
-_S("onequarter")
-_S("divide")
-_S("brokenbar")
-_S("degree")
-_S("thorn")
-_S("threequarters")
-_S("twosuperior")
-_S("registered")
-_S("minus")
-_S("eth")
-_S("multiply")
-_S("threesuperior")
-_S("copyright")
-_S("Aacute")
-_S("Acircumflex")
-_S("Adieresis")
-_S("Agrave")
-_S("Aring")
-_S("Atilde")
-_S("Ccedilla")
-_S("Eacute")
-_S("Ecircumflex")
-_S("Edieresis")
-_S("Egrave")
-_S("Iacute")
-_S("Icircumflex")
-_S("Idieresis")
-_S("Igrave")
-_S("Ntilde")
-_S("Oacute")
-_S("Ocircumflex")
-_S("Odieresis")
-_S("Ograve")
-_S("Otilde")
-_S("Scaron")
-_S("Uacute")
-_S("Ucircumflex")
-_S("Udieresis")
-_S("Ugrave")
-_S("Yacute")
-_S("Ydieresis")
-_S("Zcaron")
-_S("aacute")
-_S("acircumflex")
-_S("adieresis")
-_S("agrave")
-_S("aring")
-_S("atilde")
-_S("ccedilla")
-_S("eacute")
-_S("ecircumflex")
-_S("edieresis")
-_S("egrave")
-_S("iacute")
-_S("icircumflex")
-_S("idieresis")
-_S("igrave")
-_S("ntilde")
-_S("oacute")
-_S("ocircumflex")
-_S("odieresis")
-_S("ograve")
-_S("otilde")
-_S("scaron")
-_S("uacute")
-_S("ucircumflex")
-_S("udieresis")
-_S("ugrave")
-_S("yacute")
-_S("ydieresis")
-_S("zcaron")
-_S("exclamsmall")
-_S("Hungarumlautsmall")
-_S("dollaroldstyle")
-_S("dollarsuperior")
-_S("ampersandsmall")
-_S("Acutesmall")
-_S("parenleftsuperior")
-_S("parenrightsuperior")
-_S("twodotenleader")
-_S("onedotenleader")
-_S("zerooldstyle")
-_S("oneoldstyle")
-_S("twooldstyle")
-_S("threeoldstyle")
-_S("fouroldstyle")
-_S("fiveoldstyle")
-_S("sixoldstyle")
-_S("sevenoldstyle")
-_S("eightoldstyle")
-_S("nineoldstyle")
-_S("commasuperior")
-_S("threequartersemdash")
-_S("periodsuperior")
-_S("questionsmall")
-_S("asuperior")
-_S("bsuperior")
-_S("centsuperior")
-_S("dsuperior")
-_S("esuperior")
-_S("isuperior")
-_S("lsuperior")
-_S("msuperior")
-_S("nsuperior")
-_S("osuperior")
-_S("rsuperior")
-_S("ssuperior")
-_S("tsuperior")
-_S("ff")
-_S("ffi")
-_S("ffl")
-_S("parenleftinferior")
-_S("parenrightinferior")
-_S("Circumflexsmall")
-_S("hyphensuperior")
-_S("Gravesmall")
-_S("Asmall")
-_S("Bsmall")
-_S("Csmall")
-_S("Dsmall")
-_S("Esmall")
-_S("Fsmall")
-_S("Gsmall")
-_S("Hsmall")
-_S("Ismall")
-_S("Jsmall")
-_S("Ksmall")
-_S("Lsmall")
-_S("Msmall")
-_S("Nsmall")
-_S("Osmall")
-_S("Psmall")
-_S("Qsmall")
-_S("Rsmall")
-_S("Ssmall")
-_S("Tsmall")
-_S("Usmall")
-_S("Vsmall")
-_S("Wsmall")
-_S("Xsmall")
-_S("Ysmall")
-_S("Zsmall")
-_S("colonmonetary")
-_S("onefitted")
-_S("rupiah")
-_S("Tildesmall")
-_S("exclamdownsmall")
-_S("centoldstyle")
-_S("Lslashsmall")
-_S("Scaronsmall")
-_S("Zcaronsmall")
-_S("Dieresissmall")
-_S("Brevesmall")
-_S("Caronsmall")
-_S("Dotaccentsmall")
-_S("Macronsmall")
-_S("figuredash")
-_S("hypheninferior")
-_S("Ogoneksmall")
-_S("Ringsmall")
-_S("Cedillasmall")
-_S("questiondownsmall")
-_S("oneeighth")
-_S("threeeighths")
-_S("fiveeighths")
-_S("seveneighths")
-_S("onethird")
-_S("twothirds")
-_S("zerosuperior")
-_S("foursuperior")
-_S("fivesuperior")
-_S("sixsuperior")
-_S("sevensuperior")
-_S("eightsuperior")
-_S("ninesuperior")
-_S("zeroinferior")
-_S("oneinferior")
-_S("twoinferior")
-_S("threeinferior")
-_S("fourinferior")
-_S("fiveinferior")
-_S("sixinferior")
-_S("seveninferior")
-_S("eightinferior")
-_S("nineinferior")
-_S("centinferior")
-_S("dollarinferior")
-_S("periodinferior")
-_S("commainferior")
-_S("Agravesmall")
-_S("Aacutesmall")
-_S("Acircumflexsmall")
-_S("Atildesmall")
-_S("Adieresissmall")
-_S("Aringsmall")
-_S("AEsmall")
-_S("Ccedillasmall")
-_S("Egravesmall")
-_S("Eacutesmall")
-_S("Ecircumflexsmall")
-_S("Edieresissmall")
-_S("Igravesmall")
-_S("Iacutesmall")
-_S("Icircumflexsmall")
-_S("Idieresissmall")
-_S("Ethsmall")
-_S("Ntildesmall")
-_S("Ogravesmall")
-_S("Oacutesmall")
-_S("Ocircumflexsmall")
-_S("Otildesmall")
-_S("Odieresissmall")
-_S("OEsmall")
-_S("Oslashsmall")
-_S("Ugravesmall")
-_S("Uacutesmall")
-_S("Ucircumflexsmall")
-_S("Udieresissmall")
-_S("Yacutesmall")
-_S("Thornsmall")
-_S("Ydieresissmall")
-_S("001.000")
-_S("001.001")
-_S("001.002")
-_S("001.003")
-_S("Black")
-_S("Bold")
-_S("Book")
-_S("Light")
-_S("Medium")
-_S("Regular")
-_S("Roman")
-_S("Semibold")
-
-#endif /* HB_OT_CFF1_STD_STR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc
deleted file mode 100644
index 5040c746234..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.cc
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_CFF
-
-#include "hb-draw.hh"
-#include "hb-algs.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-cff1-interp-cs.hh"
-
-using namespace CFF;
-
-struct sid_to_gid_t
-{
- uint16_t sid;
- uint8_t gid;
-
- int cmp (uint16_t a) const
- {
- if (a == sid) return 0;
- return (a < sid) ? -1 : 1;
- }
-};
-
-/* SID to code */
-static const uint8_t standard_encoding_to_code [] =
-{
- 0, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
- 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177,
- 178, 179, 180, 182, 183, 184, 185, 186, 187, 188, 189, 191, 193, 194, 195, 196,
- 197, 198, 199, 200, 202, 203, 205, 206, 207, 208, 225, 227, 232, 233, 234, 235,
- 241, 245, 248, 249, 250, 251
-};
-
-/* SID to code */
-static const uint8_t expert_encoding_to_code [] =
-{
- 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 45, 46,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 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,
- 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, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 88, 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, 0, 0, 0, 0, 201, 0, 0, 0, 0, 189, 0, 0, 188, 0,
- 0, 0, 0, 190, 202, 0, 0, 0, 0, 203, 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, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 63, 65, 66, 67,
- 68, 69, 73, 76, 77, 78, 79, 82, 83, 84, 86, 89, 90, 91, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
- 161, 162, 163, 166, 167, 168, 169, 170, 172, 175, 178, 179, 182, 183, 184, 191,
- 192, 193, 194, 195, 196, 197, 200, 204, 205, 206, 207, 208, 209, 210, 211, 212,
- 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
- 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
- 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
-};
-
-/* glyph ID to SID */
-static const uint16_t expert_charset_to_sid [] =
-{
- 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99,
- 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 252,
- 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110,
- 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282,
- 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
- 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
- 315, 316, 317, 318, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, 326, 150,
- 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
- 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,
- 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
- 373, 374, 375, 376, 377, 378
-};
-
-/* glyph ID to SID */
-static const uint16_t expert_subset_charset_to_sid [] =
-{
- 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242,
- 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, 256, 257,
- 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272,
- 300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, 323, 324, 325, 326,
- 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
- 340, 341, 342, 343, 344, 345, 346
-};
-
-/* SID to glyph ID */
-static const sid_to_gid_t expert_charset_sid_to_gid [] =
-{
- { 1, 1 }, { 13, 12 }, { 14, 13 }, { 15, 14 },
- { 27, 26 }, { 28, 27 }, { 99, 15 }, { 109, 46 },
- { 110, 47 }, { 150, 111 }, { 155, 101 }, { 158, 100 },
- { 163, 102 }, { 164, 112 }, { 169, 113 }, { 229, 2 },
- { 230, 3 }, { 231, 4 }, { 232, 5 }, { 233, 6 },
- { 234, 7 }, { 235, 8 }, { 236, 9 }, { 237, 10 },
- { 238, 11 }, { 239, 16 }, { 240, 17 }, { 241, 18 },
- { 242, 19 }, { 243, 20 }, { 244, 21 }, { 245, 22 },
- { 246, 23 }, { 247, 24 }, { 248, 25 }, { 249, 28 },
- { 250, 29 }, { 251, 30 }, { 252, 31 }, { 253, 32 },
- { 254, 33 }, { 255, 34 }, { 256, 35 }, { 257, 36 },
- { 258, 37 }, { 259, 38 }, { 260, 39 }, { 261, 40 },
- { 262, 41 }, { 263, 42 }, { 264, 43 }, { 265, 44 },
- { 266, 45 }, { 267, 48 }, { 268, 49 }, { 269, 50 },
- { 270, 51 }, { 271, 52 }, { 272, 53 }, { 273, 54 },
- { 274, 55 }, { 275, 56 }, { 276, 57 }, { 277, 58 },
- { 278, 59 }, { 279, 60 }, { 280, 61 }, { 281, 62 },
- { 282, 63 }, { 283, 64 }, { 284, 65 }, { 285, 66 },
- { 286, 67 }, { 287, 68 }, { 288, 69 }, { 289, 70 },
- { 290, 71 }, { 291, 72 }, { 292, 73 }, { 293, 74 },
- { 294, 75 }, { 295, 76 }, { 296, 77 }, { 297, 78 },
- { 298, 79 }, { 299, 80 }, { 300, 81 }, { 301, 82 },
- { 302, 83 }, { 303, 84 }, { 304, 85 }, { 305, 86 },
- { 306, 87 }, { 307, 88 }, { 308, 89 }, { 309, 90 },
- { 310, 91 }, { 311, 92 }, { 312, 93 }, { 313, 94 },
- { 314, 95 }, { 315, 96 }, { 316, 97 }, { 317, 98 },
- { 318, 99 }, { 319, 103 }, { 320, 104 }, { 321, 105 },
- { 322, 106 }, { 323, 107 }, { 324, 108 }, { 325, 109 },
- { 326, 110 }, { 327, 114 }, { 328, 115 }, { 329, 116 },
- { 330, 117 }, { 331, 118 }, { 332, 119 }, { 333, 120 },
- { 334, 121 }, { 335, 122 }, { 336, 123 }, { 337, 124 },
- { 338, 125 }, { 339, 126 }, { 340, 127 }, { 341, 128 },
- { 342, 129 }, { 343, 130 }, { 344, 131 }, { 345, 132 },
- { 346, 133 }, { 347, 134 }, { 348, 135 }, { 349, 136 },
- { 350, 137 }, { 351, 138 }, { 352, 139 }, { 353, 140 },
- { 354, 141 }, { 355, 142 }, { 356, 143 }, { 357, 144 },
- { 358, 145 }, { 359, 146 }, { 360, 147 }, { 361, 148 },
- { 362, 149 }, { 363, 150 }, { 364, 151 }, { 365, 152 },
- { 366, 153 }, { 367, 154 }, { 368, 155 }, { 369, 156 },
- { 370, 157 }, { 371, 158 }, { 372, 159 }, { 373, 160 },
- { 374, 161 }, { 375, 162 }, { 376, 163 }, { 377, 164 },
- { 378, 165 }
-};
-
-/* SID to glyph ID */
-static const sid_to_gid_t expert_subset_charset_sid_to_gid [] =
-{
- { 1, 1 }, { 13, 8 }, { 14, 9 }, { 15, 10 },
- { 27, 22 }, { 28, 23 }, { 99, 11 }, { 109, 41 },
- { 110, 42 }, { 150, 64 }, { 155, 55 }, { 158, 54 },
- { 163, 56 }, { 164, 65 }, { 169, 66 }, { 231, 2 },
- { 232, 3 }, { 235, 4 }, { 236, 5 }, { 237, 6 },
- { 238, 7 }, { 239, 12 }, { 240, 13 }, { 241, 14 },
- { 242, 15 }, { 243, 16 }, { 244, 17 }, { 245, 18 },
- { 246, 19 }, { 247, 20 }, { 248, 21 }, { 249, 24 },
- { 250, 25 }, { 251, 26 }, { 253, 27 }, { 254, 28 },
- { 255, 29 }, { 256, 30 }, { 257, 31 }, { 258, 32 },
- { 259, 33 }, { 260, 34 }, { 261, 35 }, { 262, 36 },
- { 263, 37 }, { 264, 38 }, { 265, 39 }, { 266, 40 },
- { 267, 43 }, { 268, 44 }, { 269, 45 }, { 270, 46 },
- { 272, 47 }, { 300, 48 }, { 301, 49 }, { 302, 50 },
- { 305, 51 }, { 314, 52 }, { 315, 53 }, { 320, 57 },
- { 321, 58 }, { 322, 59 }, { 323, 60 }, { 324, 61 },
- { 325, 62 }, { 326, 63 }, { 327, 67 }, { 328, 68 },
- { 329, 69 }, { 330, 70 }, { 331, 71 }, { 332, 72 },
- { 333, 73 }, { 334, 74 }, { 335, 75 }, { 336, 76 },
- { 337, 77 }, { 338, 78 }, { 339, 79 }, { 340, 80 },
- { 341, 81 }, { 342, 82 }, { 343, 83 }, { 344, 84 },
- { 345, 85 }, { 346, 86 }
-};
-
-/* code to SID */
-static const uint8_t standard_encoding_to_sid [] =
-{
- 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,
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 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, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123,
- 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136,
- 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0,
- 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0
-};
-
-hb_codepoint_t OT::cff1::lookup_standard_encoding_for_code (hb_codepoint_t sid)
-{
- if (sid < ARRAY_LENGTH (standard_encoding_to_code))
- return (hb_codepoint_t)standard_encoding_to_code[sid];
- else
- return 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_expert_encoding_for_code (hb_codepoint_t sid)
-{
- if (sid < ARRAY_LENGTH (expert_encoding_to_code))
- return (hb_codepoint_t)expert_encoding_to_code[sid];
- else
- return 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_expert_charset_for_sid (hb_codepoint_t glyph)
-{
- if (glyph < ARRAY_LENGTH (expert_charset_to_sid))
- return (hb_codepoint_t)expert_charset_to_sid[glyph];
- else
- return 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph)
-{
- if (glyph < ARRAY_LENGTH (expert_subset_charset_to_sid))
- return (hb_codepoint_t)expert_subset_charset_to_sid[glyph];
- else
- return 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_expert_charset_for_glyph (hb_codepoint_t sid)
-{
- const auto *pair = hb_sorted_array (expert_charset_sid_to_gid).bsearch (sid);
- return pair ? pair->gid : 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid)
-{
- const auto *pair = hb_sorted_array (expert_subset_charset_sid_to_gid).bsearch (sid);
- return pair ? pair->gid : 0;
-}
-
-hb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code)
-{
- if (code < ARRAY_LENGTH (standard_encoding_to_sid))
- return (hb_codepoint_t)standard_encoding_to_sid[code];
- else
- return CFF_UNDEF_SID;
-}
-
-struct bounds_t
-{
- void init ()
- {
- min.set_int (INT_MAX, INT_MAX);
- max.set_int (INT_MIN, INT_MIN);
- }
-
- void update (const point_t &pt)
- {
- if (pt.x < min.x) min.x = pt.x;
- if (pt.x > max.x) max.x = pt.x;
- if (pt.y < min.y) min.y = pt.y;
- if (pt.y > max.y) max.y = pt.y;
- }
-
- void merge (const bounds_t &b)
- {
- if (empty ())
- *this = b;
- else if (!b.empty ())
- {
- if (b.min.x < min.x) min.x = b.min.x;
- if (b.max.x > max.x) max.x = b.max.x;
- if (b.min.y < min.y) min.y = b.min.y;
- if (b.max.y > max.y) max.y = b.max.y;
- }
- }
-
- void offset (const point_t &delta)
- {
- if (!empty ())
- {
- min.move (delta);
- max.move (delta);
- }
- }
-
- bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
-
- point_t min;
- point_t max;
-};
-
-struct cff1_extents_param_t
-{
- cff1_extents_param_t (const OT::cff1::accelerator_t *_cff) : cff (_cff)
- {
- bounds.init ();
- }
-
- void start_path () { path_open = true; }
- void end_path () { path_open = false; }
- bool is_path_open () const { return path_open; }
-
- bool path_open = false;
- bounds_t bounds;
-
- const OT::cff1::accelerator_t *cff;
-};
-
-struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, cff1_extents_param_t>
-{
- static void moveto (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt)
- {
- param.end_path ();
- env.moveto (pt);
- }
-
- static void line (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1)
- {
- if (!param.is_path_open ())
- {
- param.start_path ();
- param.bounds.update (env.get_pt ());
- }
- env.moveto (pt1);
- param.bounds.update (env.get_pt ());
- }
-
- static void curve (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
- {
- if (!param.is_path_open ())
- {
- param.start_path ();
- param.bounds.update (env.get_pt ());
- }
- /* include control points */
- param.bounds.update (pt1);
- param.bounds.update (pt2);
- env.moveto (pt3);
- param.bounds.update (env.get_pt ());
- }
-};
-
-static bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
-
-struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, cff1_extents_param_t, cff1_path_procs_extents_t>
-{
- static void process_seac (cff1_cs_interp_env_t &env, cff1_extents_param_t& param)
- {
- unsigned int n = env.argStack.get_count ();
- point_t delta;
- delta.x = env.argStack[n-4];
- delta.y = env.argStack[n-3];
- hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
- hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
-
- bounds_t base_bounds, accent_bounds;
- if (likely (!env.in_seac && base && accent
- && _get_bounds (param.cff, base, base_bounds, true)
- && _get_bounds (param.cff, accent, accent_bounds, true)))
- {
- param.bounds.merge (base_bounds);
- accent_bounds.offset (delta);
- param.bounds.merge (accent_bounds);
- }
- else
- env.set_error ();
- }
-};
-
-bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac)
-{
- bounds.init ();
- if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
-
- unsigned int fd = cff->fdSelect->get_fd (glyph);
- const hb_ubytes_t str = (*cff->charStrings)[glyph];
- cff1_cs_interp_env_t env (str, *cff, fd);
- env.set_in_seac (in_seac);
- cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp (env);
- cff1_extents_param_t param (cff);
- if (unlikely (!interp.interpret (param))) return false;
- bounds = param.bounds;
- return true;
-}
-
-bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
-{
-#ifdef HB_NO_OT_FONT_CFF
- /* XXX Remove check when this code moves to .hh file. */
- return true;
-#endif
-
- bounds_t bounds;
-
- if (!_get_bounds (this, glyph, bounds))
- return false;
-
- if (bounds.min.x >= bounds.max.x)
- {
- extents->width = 0;
- extents->x_bearing = 0;
- }
- else
- {
- extents->x_bearing = roundf (bounds.min.x.to_real ());
- extents->width = roundf (bounds.max.x.to_real () - extents->x_bearing);
- }
- if (bounds.min.y >= bounds.max.y)
- {
- extents->height = 0;
- extents->y_bearing = 0;
- }
- else
- {
- extents->y_bearing = roundf (bounds.max.y.to_real ());
- extents->height = roundf (bounds.min.y.to_real () - extents->y_bearing);
- }
-
- font->scale_glyph_extents (extents);
-
- return true;
-}
-
-struct cff1_path_param_t
-{
- cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
- hb_draw_session_t &draw_session_, point_t *delta_)
- {
- draw_session = &draw_session_;
- cff = cff_;
- font = font_;
- delta = delta_;
- }
-
- void move_to (const point_t &p)
- {
- point_t point = p;
- if (delta) point.move (*delta);
- draw_session->move_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
- }
-
- void line_to (const point_t &p)
- {
- point_t point = p;
- if (delta) point.move (*delta);
- draw_session->line_to (font->em_fscalef_x (point.x.to_real ()), font->em_fscalef_y (point.y.to_real ()));
- }
-
- void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
- {
- point_t point1 = p1, point2 = p2, point3 = p3;
- if (delta)
- {
- point1.move (*delta);
- point2.move (*delta);
- point3.move (*delta);
- }
- draw_session->cubic_to (font->em_fscalef_x (point1.x.to_real ()), font->em_fscalef_y (point1.y.to_real ()),
- font->em_fscalef_x (point2.x.to_real ()), font->em_fscalef_y (point2.y.to_real ()),
- font->em_fscalef_x (point3.x.to_real ()), font->em_fscalef_y (point3.y.to_real ()));
- }
-
- void end_path () { draw_session->close_path (); }
-
- hb_font_t *font;
- hb_draw_session_t *draw_session;
- point_t *delta;
-
- const OT::cff1::accelerator_t *cff;
-};
-
-struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_interp_env_t, cff1_path_param_t>
-{
- static void moveto (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt)
- {
- param.move_to (pt);
- env.moveto (pt);
- }
-
- static void line (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1)
- {
- param.line_to (pt1);
- env.moveto (pt1);
- }
-
- static void curve (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
- {
- param.cubic_to (pt1, pt2, pt3);
- env.moveto (pt3);
- }
-};
-
-static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
- hb_draw_session_t &draw_session, bool in_seac = false, point_t *delta = nullptr);
-
-struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
-{
- static void process_seac (cff1_cs_interp_env_t &env, cff1_path_param_t& param)
- {
- /* End previous path */
- param.end_path ();
-
- unsigned int n = env.argStack.get_count ();
- point_t delta;
- delta.x = env.argStack[n-4];
- delta.y = env.argStack[n-3];
- hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
- hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
-
- if (unlikely (!(!env.in_seac && base && accent
- && _get_path (param.cff, param.font, base, *param.draw_session, true)
- && _get_path (param.cff, param.font, accent, *param.draw_session, true, &delta))))
- env.set_error ();
- }
-};
-
-bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
- hb_draw_session_t &draw_session, bool in_seac, point_t *delta)
-{
- if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
-
- unsigned int fd = cff->fdSelect->get_fd (glyph);
- const hb_ubytes_t str = (*cff->charStrings)[glyph];
- cff1_cs_interp_env_t env (str, *cff, fd);
- env.set_in_seac (in_seac);
- cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp (env);
- cff1_path_param_t param (cff, font, draw_session, delta);
- if (unlikely (!interp.interpret (param))) return false;
-
- /* Let's end the path specially since it is called inside seac also */
- param.end_path ();
-
- return true;
-}
-
-bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
-{
- funcs->push_clip_glyph (data, glyph, font);
- funcs->color (data, true, foreground);
- funcs->pop_clip (data);
-
- return true;
-}
-
-bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
-{
-#ifdef HB_NO_OT_FONT_CFF
- /* XXX Remove check when this code moves to .hh file. */
- return true;
-#endif
-
- return _get_path (this, font, glyph, draw_session);
-}
-
-struct get_seac_param_t
-{
- get_seac_param_t (const OT::cff1::accelerator_t *_cff) : cff (_cff) {}
-
- bool has_seac () const { return base && accent; }
-
- const OT::cff1::accelerator_t *cff;
- hb_codepoint_t base = 0;
- hb_codepoint_t accent = 0;
-};
-
-struct cff1_cs_opset_seac_t : cff1_cs_opset_t<cff1_cs_opset_seac_t, get_seac_param_t>
-{
- static void process_seac (cff1_cs_interp_env_t &env, get_seac_param_t& param)
- {
- unsigned int n = env.argStack.get_count ();
- hb_codepoint_t base_char = (hb_codepoint_t)env.argStack[n-2].to_int ();
- hb_codepoint_t accent_char = (hb_codepoint_t)env.argStack[n-1].to_int ();
-
- param.base = param.cff->std_code_to_glyph (base_char);
- param.accent = param.cff->std_code_to_glyph (accent_char);
- }
-};
-
-bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
-{
- if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
-
- unsigned int fd = fdSelect->get_fd (glyph);
- const hb_ubytes_t str = (*charStrings)[glyph];
- cff1_cs_interp_env_t env (str, *this, fd);
- cff1_cs_interpreter_t<cff1_cs_opset_seac_t, get_seac_param_t> interp (env);
- get_seac_param_t param (this);
- if (unlikely (!interp.interpret (param))) return false;
-
- if (param.has_seac ())
- {
- *base = param.base;
- *accent = param.accent;
- return true;
- }
- return false;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh
deleted file mode 100644
index f461a230449..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh
+++ /dev/null
@@ -1,1484 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_OT_CFF1_TABLE_HH
-#define HB_OT_CFF1_TABLE_HH
-
-#include "hb-ot-cff-common.hh"
-#include "hb-subset-cff1.hh"
-#include "hb-draw.hh"
-#include "hb-paint.hh"
-
-#define HB_STRING_ARRAY_NAME cff1_std_strings
-#define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh"
-#include "hb-string-array.hh"
-#undef HB_STRING_ARRAY_LIST
-#undef HB_STRING_ARRAY_NAME
-
-namespace CFF {
-
-/*
- * CFF -- Compact Font Format (CFF)
- * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
- */
-#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
-
-#define CFF_UNDEF_SID CFF_UNDEF_CODE
-
-enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 };
-enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 };
-
-typedef CFFIndex<HBUINT16> CFF1Index;
-template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {};
-
-typedef CFFIndex<HBUINT16> CFF1Index;
-typedef CFF1Index CFF1CharStrings;
-typedef Subrs<HBUINT16> CFF1Subrs;
-
-struct CFF1FDSelect : FDSelect {};
-
-/* Encoding */
-struct Encoding0 {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (codes.sanitize (c));
- }
-
- hb_codepoint_t get_code (hb_codepoint_t glyph) const
- {
- assert (glyph > 0);
- glyph--;
- if (glyph < nCodes ())
- {
- return (hb_codepoint_t)codes[glyph];
- }
- else
- return CFF_UNDEF_CODE;
- }
-
- HBUINT8 &nCodes () { return codes.len; }
- HBUINT8 nCodes () const { return codes.len; }
-
- ArrayOf<HBUINT8, HBUINT8> codes;
-
- DEFINE_SIZE_ARRAY_SIZED (1, codes);
-};
-
-struct Encoding1_Range {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT8 first;
- HBUINT8 nLeft;
-
- DEFINE_SIZE_STATIC (2);
-};
-
-struct Encoding1 {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (ranges.sanitize (c));
- }
-
- hb_codepoint_t get_code (hb_codepoint_t glyph) const
- {
- assert (glyph > 0);
- glyph--;
- for (unsigned int i = 0; i < nRanges (); i++)
- {
- if (glyph <= ranges[i].nLeft)
- {
- hb_codepoint_t code = (hb_codepoint_t) ranges[i].first + glyph;
- return (likely (code < 0x100) ? code: CFF_UNDEF_CODE);
- }
- glyph -= (ranges[i].nLeft + 1);
- }
- return CFF_UNDEF_CODE;
- }
-
- HBUINT8 &nRanges () { return ranges.len; }
- HBUINT8 nRanges () const { return ranges.len; }
-
- ArrayOf<Encoding1_Range, HBUINT8> ranges;
-
- DEFINE_SIZE_ARRAY_SIZED (1, ranges);
-};
-
-struct SuppEncoding {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT8 code;
- HBUINT16 glyph;
-
- DEFINE_SIZE_STATIC (3);
-};
-
-struct CFF1SuppEncData {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (supps.sanitize (c));
- }
-
- void get_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
- {
- for (unsigned int i = 0; i < nSups (); i++)
- if (sid == supps[i].glyph)
- codes.push (supps[i].code);
- }
-
- HBUINT8 &nSups () { return supps.len; }
- HBUINT8 nSups () const { return supps.len; }
-
- ArrayOf<SuppEncoding, HBUINT8> supps;
-
- DEFINE_SIZE_ARRAY_SIZED (1, supps);
-};
-
-struct Encoding
-{
- /* serialize a fullset Encoding */
- bool serialize (hb_serialize_context_t *c, const Encoding &src)
- {
- TRACE_SERIALIZE (this);
- unsigned int size = src.get_size ();
- Encoding *dest = c->allocate_size<Encoding> (size);
- if (unlikely (!dest)) return_trace (false);
- hb_memcpy (dest, &src, size);
- return_trace (true);
- }
-
- /* serialize a subset Encoding */
- bool serialize (hb_serialize_context_t *c,
- uint8_t format,
- unsigned int enc_count,
- const hb_vector_t<code_pair_t>& code_ranges,
- const hb_vector_t<code_pair_t>& supp_codes)
- {
- TRACE_SERIALIZE (this);
- Encoding *dest = c->extend_min (this);
- if (unlikely (!dest)) return_trace (false);
- dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0);
- switch (format) {
- case 0:
- {
- Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
- if (unlikely (!fmt0)) return_trace (false);
- fmt0->nCodes () = enc_count;
- unsigned int glyph = 0;
- for (unsigned int i = 0; i < code_ranges.length; i++)
- {
- hb_codepoint_t code = code_ranges[i].code;
- for (int left = (int)code_ranges[i].glyph; left >= 0; left--)
- fmt0->codes[glyph++] = code++;
- if (unlikely (!((glyph <= 0x100) && (code <= 0x100))))
- return_trace (false);
- }
- }
- break;
-
- case 1:
- {
- Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
- if (unlikely (!fmt1)) return_trace (false);
- fmt1->nRanges () = code_ranges.length;
- for (unsigned int i = 0; i < code_ranges.length; i++)
- {
- if (unlikely (!((code_ranges[i].code <= 0xFF) && (code_ranges[i].glyph <= 0xFF))))
- return_trace (false);
- fmt1->ranges[i].first = code_ranges[i].code;
- fmt1->ranges[i].nLeft = code_ranges[i].glyph;
- }
- }
- break;
-
- }
-
- if (supp_codes.length)
- {
- CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
- if (unlikely (!suppData)) return_trace (false);
- suppData->nSups () = supp_codes.length;
- for (unsigned int i = 0; i < supp_codes.length; i++)
- {
- suppData->supps[i].code = supp_codes[i].code;
- suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
- }
- }
-
- return_trace (true);
- }
-
- unsigned int get_size () const
- {
- unsigned int size = min_size;
- switch (table_format ())
- {
- case 0: size += u.format0.get_size (); break;
- case 1: size += u.format1.get_size (); break;
- }
- if (has_supplement ())
- size += suppEncData ().get_size ();
- return size;
- }
-
- hb_codepoint_t get_code (hb_codepoint_t glyph) const
- {
- switch (table_format ())
- {
- case 0: return u.format0.get_code (glyph);
- case 1: return u.format1.get_code (glyph);
- default:return 0;
- }
- }
-
- uint8_t table_format () const { return format & 0x7F; }
- bool has_supplement () const { return format & 0x80; }
-
- void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
- {
- codes.resize (0);
- if (has_supplement ())
- suppEncData().get_codes (sid, codes);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (table_format ())
- {
- case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break;
- case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break;
- default:return_trace (false);
- }
- return_trace (likely (!has_supplement () || suppEncData ().sanitize (c)));
- }
-
- protected:
- const CFF1SuppEncData &suppEncData () const
- {
- switch (table_format ())
- {
- case 0: return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
- case 1: return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
- default:return Null (CFF1SuppEncData);
- }
- }
-
- public:
- HBUINT8 format;
- union {
- Encoding0 format0;
- Encoding1 format1;
- } u;
- /* CFF1SuppEncData suppEncData; */
-
- DEFINE_SIZE_MIN (1);
-};
-
-/* Charset */
-struct Charset0 {
- bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c));
- }
-
- hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
- {
- if (unlikely (glyph >= num_glyphs)) return 0;
- if (glyph == 0)
- return 0;
- else
- return sids[glyph - 1];
- }
-
- void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
- {
- for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++)
- mapping->set (gid, sids[gid - 1]);
- }
-
- hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
- {
- if (sid == 0)
- return 0;
-
- for (unsigned int glyph = 1; glyph < num_glyphs; glyph++)
- {
- if (sids[glyph-1] == sid)
- return glyph;
- }
- return 0;
- }
-
- unsigned int get_size (unsigned int num_glyphs) const
- {
- assert (num_glyphs > 0);
- return HBUINT16::static_size * (num_glyphs - 1);
- }
-
- HBUINT16 sids[HB_VAR_ARRAY];
-
- DEFINE_SIZE_ARRAY(0, sids);
-};
-
-template <typename TYPE>
-struct Charset_Range {
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 first;
- TYPE nLeft;
-
- DEFINE_SIZE_STATIC (HBUINT16::static_size + TYPE::static_size);
-};
-
-template <typename TYPE>
-struct Charset1_2 {
- bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
- num_glyphs--;
- for (unsigned int i = 0; num_glyphs > 0; i++)
- {
- if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1)))
- return_trace (false);
- num_glyphs -= (ranges[i].nLeft + 1);
- }
- return_trace (true);
- }
-
- hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
- {
- if (unlikely (glyph >= num_glyphs)) return 0;
- if (glyph == 0) return 0;
- glyph--;
- for (unsigned int i = 0;; i++)
- {
- if (glyph <= ranges[i].nLeft)
- return (hb_codepoint_t) ranges[i].first + glyph;
- glyph -= (ranges[i].nLeft + 1);
- }
-
- return 0;
- }
-
- void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
- {
- hb_codepoint_t gid = 1;
- if (gid >= num_glyphs)
- return;
- for (unsigned i = 0;; i++)
- {
- hb_codepoint_t sid = ranges[i].first;
- unsigned count = ranges[i].nLeft + 1;
- for (unsigned j = 0; j < count; j++)
- mapping->set (gid++, sid++);
-
- if (gid >= num_glyphs)
- break;
- }
- }
-
- hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
- {
- if (sid == 0) return 0;
- hb_codepoint_t glyph = 1;
- for (unsigned int i = 0;; i++)
- {
- if (glyph >= num_glyphs)
- return 0;
- if ((ranges[i].first <= sid) && (sid <= ranges[i].first + ranges[i].nLeft))
- return glyph + (sid - ranges[i].first);
- glyph += (ranges[i].nLeft + 1);
- }
-
- return 0;
- }
-
- unsigned int get_size (unsigned int num_glyphs) const
- {
- unsigned int size = HBUINT8::static_size;
- int glyph = (int)num_glyphs;
-
- assert (glyph > 0);
- glyph--;
- for (unsigned int i = 0; glyph > 0; i++)
- {
- glyph -= (ranges[i].nLeft + 1);
- size += Charset_Range<TYPE>::static_size;
- }
-
- return size;
- }
-
- Charset_Range<TYPE> ranges[HB_VAR_ARRAY];
-
- DEFINE_SIZE_ARRAY (0, ranges);
-};
-
-typedef Charset1_2<HBUINT8> Charset1;
-typedef Charset1_2<HBUINT16> Charset2;
-typedef Charset_Range<HBUINT8> Charset1_Range;
-typedef Charset_Range<HBUINT16> Charset2_Range;
-
-struct Charset
-{
- /* serialize a fullset Charset */
- bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
- {
- TRACE_SERIALIZE (this);
- unsigned int size = src.get_size (num_glyphs);
- Charset *dest = c->allocate_size<Charset> (size);
- if (unlikely (!dest)) return_trace (false);
- hb_memcpy (dest, &src, size);
- return_trace (true);
- }
-
- /* serialize a subset Charset */
- bool serialize (hb_serialize_context_t *c,
- uint8_t format,
- unsigned int num_glyphs,
- const hb_vector_t<code_pair_t>& sid_ranges)
- {
- TRACE_SERIALIZE (this);
- Charset *dest = c->extend_min (this);
- if (unlikely (!dest)) return_trace (false);
- dest->format = format;
- switch (format)
- {
- case 0:
- {
- Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
- if (unlikely (!fmt0)) return_trace (false);
- unsigned int glyph = 0;
- for (unsigned int i = 0; i < sid_ranges.length; i++)
- {
- hb_codepoint_t sid = sid_ranges[i].code;
- for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
- fmt0->sids[glyph++] = sid++;
- }
- }
- break;
-
- case 1:
- {
- Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
- if (unlikely (!fmt1)) return_trace (false);
- for (unsigned int i = 0; i < sid_ranges.length; i++)
- {
- if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
- return_trace (false);
- fmt1->ranges[i].first = sid_ranges[i].code;
- fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
- }
- }
- break;
-
- case 2:
- {
- Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
- if (unlikely (!fmt2)) return_trace (false);
- for (unsigned int i = 0; i < sid_ranges.length; i++)
- {
- if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
- return_trace (false);
- fmt2->ranges[i].first = sid_ranges[i].code;
- fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
- }
- }
- break;
-
- }
- return_trace (true);
- }
-
- unsigned int get_size (unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: return min_size + u.format0.get_size (num_glyphs);
- case 1: return min_size + u.format1.get_size (num_glyphs);
- case 2: return min_size + u.format2.get_size (num_glyphs);
- default:return 0;
- }
- }
-
- hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: return u.format0.get_sid (glyph, num_glyphs);
- case 1: return u.format1.get_sid (glyph, num_glyphs);
- case 2: return u.format2.get_sid (glyph, num_glyphs);
- default:return 0;
- }
- }
-
- void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: u.format0.collect_glyph_to_sid_map (mapping, num_glyphs); return;
- case 1: u.format1.collect_glyph_to_sid_map (mapping, num_glyphs); return;
- case 2: u.format2.collect_glyph_to_sid_map (mapping, num_glyphs); return;
- default:return;
- }
- }
-
- hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: return u.format0.get_glyph (sid, num_glyphs);
- case 1: return u.format1.get_glyph (sid, num_glyphs);
- case 2: return u.format2.get_glyph (sid, num_glyphs);
- default:return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (format)
- {
- case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
- case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
- case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
- default:return_trace (false);
- }
- }
-
- HBUINT8 format;
- union {
- Charset0 format0;
- Charset1 format1;
- Charset2 format2;
- } u;
-
- DEFINE_SIZE_MIN (1);
-};
-
-struct CFF1StringIndex : CFF1Index
-{
- bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
- const hb_inc_bimap_t &sidmap)
- {
- TRACE_SERIALIZE (this);
- if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
- {
- if (unlikely (!c->extend_min (this->count)))
- return_trace (false);
- count = 0;
- return_trace (true);
- }
-
- byte_str_array_t bytesArray;
- if (!bytesArray.resize (sidmap.get_population ()))
- return_trace (false);
- for (unsigned int i = 0; i < strings.count; i++)
- {
- hb_codepoint_t j = sidmap[i];
- if (j != HB_MAP_VALUE_INVALID)
- bytesArray[j] = strings[i];
- }
-
- bool result = CFF1Index::serialize (c, bytesArray);
- return_trace (result);
- }
-};
-
-struct cff1_top_dict_interp_env_t : num_interp_env_t
-{
- cff1_top_dict_interp_env_t ()
- : num_interp_env_t(), prev_offset(0), last_offset(0) {}
- cff1_top_dict_interp_env_t (const hb_ubytes_t &bytes)
- : num_interp_env_t(bytes), prev_offset(0), last_offset(0) {}
-
- unsigned int prev_offset;
- unsigned int last_offset;
-};
-
-struct name_dict_values_t
-{
- enum name_dict_val_index_t
- {
- version,
- notice,
- copyright,
- fullName,
- familyName,
- weight,
- postscript,
- fontName,
- baseFontName,
- registry,
- ordering,
-
- ValCount
- };
-
- void init ()
- {
- for (unsigned int i = 0; i < ValCount; i++)
- values[i] = CFF_UNDEF_SID;
- }
-
- unsigned int& operator[] (unsigned int i)
- { assert (i < ValCount); return values[i]; }
-
- unsigned int operator[] (unsigned int i) const
- { assert (i < ValCount); return values[i]; }
-
- static enum name_dict_val_index_t name_op_to_index (op_code_t op)
- {
- switch (op) {
- default: // can't happen - just make some compiler happy
- case OpCode_version:
- return version;
- case OpCode_Notice:
- return notice;
- case OpCode_Copyright:
- return copyright;
- case OpCode_FullName:
- return fullName;
- case OpCode_FamilyName:
- return familyName;
- case OpCode_Weight:
- return weight;
- case OpCode_PostScript:
- return postscript;
- case OpCode_FontName:
- return fontName;
- case OpCode_BaseFontName:
- return baseFontName;
- }
- }
-
- unsigned int values[ValCount];
-};
-
-struct cff1_top_dict_val_t : op_str_t
-{
- unsigned int last_arg_offset;
-};
-
-struct cff1_top_dict_values_t : top_dict_values_t<cff1_top_dict_val_t>
-{
- void init ()
- {
- top_dict_values_t<cff1_top_dict_val_t>::init ();
-
- nameSIDs.init ();
- ros_supplement = 0;
- cidCount = 8720;
- EncodingOffset = 0;
- CharsetOffset = 0;
- FDSelectOffset = 0;
- privateDictInfo.init ();
- }
- void fini () { top_dict_values_t<cff1_top_dict_val_t>::fini (); }
-
- bool is_CID () const
- { return nameSIDs[name_dict_values_t::registry] != CFF_UNDEF_SID; }
-
- name_dict_values_t nameSIDs;
- unsigned int ros_supplement_offset;
- unsigned int ros_supplement;
- unsigned int cidCount;
-
- unsigned int EncodingOffset;
- unsigned int CharsetOffset;
- unsigned int FDSelectOffset;
- table_info_t privateDictInfo;
-};
-
-struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t>
-{
- static void process_op (op_code_t op, cff1_top_dict_interp_env_t& env, cff1_top_dict_values_t& dictval)
- {
- cff1_top_dict_val_t val;
- val.last_arg_offset = (env.last_offset-1) - dictval.opStart; /* offset to the last argument */
-
- switch (op) {
- case OpCode_version:
- case OpCode_Notice:
- case OpCode_Copyright:
- case OpCode_FullName:
- case OpCode_FontName:
- case OpCode_FamilyName:
- case OpCode_Weight:
- case OpCode_PostScript:
- case OpCode_BaseFontName:
- dictval.nameSIDs[name_dict_values_t::name_op_to_index (op)] = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_isFixedPitch:
- case OpCode_ItalicAngle:
- case OpCode_UnderlinePosition:
- case OpCode_UnderlineThickness:
- case OpCode_PaintType:
- case OpCode_CharstringType:
- case OpCode_UniqueID:
- case OpCode_StrokeWidth:
- case OpCode_SyntheticBase:
- case OpCode_CIDFontVersion:
- case OpCode_CIDFontRevision:
- case OpCode_CIDFontType:
- case OpCode_UIDBase:
- case OpCode_FontBBox:
- case OpCode_XUID:
- case OpCode_BaseFontBlend:
- env.clear_args ();
- break;
-
- case OpCode_CIDCount:
- dictval.cidCount = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- case OpCode_ROS:
- dictval.ros_supplement = env.argStack.pop_uint ();
- dictval.nameSIDs[name_dict_values_t::ordering] = env.argStack.pop_uint ();
- dictval.nameSIDs[name_dict_values_t::registry] = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- case OpCode_Encoding:
- dictval.EncodingOffset = env.argStack.pop_uint ();
- env.clear_args ();
- if (unlikely (dictval.EncodingOffset == 0)) return;
- break;
-
- case OpCode_charset:
- dictval.CharsetOffset = env.argStack.pop_uint ();
- env.clear_args ();
- if (unlikely (dictval.CharsetOffset == 0)) return;
- break;
-
- case OpCode_FDSelect:
- dictval.FDSelectOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- case OpCode_Private:
- dictval.privateDictInfo.offset = env.argStack.pop_uint ();
- dictval.privateDictInfo.size = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- env.last_offset = env.str_ref.get_offset ();
- top_dict_opset_t<cff1_top_dict_val_t>::process_op (op, env, dictval);
- /* Record this operand below if stack is empty, otherwise done */
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref, val);
- }
-};
-
-struct cff1_font_dict_values_t : dict_values_t<op_str_t>
-{
- void init ()
- {
- dict_values_t<op_str_t>::init ();
- privateDictInfo.init ();
- fontName = CFF_UNDEF_SID;
- }
- void fini () { dict_values_t<op_str_t>::fini (); }
-
- table_info_t privateDictInfo;
- unsigned int fontName;
-};
-
-struct cff1_font_dict_opset_t : dict_opset_t
-{
- static void process_op (op_code_t op, num_interp_env_t& env, cff1_font_dict_values_t& dictval)
- {
- switch (op) {
- case OpCode_FontName:
- dictval.fontName = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_FontMatrix:
- case OpCode_PaintType:
- env.clear_args ();
- break;
- case OpCode_Private:
- dictval.privateDictInfo.offset = env.argStack.pop_uint ();
- dictval.privateDictInfo.size = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- dict_opset_t::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref);
- }
-};
-
-template <typename VAL>
-struct cff1_private_dict_values_base_t : dict_values_t<VAL>
-{
- void init ()
- {
- dict_values_t<VAL>::init ();
- subrsOffset = 0;
- localSubrs = &Null (CFF1Subrs);
- }
- void fini () { dict_values_t<VAL>::fini (); }
-
- unsigned int subrsOffset;
- const CFF1Subrs *localSubrs;
-};
-
-typedef cff1_private_dict_values_base_t<op_str_t> cff1_private_dict_values_subset_t;
-typedef cff1_private_dict_values_base_t<num_dict_val_t> cff1_private_dict_values_t;
-
-struct cff1_private_dict_opset_t : dict_opset_t
-{
- static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_t& dictval)
- {
- num_dict_val_t val;
- val.init ();
-
- switch (op) {
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_ForceBold:
- case OpCode_LanguageGroup:
- case OpCode_ExpansionFactor:
- case OpCode_initialRandomSeed:
- case OpCode_defaultWidthX:
- case OpCode_nominalWidthX:
- env.clear_args ();
- break;
- case OpCode_Subrs:
- dictval.subrsOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- dict_opset_t::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref, val);
- }
-};
-
-struct cff1_private_dict_opset_subset : dict_opset_t
-{
- static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_subset_t& dictval)
- {
- switch (op) {
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_ForceBold:
- case OpCode_LanguageGroup:
- case OpCode_ExpansionFactor:
- case OpCode_initialRandomSeed:
- case OpCode_defaultWidthX:
- case OpCode_nominalWidthX:
- env.clear_args ();
- break;
-
- case OpCode_Subrs:
- dictval.subrsOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- dict_opset_t::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref);
- }
-};
-
-typedef dict_interpreter_t<cff1_top_dict_opset_t, cff1_top_dict_values_t, cff1_top_dict_interp_env_t> cff1_top_dict_interpreter_t;
-typedef dict_interpreter_t<cff1_font_dict_opset_t, cff1_font_dict_values_t> cff1_font_dict_interpreter_t;
-
-typedef CFF1Index CFF1NameIndex;
-typedef CFF1IndexOf<TopDict> CFF1TopDictIndex;
-
-struct cff1_font_dict_values_mod_t
-{
- cff1_font_dict_values_mod_t() { init (); }
-
- void init () { init ( &Null (cff1_font_dict_values_t), CFF_UNDEF_SID ); }
-
- void init (const cff1_font_dict_values_t *base_,
- unsigned int fontName_)
- {
- base = base_;
- fontName = fontName_;
- privateDictInfo.init ();
- }
-
- unsigned get_count () const { return base->get_count (); }
-
- const op_str_t &operator [] (unsigned int i) const { return (*base)[i]; }
-
- const cff1_font_dict_values_t *base;
- table_info_t privateDictInfo;
- unsigned int fontName;
-};
-
-struct CFF1FDArray : FDArray<HBUINT16>
-{
- /* FDArray::serialize() requires this partial specialization to compile */
- template <typename ITER, typename OP_SERIALIZER>
- bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr)
- { return FDArray<HBUINT16>::serialize<cff1_font_dict_values_mod_t, cff1_font_dict_values_mod_t> (c, it, opszr); }
-};
-
-} /* namespace CFF */
-
-namespace OT {
-
-using namespace CFF;
-
-struct cff1
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cff1;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version.major == 1));
- }
-
- template <typename PRIVOPSET, typename PRIVDICTVAL>
- struct accelerator_templ_t
- {
- void init (hb_face_t *face)
- {
- topDict.init ();
- fontDicts.init ();
- privateDicts.init ();
-
- this->blob = sc.reference_table<cff1> (face);
-
- /* setup for run-time santization */
- sc.init (this->blob);
- sc.start_processing ();
-
- const OT::cff1 *cff = this->blob->template as<OT::cff1> ();
-
- if (cff == &Null (OT::cff1))
- { fini (); return; }
-
- nameIndex = &cff->nameIndex (cff);
- if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc))
- { fini (); return; }
-
- topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ());
- if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0))
- { fini (); return; }
-
- { /* parse top dict */
- const hb_ubytes_t topDictStr = (*topDictIndex)[0];
- if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
- cff1_top_dict_interp_env_t env (topDictStr);
- cff1_top_dict_interpreter_t top_interp (env);
- if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
- }
-
- if (is_predef_charset ())
- charset = &Null (Charset);
- else
- {
- charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset);
- if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; }
- }
-
- fdCount = 1;
- if (is_CID ())
- {
- fdArray = &StructAtOffsetOrNull<CFF1FDArray> (cff, topDict.FDArrayOffset);
- fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset);
- if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) ||
- (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
- { fini (); return; }
-
- fdCount = fdArray->count;
- }
- else
- {
- fdArray = &Null (CFF1FDArray);
- fdSelect = &Null (CFF1FDSelect);
- }
-
- encoding = &Null (Encoding);
- if (is_CID ())
- {
- if (unlikely (charset == &Null (Charset))) { fini (); return; }
- }
- else
- {
- if (!is_predef_encoding ())
- {
- encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
- if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
- }
- }
-
- stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ());
- if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
- { fini (); return; }
-
- globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ());
- if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc))
- { fini (); return; }
-
- charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset);
-
- if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
- { fini (); return; }
-
- num_glyphs = charStrings->count;
- if (num_glyphs != sc.get_num_glyphs ())
- { fini (); return; }
-
- if (unlikely (!privateDicts.resize (fdCount)))
- { fini (); return; }
- for (unsigned int i = 0; i < fdCount; i++)
- privateDicts[i].init ();
-
- // parse CID font dicts and gather private dicts
- if (is_CID ())
- {
- for (unsigned int i = 0; i < fdCount; i++)
- {
- hb_ubytes_t fontDictStr = (*fdArray)[i];
- if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
- cff1_font_dict_values_t *font;
- cff1_top_dict_interp_env_t env (fontDictStr);
- cff1_font_dict_interpreter_t font_interp (env);
- font = fontDicts.push ();
- if (unlikely (fontDicts.in_error ())) { fini (); return; }
-
- font->init ();
- if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
- PRIVDICTVAL *priv = &privateDicts[i];
- const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
- if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
- num_interp_env_t env2 (privDictStr);
- dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2);
- priv->init ();
- if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
-
- priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
- if (priv->localSubrs != &Null (CFF1Subrs) &&
- unlikely (!priv->localSubrs->sanitize (&sc)))
- { fini (); return; }
- }
- }
- else /* non-CID */
- {
- cff1_top_dict_values_t *font = &topDict;
- PRIVDICTVAL *priv = &privateDicts[0];
-
- const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
- if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
- num_interp_env_t env (privDictStr);
- dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env);
- priv->init ();
- if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
-
- priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
- if (priv->localSubrs != &Null (CFF1Subrs) &&
- unlikely (!priv->localSubrs->sanitize (&sc)))
- { fini (); return; }
- }
- }
-
- void fini ()
- {
- sc.end_processing ();
- topDict.fini ();
- fontDicts.fini ();
- privateDicts.fini ();
- hb_blob_destroy (blob);
- blob = nullptr;
- }
-
- bool is_valid () const { return blob; }
- bool is_CID () const { return topDict.is_CID (); }
-
- bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
-
- unsigned int std_code_to_glyph (hb_codepoint_t code) const
- {
- hb_codepoint_t sid = lookup_standard_encoding_for_sid (code);
- if (unlikely (sid == CFF_UNDEF_SID))
- return 0;
-
- if (charset != &Null (Charset))
- return charset->get_glyph (sid, num_glyphs);
- else if ((topDict.CharsetOffset == ISOAdobeCharset)
- && (code <= 228 /*zcaron*/)) return sid;
- return 0;
- }
-
- bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
-
- hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
- {
- if (encoding != &Null (Encoding))
- return encoding->get_code (glyph);
- else
- {
- hb_codepoint_t sid = glyph_to_sid (glyph);
- if (sid == 0) return 0;
- hb_codepoint_t code = 0;
- switch (topDict.EncodingOffset)
- {
- case StandardEncoding:
- code = lookup_standard_encoding_for_code (sid);
- break;
- case ExpertEncoding:
- code = lookup_expert_encoding_for_code (sid);
- break;
- default:
- break;
- }
- return code;
- }
- }
-
- hb_map_t *create_glyph_to_sid_map () const
- {
- if (charset != &Null (Charset))
- {
- hb_map_t *mapping = hb_map_create ();
- mapping->set (0, 0);
- charset->collect_glyph_to_sid_map (mapping, num_glyphs);
- return mapping;
- }
- else
- return nullptr;
- }
-
- hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const
- {
- if (charset != &Null (Charset))
- return charset->get_sid (glyph, num_glyphs);
- else
- {
- hb_codepoint_t sid = 0;
- switch (topDict.CharsetOffset)
- {
- case ISOAdobeCharset:
- if (glyph <= 228 /*zcaron*/) sid = glyph;
- break;
- case ExpertCharset:
- sid = lookup_expert_charset_for_sid (glyph);
- break;
- case ExpertSubsetCharset:
- sid = lookup_expert_subset_charset_for_sid (glyph);
- break;
- default:
- break;
- }
- return sid;
- }
- }
-
- hb_codepoint_t sid_to_glyph (hb_codepoint_t sid) const
- {
- if (charset != &Null (Charset))
- return charset->get_glyph (sid, num_glyphs);
- else
- {
- hb_codepoint_t glyph = 0;
- switch (topDict.CharsetOffset)
- {
- case ISOAdobeCharset:
- if (sid <= 228 /*zcaron*/) glyph = sid;
- break;
- case ExpertCharset:
- glyph = lookup_expert_charset_for_glyph (sid);
- break;
- case ExpertSubsetCharset:
- glyph = lookup_expert_subset_charset_for_glyph (sid);
- break;
- default:
- break;
- }
- return glyph;
- }
- }
-
- protected:
- hb_sanitize_context_t sc;
-
- public:
- hb_blob_t *blob = nullptr;
- const Encoding *encoding = nullptr;
- const Charset *charset = nullptr;
- const CFF1NameIndex *nameIndex = nullptr;
- const CFF1TopDictIndex *topDictIndex = nullptr;
- const CFF1StringIndex *stringIndex = nullptr;
- const CFF1Subrs *globalSubrs = nullptr;
- const CFF1CharStrings *charStrings = nullptr;
- const CFF1FDArray *fdArray = nullptr;
- const CFF1FDSelect *fdSelect = nullptr;
- unsigned int fdCount = 0;
-
- cff1_top_dict_values_t topDict;
- hb_vector_t<cff1_font_dict_values_t>
- fontDicts;
- hb_vector_t<PRIVDICTVAL> privateDicts;
-
- unsigned int num_glyphs = 0;
- };
-
- struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
- {
- accelerator_t (hb_face_t *face)
- {
- SUPER::init (face);
-
- glyph_names.set_relaxed (nullptr);
-
- if (!is_valid ()) return;
- if (is_CID ()) return;
-
- }
- ~accelerator_t ()
- {
- hb_sorted_vector_t<gname_t> *names = glyph_names.get_relaxed ();
- if (names)
- {
- names->fini ();
- hb_free (names);
- }
-
- SUPER::fini ();
- }
-
- bool get_glyph_name (hb_codepoint_t glyph,
- char *buf, unsigned int buf_len) const
- {
- if (unlikely (glyph >= num_glyphs)) return false;
- if (unlikely (!is_valid ())) return false;
- if (is_CID()) return false;
- if (unlikely (!buf_len)) return true;
- hb_codepoint_t sid = glyph_to_sid (glyph);
- const char *str;
- size_t str_len;
- if (sid < cff1_std_strings_length)
- {
- hb_bytes_t byte_str = cff1_std_strings (sid);
- str = byte_str.arrayZ;
- str_len = byte_str.length;
- }
- else
- {
- hb_ubytes_t ubyte_str = (*stringIndex)[sid - cff1_std_strings_length];
- str = (const char *)ubyte_str.arrayZ;
- str_len = ubyte_str.length;
- }
- if (!str_len) return false;
- unsigned int len = hb_min (buf_len - 1, str_len);
- strncpy (buf, (const char*)str, len);
- buf[len] = '\0';
- return true;
- }
-
- bool get_glyph_from_name (const char *name, int len,
- hb_codepoint_t *glyph) const
- {
- if (unlikely (!is_valid ())) return false;
- if (is_CID()) return false;
- if (len < 0) len = strlen (name);
- if (unlikely (!len)) return false;
-
- retry:
- hb_sorted_vector_t<gname_t> *names = glyph_names.get_acquire ();
- if (unlikely (!names))
- {
- names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1);
- if (likely (names))
- {
- names->init ();
- /* TODO */
-
- /* fill glyph names */
- for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
- {
- hb_codepoint_t sid = glyph_to_sid (gid);
- gname_t gname;
- gname.sid = sid;
- if (sid < cff1_std_strings_length)
- gname.name = cff1_std_strings (sid);
- else
- {
- hb_ubytes_t ustr = (*stringIndex)[sid - cff1_std_strings_length];
- gname.name = hb_bytes_t ((const char*) ustr.arrayZ, ustr.length);
- }
- if (unlikely (!gname.name.arrayZ))
- gname.name = hb_bytes_t ("", 0); /* To avoid nullptr. */
- names->push (gname);
- }
- names->qsort ();
- }
- if (unlikely (!glyph_names.cmpexch (nullptr, names)))
- {
- if (names)
- {
- names->fini ();
- hb_free (names);
- }
- goto retry;
- }
- }
-
- gname_t key = { hb_bytes_t (name, len), 0 };
- const gname_t *gname = names ? names->bsearch (key) : nullptr;
- if (!gname) return false;
- hb_codepoint_t gid = sid_to_glyph (gname->sid);
- if (!gid && gname->sid) return false;
- *glyph = gid;
- return true;
- }
-
- HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
- HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
- HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
- HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
-
- private:
- struct gname_t
- {
- hb_bytes_t name;
- uint16_t sid;
-
- static int cmp (const void *a_, const void *b_)
- {
- const gname_t *a = (const gname_t *)a_;
- const gname_t *b = (const gname_t *)b_;
- unsigned minlen = hb_min (a->name.length, b->name.length);
- int ret = strncmp (a->name.arrayZ, b->name.arrayZ, minlen);
- if (ret) return ret;
- return a->name.length - b->name.length;
- }
-
- int cmp (const gname_t &a) const { return cmp (&a, this); }
- };
-
- mutable hb_atomic_ptr_t<hb_sorted_vector_t<gname_t>> glyph_names;
-
- typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER;
- };
-
- struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {};
-
- bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); }
-
- protected:
- HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid);
- HB_INTERNAL static hb_codepoint_t lookup_expert_encoding_for_code (hb_codepoint_t sid);
- HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_sid (hb_codepoint_t glyph);
- HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph);
- HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_glyph (hb_codepoint_t sid);
- HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid);
- HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_sid (hb_codepoint_t code);
-
- public:
- FixedVersion<HBUINT8> version; /* Version of CFF table. set to 0x0100u */
- NNOffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */
- HBUINT8 offSize; /* offset size (unused?) */
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct cff1_accelerator_t : cff1::accelerator_t {
- cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-#endif /* HB_OT_CFF1_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc
deleted file mode 100644
index 79555655519..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_FONT_CFF
-
-#include "hb-ot-cff2-table.hh"
-#include "hb-cff2-interp-cs.hh"
-#include "hb-draw.hh"
-
-using namespace CFF;
-
-struct cff2_extents_param_t
-{
- cff2_extents_param_t ()
- {
- min_x.set_int (INT_MAX);
- min_y.set_int (INT_MAX);
- max_x.set_int (INT_MIN);
- max_y.set_int (INT_MIN);
- }
-
- void start_path () { path_open = true; }
- void end_path () { path_open = false; }
- bool is_path_open () const { return path_open; }
-
- void update_bounds (const point_t &pt)
- {
- if (pt.x < min_x) min_x = pt.x;
- if (pt.x > max_x) max_x = pt.x;
- if (pt.y < min_y) min_y = pt.y;
- if (pt.y > max_y) max_y = pt.y;
- }
-
- bool path_open = false;
- number_t min_x;
- number_t min_y;
- number_t max_x;
- number_t max_y;
-};
-
-struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t<number_t>, cff2_extents_param_t>
-{
- static void moveto (cff2_cs_interp_env_t<number_t> &env, cff2_extents_param_t& param, const point_t &pt)
- {
- param.end_path ();
- env.moveto (pt);
- }
-
- static void line (cff2_cs_interp_env_t<number_t> &env, cff2_extents_param_t& param, const point_t &pt1)
- {
- if (!param.is_path_open ())
- {
- param.start_path ();
- param.update_bounds (env.get_pt ());
- }
- env.moveto (pt1);
- param.update_bounds (env.get_pt ());
- }
-
- static void curve (cff2_cs_interp_env_t<number_t> &env, cff2_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
- {
- if (!param.is_path_open ())
- {
- param.start_path ();
- param.update_bounds (env.get_pt ());
- }
- /* include control points */
- param.update_bounds (pt1);
- param.update_bounds (pt2);
- env.moveto (pt3);
- param.update_bounds (env.get_pt ());
- }
-};
-
-struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_extents_param_t, number_t, cff2_path_procs_extents_t> {};
-
-bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents) const
-{
-#ifdef HB_NO_OT_FONT_CFF
- /* XXX Remove check when this code moves to .hh file. */
- return true;
-#endif
-
- if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
-
- unsigned int fd = fdSelect->get_fd (glyph);
- const hb_ubytes_t str = (*charStrings)[glyph];
- cff2_cs_interp_env_t<number_t> env (str, *this, fd, font->coords, font->num_coords);
- cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t, number_t> interp (env);
- cff2_extents_param_t param;
- if (unlikely (!interp.interpret (param))) return false;
-
- if (param.min_x >= param.max_x)
- {
- extents->width = 0;
- extents->x_bearing = 0;
- }
- else
- {
- extents->x_bearing = roundf (param.min_x.to_real ());
- extents->width = roundf (param.max_x.to_real () - extents->x_bearing);
- }
- if (param.min_y >= param.max_y)
- {
- extents->height = 0;
- extents->y_bearing = 0;
- }
- else
- {
- extents->y_bearing = roundf (param.max_y.to_real ());
- extents->height = roundf (param.min_y.to_real () - extents->y_bearing);
- }
-
- font->scale_glyph_extents (extents);
-
- return true;
-}
-
-bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
-{
- funcs->push_clip_glyph (data, glyph, font);
- funcs->color (data, true, foreground);
- funcs->pop_clip (data);
-
- return true;
-}
-
-struct cff2_path_param_t
-{
- cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
- {
- draw_session = &draw_session_;
- font = font_;
- }
-
- void move_to (const point_t &p)
- { draw_session->move_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
-
- void line_to (const point_t &p)
- { draw_session->line_to (font->em_fscalef_x (p.x.to_real ()), font->em_fscalef_y (p.y.to_real ())); }
-
- void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
- {
- draw_session->cubic_to (font->em_fscalef_x (p1.x.to_real ()), font->em_fscalef_y (p1.y.to_real ()),
- font->em_fscalef_x (p2.x.to_real ()), font->em_fscalef_y (p2.y.to_real ()),
- font->em_fscalef_x (p3.x.to_real ()), font->em_fscalef_y (p3.y.to_real ()));
- }
-
- protected:
- hb_draw_session_t *draw_session;
- hb_font_t *font;
-};
-
-struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_interp_env_t<number_t>, cff2_path_param_t>
-{
- static void moveto (cff2_cs_interp_env_t<number_t> &env, cff2_path_param_t& param, const point_t &pt)
- {
- param.move_to (pt);
- env.moveto (pt);
- }
-
- static void line (cff2_cs_interp_env_t<number_t> &env, cff2_path_param_t& param, const point_t &pt1)
- {
- param.line_to (pt1);
- env.moveto (pt1);
- }
-
- static void curve (cff2_cs_interp_env_t<number_t> &env, cff2_path_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
- {
- param.cubic_to (pt1, pt2, pt3);
- env.moveto (pt3);
- }
-};
-
-struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, number_t, cff2_path_procs_path_t> {};
-
-bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
-{
-#ifdef HB_NO_OT_FONT_CFF
- /* XXX Remove check when this code moves to .hh file. */
- return true;
-#endif
-
- if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
-
- unsigned int fd = fdSelect->get_fd (glyph);
- const hb_ubytes_t str = (*charStrings)[glyph];
- cff2_cs_interp_env_t<number_t> env (str, *this, fd, font->coords, font->num_coords);
- cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t, number_t> interp (env);
- cff2_path_param_t param (font, draw_session);
- if (unlikely (!interp.interpret (param))) return false;
- return true;
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
deleted file mode 100644
index b9a8819ab85..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_OT_CFF2_TABLE_HH
-#define HB_OT_CFF2_TABLE_HH
-
-#include "hb-ot-cff-common.hh"
-#include "hb-subset-cff2.hh"
-#include "hb-draw.hh"
-#include "hb-paint.hh"
-
-namespace CFF {
-
-/*
- * CFF2 -- Compact Font Format (CFF) Version 2
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2
- */
-#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2')
-
-typedef CFFIndex<HBUINT32> CFF2Index;
-template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {};
-
-typedef CFF2Index CFF2CharStrings;
-typedef Subrs<HBUINT32> CFF2Subrs;
-
-typedef FDSelect3_4<HBUINT32, HBUINT16> FDSelect4;
-typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range;
-
-struct CFF2FDSelect
-{
- bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
- {
- TRACE_SERIALIZE (this);
- unsigned int size = src.get_size (num_glyphs);
- CFF2FDSelect *dest = c->allocate_size<CFF2FDSelect> (size);
- if (unlikely (!dest)) return_trace (false);
- hb_memcpy (dest, &src, size);
- return_trace (true);
- }
-
- unsigned int get_size (unsigned int num_glyphs) const
- {
- switch (format)
- {
- case 0: return format.static_size + u.format0.get_size (num_glyphs);
- case 3: return format.static_size + u.format3.get_size ();
- case 4: return format.static_size + u.format4.get_size ();
- default:return 0;
- }
- }
-
- hb_codepoint_t get_fd (hb_codepoint_t glyph) const
- {
- if (this == &Null (CFF2FDSelect))
- return 0;
-
- switch (format)
- {
- case 0: return u.format0.get_fd (glyph);
- case 3: return u.format3.get_fd (glyph);
- case 4: return u.format4.get_fd (glyph);
- default:return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (format)
- {
- case 0: return_trace (u.format0.sanitize (c, fdcount));
- case 3: return_trace (u.format3.sanitize (c, fdcount));
- case 4: return_trace (u.format4.sanitize (c, fdcount));
- default:return_trace (false);
- }
- }
-
- HBUINT8 format;
- union {
- FDSelect0 format0;
- FDSelect3 format3;
- FDSelect4 format4;
- } u;
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct CFF2VariationStore
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this)) && c->check_range (&varStore, size) && varStore.sanitize (c));
- }
-
- bool serialize (hb_serialize_context_t *c, const CFF2VariationStore *varStore)
- {
- TRACE_SERIALIZE (this);
- unsigned int size_ = varStore->get_size ();
- CFF2VariationStore *dest = c->allocate_size<CFF2VariationStore> (size_);
- if (unlikely (!dest)) return_trace (false);
- hb_memcpy (dest, varStore, size_);
- return_trace (true);
- }
-
- unsigned int get_size () const { return HBUINT16::static_size + size; }
-
- HBUINT16 size;
- VariationStore varStore;
-
- DEFINE_SIZE_MIN (2 + VariationStore::min_size);
-};
-
-struct cff2_top_dict_values_t : top_dict_values_t<>
-{
- void init ()
- {
- top_dict_values_t<>::init ();
- vstoreOffset = 0;
- FDSelectOffset = 0;
- }
- void fini () { top_dict_values_t<>::fini (); }
-
- unsigned int vstoreOffset;
- unsigned int FDSelectOffset;
-};
-
-struct cff2_top_dict_opset_t : top_dict_opset_t<>
-{
- static void process_op (op_code_t op, num_interp_env_t& env, cff2_top_dict_values_t& dictval)
- {
- switch (op) {
- case OpCode_FontMatrix:
- {
- dict_val_t val;
- val.init ();
- dictval.add_op (op, env.str_ref);
- env.clear_args ();
- }
- break;
-
- case OpCode_vstore:
- dictval.vstoreOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_FDSelect:
- dictval.FDSelectOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- SUPER::process_op (op, env, dictval);
- /* Record this operand below if stack is empty, otherwise done */
- if (!env.argStack.is_empty ()) return;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref);
- }
-
- typedef top_dict_opset_t<> SUPER;
-};
-
-struct cff2_font_dict_values_t : dict_values_t<op_str_t>
-{
- void init ()
- {
- dict_values_t<op_str_t>::init ();
- privateDictInfo.init ();
- }
- void fini () { dict_values_t<op_str_t>::fini (); }
-
- table_info_t privateDictInfo;
-};
-
-struct cff2_font_dict_opset_t : dict_opset_t
-{
- static void process_op (op_code_t op, num_interp_env_t& env, cff2_font_dict_values_t& dictval)
- {
- switch (op) {
- case OpCode_Private:
- dictval.privateDictInfo.offset = env.argStack.pop_uint ();
- dictval.privateDictInfo.size = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- SUPER::process_op (op, env);
- if (!env.argStack.is_empty ())
- return;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref);
- }
-
- private:
- typedef dict_opset_t SUPER;
-};
-
-template <typename VAL>
-struct cff2_private_dict_values_base_t : dict_values_t<VAL>
-{
- void init ()
- {
- dict_values_t<VAL>::init ();
- subrsOffset = 0;
- localSubrs = &Null (CFF2Subrs);
- ivs = 0;
- }
- void fini () { dict_values_t<VAL>::fini (); }
-
- unsigned int subrsOffset;
- const CFF2Subrs *localSubrs;
- unsigned int ivs;
-};
-
-typedef cff2_private_dict_values_base_t<op_str_t> cff2_private_dict_values_subset_t;
-typedef cff2_private_dict_values_base_t<num_dict_val_t> cff2_private_dict_values_t;
-
-struct cff2_priv_dict_interp_env_t : num_interp_env_t
-{
- cff2_priv_dict_interp_env_t (const hb_ubytes_t &str) :
- num_interp_env_t (str) {}
-
- void process_vsindex ()
- {
- if (likely (!seen_vsindex))
- {
- set_ivs (argStack.pop_uint ());
- }
- seen_vsindex = true;
- }
-
- unsigned int get_ivs () const { return ivs; }
- void set_ivs (unsigned int ivs_) { ivs = ivs_; }
-
- protected:
- unsigned int ivs = 0;
- bool seen_vsindex = false;
-};
-
-struct cff2_private_dict_opset_t : dict_opset_t
-{
- static void process_op (op_code_t op, cff2_priv_dict_interp_env_t& env, cff2_private_dict_values_t& dictval)
- {
- num_dict_val_t val;
- val.init ();
-
- switch (op) {
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_ExpansionFactor:
- case OpCode_LanguageGroup:
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- env.clear_args ();
- break;
- case OpCode_Subrs:
- dictval.subrsOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
- case OpCode_vsindexdict:
- env.process_vsindex ();
- dictval.ivs = env.get_ivs ();
- env.clear_args ();
- break;
- case OpCode_blenddict:
- break;
-
- default:
- dict_opset_t::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref, val);
- }
-};
-
-struct cff2_private_dict_opset_subset_t : dict_opset_t
-{
- static void process_op (op_code_t op, cff2_priv_dict_interp_env_t& env, cff2_private_dict_values_subset_t& dictval)
- {
- switch (op) {
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- case OpCode_LanguageGroup:
- case OpCode_ExpansionFactor:
- env.clear_args ();
- break;
-
- case OpCode_blenddict:
- env.clear_args ();
- return;
-
- case OpCode_Subrs:
- dictval.subrsOffset = env.argStack.pop_uint ();
- env.clear_args ();
- break;
-
- default:
- SUPER::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- dictval.add_op (op, env.str_ref);
- }
-
- private:
- typedef dict_opset_t SUPER;
-};
-
-typedef dict_interpreter_t<cff2_top_dict_opset_t, cff2_top_dict_values_t> cff2_top_dict_interpreter_t;
-typedef dict_interpreter_t<cff2_font_dict_opset_t, cff2_font_dict_values_t> cff2_font_dict_interpreter_t;
-
-struct CFF2FDArray : FDArray<HBUINT32>
-{
- /* FDArray::serialize does not compile without this partial specialization */
- template <typename ITER, typename OP_SERIALIZER>
- bool serialize (hb_serialize_context_t *c, ITER it, OP_SERIALIZER& opszr)
- { return FDArray<HBUINT32>::serialize<cff2_font_dict_values_t, table_info_t> (c, it, opszr); }
-};
-
-} /* namespace CFF */
-
-namespace OT {
-
-using namespace CFF;
-
-struct cff2
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cff2;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version.major == 2));
- }
-
- template <typename PRIVOPSET, typename PRIVDICTVAL>
- struct accelerator_templ_t
- {
- accelerator_templ_t (hb_face_t *face)
- {
- topDict.init ();
- fontDicts.init ();
- privateDicts.init ();
-
- this->blob = sc.reference_table<cff2> (face);
-
- /* setup for run-time santization */
- sc.init (this->blob);
- sc.start_processing ();
-
- const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
-
- if (cff2 == &Null (OT::cff2))
- goto fail;
-
- { /* parse top dict */
- hb_ubytes_t topDictStr = (cff2 + cff2->topDict).as_ubytes (cff2->topDictSize);
- if (unlikely (!topDictStr.sanitize (&sc))) goto fail;
- num_interp_env_t env (topDictStr);
- cff2_top_dict_interpreter_t top_interp (env);
- topDict.init ();
- if (unlikely (!top_interp.interpret (topDict))) goto fail;
- }
-
- globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
- varStore = &StructAtOffsetOrNull<CFF2VariationStore> (cff2, topDict.vstoreOffset);
- charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset);
- fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset);
- fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset);
-
- if (((varStore != &Null (CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) ||
- (charStrings == &Null (CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) ||
- (globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
- (fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
- (((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
- goto fail;
-
- num_glyphs = charStrings->count;
- if (num_glyphs != sc.get_num_glyphs ())
- goto fail;
-
- fdCount = fdArray->count;
- if (!privateDicts.resize (fdCount))
- goto fail;
-
- /* parse font dicts and gather private dicts */
- for (unsigned int i = 0; i < fdCount; i++)
- {
- const hb_ubytes_t fontDictStr = (*fdArray)[i];
- if (unlikely (!fontDictStr.sanitize (&sc))) goto fail;
- cff2_font_dict_values_t *font;
- num_interp_env_t env (fontDictStr);
- cff2_font_dict_interpreter_t font_interp (env);
- font = fontDicts.push ();
- if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail;
- font->init ();
- if (unlikely (!font_interp.interpret (*font))) goto fail;
-
- const hb_ubytes_t privDictStr = StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
- if (unlikely (!privDictStr.sanitize (&sc))) goto fail;
- cff2_priv_dict_interp_env_t env2 (privDictStr);
- dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp (env2);
- privateDicts[i].init ();
- if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail;
-
- privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset);
- if (privateDicts[i].localSubrs != &Null (CFF2Subrs) &&
- unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
- goto fail;
- }
-
-
- return;
-
- fail:
- _fini ();
- }
- ~accelerator_templ_t () { _fini (); }
- void _fini ()
- {
- sc.end_processing ();
- topDict.fini ();
- fontDicts.fini ();
- privateDicts.fini ();
- hb_blob_destroy (blob);
- blob = nullptr;
- }
-
- hb_map_t *create_glyph_to_sid_map () const
- {
- return nullptr;
- }
-
- bool is_valid () const { return blob; }
-
- protected:
- hb_sanitize_context_t sc;
-
- public:
- hb_blob_t *blob = nullptr;
- cff2_top_dict_values_t topDict;
- const CFF2Subrs *globalSubrs = nullptr;
- const CFF2VariationStore *varStore = nullptr;
- const CFF2CharStrings *charStrings = nullptr;
- const CFF2FDArray *fdArray = nullptr;
- const CFF2FDSelect *fdSelect = nullptr;
- unsigned int fdCount = 0;
-
- hb_vector_t<cff2_font_dict_values_t> fontDicts;
- hb_vector_t<PRIVDICTVAL> privateDicts;
-
- unsigned int num_glyphs = 0;
- };
-
- struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t>
- {
- accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {}
-
- HB_INTERNAL bool get_extents (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents) const;
- HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
- HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
- };
-
- typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;
-
- bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); }
-
- public:
- FixedVersion<HBUINT8> version; /* Version of CFF2 table. set to 0x0200u */
- NNOffsetTo<TopDict, HBUINT8> topDict; /* headerSize = Offset to Top DICT. */
- HBUINT16 topDictSize; /* Top DICT size */
-
- public:
- DEFINE_SIZE_STATIC (5);
-};
-
-struct cff2_accelerator_t : cff2::accelerator_t {
- cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-#endif /* HB_OT_CFF2_TABLE_HH */
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 cf5ccd53e95..883d7b3f0b2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh
@@ -27,67 +27,41 @@
#ifndef HB_OT_CMAP_TABLE_HH
#define HB_OT_CMAP_TABLE_HH
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-shaper-arabic-pua.hh"
-#include "hb-open-type.hh"
-#include "hb-set.hh"
-#include "hb-cache.hh"
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
/*
- * cmap -- Character to Glyph Index Mapping
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cmap
+ * cmap -- Character To Glyph Index Mapping Table
*/
-#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
-namespace OT {
+#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
struct CmapSubtableFormat0
{
- bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+ inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
- if (unlikely (!gid))
+ if (!gid)
return false;
*glyph = gid;
return true;
}
- unsigned get_language () const
- {
- return language;
- }
-
- void collect_unicodes (hb_set_t *out) const
- {
- for (unsigned int i = 0; i < 256; i++)
- if (glyphIdArray[i])
- out->add (i);
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- for (unsigned i = 0; i < 256; i++)
- if (glyphIdArray[i])
- {
- hb_codepoint_t glyph = glyphIdArray[i];
- unicodes->add (i);
- mapping->set (i, glyph);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
protected:
- HBUINT16 format; /* Format number is set to 0. */
- HBUINT16 length; /* Byte length of this subtable. */
- HBUINT16 language; /* Ignore. */
- HBUINT8 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);
@@ -95,300 +69,12 @@ struct CmapSubtableFormat0
struct CmapSubtableFormat4
{
-
-
- template<typename Iterator,
- typename Writer,
- hb_requires (hb_is_iterator (Iterator))>
- void to_ranges (Iterator it, Writer& range_writer)
- {
- hb_codepoint_t start_cp = 0, prev_run_start_cp = 0, run_start_cp = 0, end_cp = 0, last_gid = 0;
- int run_length = 0 , delta = 0, prev_delta = 0;
-
- enum {
- FIRST_SUB_RANGE,
- FOLLOWING_SUB_RANGE,
- } mode;
-
- while (it) {
- // Start a new range
- {
- const auto& pair = *it;
- start_cp = pair.first;
- prev_run_start_cp = start_cp;
- run_start_cp = start_cp;
- end_cp = start_cp;
- last_gid = pair.second;
- run_length = 1;
- prev_delta = 0;
- }
-
- delta = last_gid - start_cp;
- mode = FIRST_SUB_RANGE;
- it++;
-
- while (it) {
- // Process range
- const auto& pair = *it;
- hb_codepoint_t next_cp = pair.first;
- hb_codepoint_t next_gid = pair.second;
- if (next_cp != end_cp + 1) {
- // Current range is over, stop processing.
- break;
- }
-
- if (next_gid == last_gid + 1) {
- // The current run continues.
- end_cp = next_cp;
- run_length++;
- last_gid = next_gid;
- it++;
- continue;
- }
-
- // A new run is starting, decide if we want to commit the current run.
- int split_cost = (mode == FIRST_SUB_RANGE) ? 8 : 16;
- int run_cost = run_length * 2;
- if (run_cost >= split_cost) {
- commit_current_range(start_cp,
- prev_run_start_cp,
- run_start_cp,
- end_cp,
- delta,
- prev_delta,
- split_cost,
- range_writer);
- start_cp = next_cp;
- }
-
- // Start the new run
- mode = FOLLOWING_SUB_RANGE;
- prev_run_start_cp = run_start_cp;
- run_start_cp = next_cp;
- end_cp = next_cp;
- prev_delta = delta;
- delta = next_gid - run_start_cp;
- run_length = 1;
- last_gid = next_gid;
- it++;
- }
-
- // Finalize range
- commit_current_range (start_cp,
- prev_run_start_cp,
- run_start_cp,
- end_cp,
- delta,
- prev_delta,
- 8,
- range_writer);
- }
-
- if (likely (end_cp != 0xFFFF)) {
- range_writer (0xFFFF, 0xFFFF, 1);
- }
- }
-
- /*
- * Writes the current range as either one or two ranges depending on what is most efficient.
- */
- template<typename Writer>
- void commit_current_range (hb_codepoint_t start,
- hb_codepoint_t prev_run_start,
- hb_codepoint_t run_start,
- hb_codepoint_t end,
- int run_delta,
- int previous_run_delta,
- int split_cost,
- Writer& range_writer) {
- bool should_split = false;
- if (start < run_start && run_start < end) {
- int run_cost = (end - run_start + 1) * 2;
- if (run_cost >= split_cost) {
- should_split = true;
- }
- }
-
- // TODO(grieger): handle case where delta is legitimately 0, mark range offset array instead?
- if (should_split) {
- if (start == prev_run_start)
- range_writer (start, run_start - 1, previous_run_delta);
- else
- range_writer (start, run_start - 1, 0);
- range_writer (run_start, end, run_delta);
- return;
- }
-
-
- if (start == run_start) {
- // Range is only a run
- range_writer (start, end, run_delta);
- return;
- }
-
- // Write only a single non-run range.
- range_writer (start, end, 0);
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- unsigned serialize_find_segcount (Iterator it) {
- struct Counter {
- unsigned segcount = 0;
-
- void operator() (hb_codepoint_t start,
- hb_codepoint_t end,
- int delta) {
- segcount++;
- }
- } counter;
-
- to_ranges (+it, counter);
- return counter.segcount;
- }
-
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize_start_end_delta_arrays (hb_serialize_context_t *c,
- Iterator it,
- int segcount)
- {
- struct Writer {
- hb_serialize_context_t *serializer_;
- HBUINT16* end_code_;
- HBUINT16* start_code_;
- HBINT16* id_delta_;
- int index_;
-
- Writer(hb_serialize_context_t *serializer)
- : serializer_(serializer),
- end_code_(nullptr),
- start_code_(nullptr),
- id_delta_(nullptr),
- index_ (0) {}
- void operator() (hb_codepoint_t start,
- hb_codepoint_t end,
- int delta) {
- start_code_[index_] = start;
- end_code_[index_] = end;
- id_delta_[index_] = delta;
- index_++;
- }
- } writer(c);
-
- writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
- c->allocate_size<HBUINT16> (2); // padding
- writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
- writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount);
-
- if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false;
-
- to_ranges (+it, writer);
- return true;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- HBUINT16* serialize_rangeoffset_glyid (hb_serialize_context_t *c,
- Iterator it,
- HBUINT16 *endCode,
- HBUINT16 *startCode,
- HBINT16 *idDelta,
- unsigned segcount)
- {
- hb_map_t cp_to_gid { it };
-
- HBUINT16 *idRangeOffset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
- if (unlikely (!c->check_success (idRangeOffset))) return nullptr;
- if (unlikely ((char *)idRangeOffset - (char *)idDelta != (int) segcount * (int) HBINT16::static_size)) return nullptr;
-
- for (unsigned i : + hb_range (segcount)
- | hb_filter ([&] (const unsigned _) { return idDelta[_] == 0; }))
- {
- idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i);
- for (hb_codepoint_t cp = startCode[i]; cp <= endCode[i]; cp++)
- {
- HBUINT16 gid;
- gid = cp_to_gid[cp];
- c->copy<HBUINT16> (gid);
- }
- }
-
- return idRangeOffset;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- auto format4_iter =
- + it
- | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
- { return _.first <= 0xFFFF; })
- ;
-
- if (!format4_iter) return;
-
- unsigned table_initpos = c->length ();
- if (unlikely (!c->extend_min (this))) return;
- this->format = 4;
-
- hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> cp_to_gid {
- format4_iter
- };
-
- //serialize endCode[], startCode[], idDelta[]
- HBUINT16* endCode = c->start_embed<HBUINT16> ();
- unsigned segcount = serialize_find_segcount (cp_to_gid.iter());
- if (unlikely (!serialize_start_end_delta_arrays (c, cp_to_gid.iter(), segcount)))
- return;
-
- HBUINT16 *startCode = endCode + segcount + 1;
- HBINT16 *idDelta = ((HBINT16*)startCode) + segcount;
-
- HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c,
- cp_to_gid.iter (),
- endCode,
- startCode,
- idDelta,
- segcount);
- if (unlikely (!c->check_success (idRangeOffset))) return;
-
- this->length = c->length () - table_initpos;
- if ((long long) this->length != (long long) c->length () - table_initpos)
- {
- // Length overflowed. Discard the current object before setting the error condition, otherwise
- // discard is a noop which prevents the higher level code from reverting the serializer to the
- // pre-error state in cmap4 overflow handling code.
- c->pop_discard ();
- c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW);
- return;
- }
-
- this->segCountX2 = segcount * 2;
- this->entrySelector = hb_max (1u, hb_bit_storage (segcount)) - 1;
- this->searchRange = 2 * (1u << this->entrySelector);
- this->rangeShift = segcount * 2 > this->searchRange
- ? 2 * segcount - this->searchRange
- : 0;
- }
-
- unsigned get_language () const
- {
- return language;
- }
-
struct accelerator_t
{
- accelerator_t () {}
- accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); }
-
- void init (const CmapSubtableFormat4 *subtable)
+ inline void init (const CmapSubtableFormat4 *subtable)
{
segCount = subtable->segCountX2 / 2;
- endCount = subtable->values.arrayZ;
+ endCount = subtable->values;
startCount = endCount + segCount + 1;
idDelta = startCount + segCount;
idRangeOffset = idDelta + segCount;
@@ -396,162 +82,68 @@ struct CmapSubtableFormat4
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
}
- bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+ static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
{
- struct CustomRange
+ const accelerator_t *thiz = (const accelerator_t *) obj;
+
+ /* Custom two-array bsearch. */
+ int min = 0, max = (int) thiz->segCount - 1;
+ const UINT16 *startCount = thiz->startCount;
+ const UINT16 *endCount = thiz->endCount;
+ unsigned int i;
+ while (min <= max)
{
- int cmp (hb_codepoint_t k,
- unsigned distance) const
+ int mid = (min + max) / 2;
+ if (codepoint < startCount[mid])
+ max = mid - 1;
+ else if (codepoint > endCount[mid])
+ min = mid + 1;
+ else
{
- if (k > last) return +1;
- if (k < (&last)[distance]/*first*/) return -1;
- return 0;
+ i = mid;
+ goto found;
}
- HBUINT16 last;
- };
-
- const HBUINT16 *found = hb_bsearch (codepoint,
- this->endCount,
- this->segCount,
- sizeof (CustomRange),
- _hb_cmp_method<hb_codepoint_t, CustomRange, unsigned>,
- this->segCount + 1);
- if (unlikely (!found))
- return false;
- unsigned int i = found - endCount;
+ }
+ return false;
+ found:
hb_codepoint_t gid;
- unsigned int rangeOffset = this->idRangeOffset[i];
+ unsigned int rangeOffset = thiz->idRangeOffset[i];
if (rangeOffset == 0)
- gid = codepoint + this->idDelta[i];
+ gid = codepoint + thiz->idDelta[i];
else
{
/* Somebody has been smoking... */
- unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
- if (unlikely (index >= this->glyphIdArrayLength))
+ unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount;
+ if (unlikely (index >= thiz->glyphIdArrayLength))
return false;
- gid = this->glyphIdArray[index];
+ gid = thiz->glyphIdArray[index];
if (unlikely (!gid))
return false;
- gid += this->idDelta[i];
- }
- gid &= 0xFFFFu;
- if (unlikely (!gid))
- return false;
- *glyph = gid;
- return true;
- }
-
- HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
- { return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); }
-
- void collect_unicodes (hb_set_t *out) const
- {
- unsigned int count = this->segCount;
- if (count && this->startCount[count - 1] == 0xFFFFu)
- count--; /* Skip sentinel segment. */
- for (unsigned int i = 0; i < count; i++)
- {
- hb_codepoint_t start = this->startCount[i];
- hb_codepoint_t end = this->endCount[i];
- unsigned int rangeOffset = this->idRangeOffset[i];
- out->add_range(start, end);
- if (rangeOffset == 0)
- {
- for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
- {
- hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu;
- if (unlikely (!gid))
- out->del(codepoint);
- }
- }
- else
- {
- for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
- {
- unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
- if (unlikely (index >= this->glyphIdArrayLength))
- {
- out->del_range (codepoint, end);
- break;
- }
- hb_codepoint_t gid = this->glyphIdArray[index];
- if (unlikely (!gid))
- out->del(codepoint);
- }
- }
+ gid += thiz->idDelta[i];
}
- }
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- // TODO(grieger): optimize similar to collect_unicodes
- // (ie. use add_range())
- unsigned count = this->segCount;
- if (count && this->startCount[count - 1] == 0xFFFFu)
- count--; /* Skip sentinel segment. */
- for (unsigned i = 0; i < count; i++)
- {
- hb_codepoint_t start = this->startCount[i];
- hb_codepoint_t end = this->endCount[i];
- unsigned rangeOffset = this->idRangeOffset[i];
- if (rangeOffset == 0)
- {
- for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
- {
- hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu;
- if (unlikely (!gid))
- continue;
- unicodes->add (codepoint);
- mapping->set (codepoint, gid);
- }
- }
- else
- {
- for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
- {
- unsigned index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
- if (unlikely (index >= this->glyphIdArrayLength))
- break;
- hb_codepoint_t gid = this->glyphIdArray[index];
- if (unlikely (!gid))
- continue;
- unicodes->add (codepoint);
- mapping->set (codepoint, gid);
- }
- }
- }
+ *glyph = gid & 0xFFFFu;
+ return true;
}
- const HBUINT16 *endCount;
- const HBUINT16 *startCount;
- const HBUINT16 *idDelta;
- const HBUINT16 *idRangeOffset;
- const HBUINT16 *glyphIdArray;
+ const UINT16 *endCount;
+ const UINT16 *startCount;
+ const UINT16 *idDelta;
+ const UINT16 *idRangeOffset;
+ const UINT16 *glyphIdArray;
unsigned int segCount;
unsigned int glyphIdArrayLength;
};
- bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+ inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
- accelerator_t accel (this);
+ accelerator_t accel;
+ accel.init (this);
return accel.get_glyph_func (&accel, codepoint, glyph);
}
- void collect_unicodes (hb_set_t *out) const
- {
- accelerator_t accel (this);
- accel.collect_unicodes (out);
- }
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- accelerator_t accel (this);
- accel.collect_mapping (unicodes, mapping);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
@@ -562,9 +154,9 @@ struct CmapSubtableFormat4
/* Some broken fonts have too long of a "length" value.
* If that is the case, just change the value to truncate
* the subtable at the end of the blob. */
- uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535,
- (uintptr_t) (c->end -
- (char *) this));
+ uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
+ (uintptr_t) (c->end -
+ (char *) this));
if (!c->try_set (&length, new_length))
return_trace (false);
}
@@ -572,29 +164,25 @@ struct CmapSubtableFormat4
return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
}
-
-
protected:
- HBUINT16 format; /* Format number is set to 4. */
- HBUINT16 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. */
- HBUINT16 language; /* Ignore. */
- HBUINT16 segCountX2; /* 2 x segCount. */
- HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */
- HBUINT16 entrySelector; /* log2(searchRange/2) */
- HBUINT16 rangeShift; /* 2 x segCount - searchRange */
-
- UnsizedArrayOf<HBUINT16>
- values;
+ 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 */
+
+ UINT16 values[VAR];
#if 0
- HBUINT16 endCount[segCount]; /* End characterCode for each segment,
+ UINT16 endCount[segCount]; /* End characterCode for each segment,
* last=0xFFFFu. */
- HBUINT16 reservedPad; /* Set to 0. */
- HBUINT16 startCount[segCount]; /* Start character code for each segment. */
- HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */
- HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
- UnsizedArrayOf<HBUINT16>
- glyphIdArray; /* 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:
@@ -605,9 +193,6 @@ struct CmapSubtableLongGroup
{
friend struct CmapSubtableFormat12;
friend struct CmapSubtableFormat13;
- template<typename U>
- friend struct CmapSubtableLongSegmented;
- friend struct cmap;
int cmp (hb_codepoint_t codepoint) const
{
@@ -616,65 +201,35 @@ struct CmapSubtableLongGroup
return 0;
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
private:
- HBUINT32 startCharCode; /* First character code in this group. */
- HBUINT32 endCharCode; /* Last character code in this group. */
- HBUINT32 glyphID; /* Glyph index; interpretation depends on
- * subtable format. */
+ 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);
};
-DECLARE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup);
template <typename UINT>
struct CmapSubtableTrimmed
{
- bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+ inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
/* Rely on our implicit array bound-checking. */
hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
- if (unlikely (!gid))
+ if (!gid)
return false;
*glyph = gid;
return true;
}
- unsigned get_language () const
- {
- return language;
- }
-
- void collect_unicodes (hb_set_t *out) const
- {
- hb_codepoint_t start = startCharCode;
- unsigned int count = glyphIdArray.len;
- for (unsigned int i = 0; i < count; i++)
- if (glyphIdArray[i])
- out->add (start + i);
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- hb_codepoint_t start_cp = startCharCode;
- unsigned count = glyphIdArray.len;
- for (unsigned i = 0; i < count; i++)
- if (glyphIdArray[i])
- {
- hb_codepoint_t unicode = start_cp + i;
- hb_codepoint_t glyphid = glyphIdArray[i];
- unicodes->add (unicode);
- mapping->set (unicode, glyphid);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && glyphIdArray.sanitize (c));
@@ -682,111 +237,43 @@ struct CmapSubtableTrimmed
protected:
UINT formatReserved; /* Subtable format and (maybe) padding. */
- UINT length; /* Byte length of this subtable. */
- UINT language; /* Ignore. */
+ UINT lengthZ; /* Byte length of this subtable. */
+ UINT languageZ; /* Ignore. */
UINT startCharCode; /* First character code covered. */
- ArrayOf<HBGlyphID16, UINT>
+ ArrayOf<GlyphID, UINT>
glyphIdArray; /* Array of glyph index values for character
* codes in the range. */
public:
DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
};
-struct CmapSubtableFormat6 : CmapSubtableTrimmed<HBUINT16> {};
-struct CmapSubtableFormat10 : CmapSubtableTrimmed<HBUINT32> {};
+struct CmapSubtableFormat6 : CmapSubtableTrimmed<UINT16> {};
+struct CmapSubtableFormat10 : CmapSubtableTrimmed<UINT32 > {};
template <typename T>
struct CmapSubtableLongSegmented
{
- friend struct cmap;
-
- bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+ inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
- hb_codepoint_t gid = T::group_get_glyph (groups.bsearch (codepoint), codepoint);
- if (unlikely (!gid))
+ int i = groups.bsearch (codepoint);
+ if (i == -1)
return false;
- *glyph = gid;
+ *glyph = T::group_get_glyph (groups[i], codepoint);
return true;
}
- unsigned get_language () const
- {
- return language;
- }
-
- void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const
- {
- for (unsigned int i = 0; i < this->groups.len; i++)
- {
- hb_codepoint_t start = this->groups[i].startCharCode;
- hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
- (hb_codepoint_t) HB_UNICODE_MAX);
- hb_codepoint_t gid = this->groups[i].glyphID;
- if (!gid)
- {
- /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */
- if (! T::group_get_glyph (this->groups[i], end)) continue;
- start++;
- gid++;
- }
- if (unlikely ((unsigned int) gid >= num_glyphs)) continue;
- if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
- end = start + (hb_codepoint_t) num_glyphs - gid;
-
- out->add_range (start, hb_min (end, 0x10FFFFu));
- }
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping, /* OUT */
- unsigned num_glyphs) const
- {
- hb_codepoint_t last_end = 0;
- for (unsigned i = 0; i < this->groups.len; i++)
- {
- hb_codepoint_t start = this->groups[i].startCharCode;
- hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
- (hb_codepoint_t) HB_UNICODE_MAX);
- if (unlikely (start > end || start < last_end)) {
- // Range is not in order and is invalid, skip it.
- continue;
- }
- last_end = end;
-
-
- hb_codepoint_t gid = this->groups[i].glyphID;
- if (!gid)
- {
- /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */
- if (! T::group_get_glyph (this->groups[i], end)) continue;
- start++;
- gid++;
- }
- if (unlikely ((unsigned int) gid >= num_glyphs)) continue;
- if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
- end = start + (hb_codepoint_t) num_glyphs - gid;
-
- for (unsigned cp = start; cp <= end; cp++)
- {
- unicodes->add (cp);
- mapping->set (cp, gid);
- gid++;
- }
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && groups.sanitize (c));
}
protected:
- HBUINT16 format; /* Subtable format; set to 12. */
- HBUINT16 reserved; /* Reserved; set to 0. */
- HBUINT32 length; /* Byte length of this subtable. */
- HBUINT32 language; /* Ignore. */
- SortedArray32Of<CmapSubtableLongGroup>
+ 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);
@@ -794,80 +281,15 @@ struct CmapSubtableLongSegmented
struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
{
- static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
- hb_codepoint_t u)
- { return likely (group.startCharCode <= group.endCharCode) ?
- group.glyphID + (u - group.startCharCode) : 0; }
-
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- if (!it) return;
- unsigned table_initpos = c->length ();
- if (unlikely (!c->extend_min (this))) return;
-
- hb_codepoint_t startCharCode = (hb_codepoint_t) -1, endCharCode = (hb_codepoint_t) -1;
- hb_codepoint_t glyphID = 0;
-
- for (const auto& _ : +it)
- {
- if (startCharCode == (hb_codepoint_t) -1)
- {
- startCharCode = _.first;
- endCharCode = _.first;
- glyphID = _.second;
- }
- else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
- {
- CmapSubtableLongGroup grouprecord;
- grouprecord.startCharCode = startCharCode;
- grouprecord.endCharCode = endCharCode;
- grouprecord.glyphID = glyphID;
- c->copy<CmapSubtableLongGroup> (grouprecord);
-
- startCharCode = _.first;
- endCharCode = _.first;
- glyphID = _.second;
- }
- else
- endCharCode = _.first;
- }
-
- CmapSubtableLongGroup record;
- record.startCharCode = startCharCode;
- record.endCharCode = endCharCode;
- record.glyphID = glyphID;
- c->copy<CmapSubtableLongGroup> (record);
-
- this->format = 12;
- this->reserved = 0;
- this->length = c->length () - table_initpos;
- this->groups.len = (this->length - min_size) / CmapSubtableLongGroup::static_size;
- }
-
- static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
- { return 16 + 12 * groups_data.length; }
-
- private:
- static bool _is_gid_consecutive (hb_codepoint_t endCharCode,
- hb_codepoint_t startCharCode,
- hb_codepoint_t glyphID,
- hb_codepoint_t cp,
- hb_codepoint_t new_gid)
- {
- return (cp - 1 == endCharCode) &&
- new_gid == glyphID + (cp - startCharCode);
- }
-
+ static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
+ hb_codepoint_t u)
+ { return group.glyphID + (u - group.startCharCode); }
};
struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
{
- static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
- hb_codepoint_t u HB_UNUSED)
+ static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
+ hb_codepoint_t u HB_UNUSED)
{ return group.glyphID; }
};
@@ -880,274 +302,76 @@ typedef enum
struct UnicodeValueRange
{
- int cmp (const hb_codepoint_t &codepoint) const
+ inline int cmp (const hb_codepoint_t &codepoint) const
{
if (codepoint < startUnicodeValue) return -1;
if (codepoint > startUnicodeValue + additionalCount) return +1;
return 0;
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
- HBUINT24 startUnicodeValue; /* First value in this range. */
- HBUINT8 additionalCount; /* Number of additional values in this
+ UINT24 startUnicodeValue; /* First value in this range. */
+ UINT8 additionalCount; /* Number of additional values in this
* range. */
public:
DEFINE_SIZE_STATIC (4);
};
-struct DefaultUVS : SortedArray32Of<UnicodeValueRange>
-{
- void collect_unicodes (hb_set_t *out) const
- {
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- hb_codepoint_t first = arrayZ[i].startUnicodeValue;
- hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
- (hb_codepoint_t) HB_UNICODE_MAX);
- out->add_range (first, last);
- }
- }
-
- DefaultUVS* copy (hb_serialize_context_t *c,
- const hb_set_t *unicodes) const
- {
- DefaultUVS *out = c->start_embed<DefaultUVS> ();
- if (unlikely (!out)) return nullptr;
- auto snap = c->snapshot ();
-
- HBUINT32 len;
- len = 0;
- if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
- unsigned init_len = c->length ();
-
- if (this->len > unicodes->get_population () * hb_bit_storage ((unsigned) this->len))
- {
- hb_codepoint_t start = HB_SET_VALUE_INVALID;
- hb_codepoint_t end = HB_SET_VALUE_INVALID;
-
- for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
- unicodes->next (&u);)
- {
- if (!as_array ().bsearch (u))
- continue;
- if (start == HB_SET_VALUE_INVALID)
- {
- start = u;
- end = start - 1;
- }
- if (end + 1 != u || end - start == 255)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = start;
- rec.additionalCount = end - start;
- c->copy<UnicodeValueRange> (rec);
- start = u;
- }
- end = u;
- }
- if (start != HB_SET_VALUE_INVALID)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = start;
- rec.additionalCount = end - start;
- c->copy<UnicodeValueRange> (rec);
- }
-
- }
- else
- {
- hb_codepoint_t lastCode = HB_SET_VALUE_INVALID;
- int count = -1;
-
- for (const UnicodeValueRange& _ : *this)
- {
- hb_codepoint_t curEntry = (hb_codepoint_t) (_.startUnicodeValue - 1);
- hb_codepoint_t end = curEntry + _.additionalCount + 2;
-
- for (; unicodes->next (&curEntry) && curEntry < end;)
- {
- count += 1;
- if (lastCode == HB_SET_VALUE_INVALID)
- lastCode = curEntry;
- else if (lastCode + count != curEntry)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = lastCode;
- rec.additionalCount = count - 1;
- c->copy<UnicodeValueRange> (rec);
-
- lastCode = curEntry;
- count = 0;
- }
- }
- }
-
- if (lastCode != HB_MAP_VALUE_INVALID)
- {
- UnicodeValueRange rec;
- rec.startUnicodeValue = lastCode;
- rec.additionalCount = count;
- c->copy<UnicodeValueRange> (rec);
- }
- }
-
- if (c->length () - init_len == 0)
- {
- c->revert (snap);
- return nullptr;
- }
- else
- {
- if (unlikely (!c->check_assign (out->len,
- (c->length () - init_len) / UnicodeValueRange::static_size,
- HB_SERIALIZE_ERROR_INT_OVERFLOW))) return nullptr;
- return out;
- }
- }
-
- public:
- DEFINE_SIZE_ARRAY (4, *this);
-};
+typedef SortedArrayOf<UnicodeValueRange, UINT32> DefaultUVS;
struct UVSMapping
{
- int cmp (const hb_codepoint_t &codepoint) const
- { return unicodeValue.cmp (codepoint); }
+ inline int cmp (const hb_codepoint_t &codepoint) const
+ {
+ return unicodeValue.cmp (codepoint);
+ }
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
- HBUINT24 unicodeValue; /* Base Unicode value of the UVS */
- HBGlyphID16 glyphID; /* Glyph ID of the UVS */
+ UINT24 unicodeValue; /* Base Unicode value of the UVS */
+ GlyphID glyphID; /* Glyph ID of the UVS */
public:
DEFINE_SIZE_STATIC (5);
};
-struct NonDefaultUVS : SortedArray32Of<UVSMapping>
-{
- void collect_unicodes (hb_set_t *out) const
- {
- for (const auto& a : as_array ())
- out->add (a.unicodeValue);
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- for (const auto& a : as_array ())
- {
- hb_codepoint_t unicode = a.unicodeValue;
- hb_codepoint_t glyphid = a.glyphID;
- unicodes->add (unicode);
- mapping->set (unicode, glyphid);
- }
- }
-
- void closure_glyphs (const hb_set_t *unicodes,
- hb_set_t *glyphset) const
- {
- + as_array ()
- | hb_filter (unicodes, &UVSMapping::unicodeValue)
- | hb_map (&UVSMapping::glyphID)
- | hb_sink (glyphset)
- ;
- }
-
- NonDefaultUVS* copy (hb_serialize_context_t *c,
- const hb_set_t *unicodes,
- const hb_set_t *glyphs_requested,
- const hb_map_t *glyph_map) const
- {
- NonDefaultUVS *out = c->start_embed<NonDefaultUVS> ();
- if (unlikely (!out)) return nullptr;
-
- auto it =
- + as_array ()
- | hb_filter ([&] (const UVSMapping& _)
- {
- return unicodes->has (_.unicodeValue) || glyphs_requested->has (_.glyphID);
- })
- ;
-
- if (!it) return nullptr;
-
- HBUINT32 len;
- len = it.len ();
- if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
-
- for (const UVSMapping& _ : it)
- {
- UVSMapping mapping;
- mapping.unicodeValue = _.unicodeValue;
- mapping.glyphID = glyph_map->get (_.glyphID);
- c->copy<UVSMapping> (mapping);
- }
-
- return out;
- }
-
- public:
- DEFINE_SIZE_ARRAY (4, *this);
-};
+typedef SortedArrayOf<UVSMapping, UINT32> NonDefaultUVS;
struct VariationSelectorRecord
{
- glyph_variant_t get_glyph (hb_codepoint_t codepoint,
- hb_codepoint_t *glyph,
- const void *base) const
- {
- if ((base+defaultUVS).bfind (codepoint))
+ inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph,
+ const void *base) const
+ {
+ int i;
+ const DefaultUVS &defaults = base+defaultUVS;
+ i = defaults.bsearch (codepoint);
+ if (i != -1)
return GLYPH_VARIANT_USE_DEFAULT;
- const UVSMapping &nonDefault = (base+nonDefaultUVS).bsearch (codepoint);
- if (nonDefault.glyphID)
+ const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
+ i = nonDefaults.bsearch (codepoint);
+ if (i != -1)
{
- *glyph = nonDefault.glyphID;
+ *glyph = nonDefaults[i].glyphID;
return GLYPH_VARIANT_FOUND;
}
return GLYPH_VARIANT_NOT_FOUND;
}
- VariationSelectorRecord(const VariationSelectorRecord& other)
+ inline int cmp (const hb_codepoint_t &variation_selector) const
{
- *this = other;
+ return varSelector.cmp (variation_selector);
}
- void operator= (const VariationSelectorRecord& other)
- {
- varSelector = other.varSelector;
- HBUINT32 offset = other.defaultUVS;
- defaultUVS = offset;
- offset = other.nonDefaultUVS;
- nonDefaultUVS = offset;
- }
-
- void collect_unicodes (hb_set_t *out, const void *base) const
- {
- (base+defaultUVS).collect_unicodes (out);
- (base+nonDefaultUVS).collect_unicodes (out);
- }
-
- void collect_mapping (const void *base,
- hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- (base+defaultUVS).collect_unicodes (unicodes);
- (base+nonDefaultUVS).collect_mapping (unicodes, mapping);
- }
-
- int cmp (const hb_codepoint_t &variation_selector) const
- { return varSelector.cmp (variation_selector); }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -1155,177 +379,25 @@ struct VariationSelectorRecord
nonDefaultUVS.sanitize (c, base));
}
- hb_pair_t<unsigned, unsigned>
- copy (hb_serialize_context_t *c,
- const hb_set_t *unicodes,
- const hb_set_t *glyphs_requested,
- const hb_map_t *glyph_map,
- const void *base) const
- {
- auto snap = c->snapshot ();
- auto *out = c->embed<VariationSelectorRecord> (*this);
- if (unlikely (!out)) return hb_pair (0, 0);
-
- out->defaultUVS = 0;
- out->nonDefaultUVS = 0;
-
- unsigned non_default_uvs_objidx = 0;
- if (nonDefaultUVS != 0)
- {
- c->push ();
- if (c->copy (base+nonDefaultUVS, unicodes, glyphs_requested, glyph_map))
- non_default_uvs_objidx = c->pop_pack ();
- else c->pop_discard ();
- }
-
- unsigned default_uvs_objidx = 0;
- if (defaultUVS != 0)
- {
- c->push ();
- if (c->copy (base+defaultUVS, unicodes))
- default_uvs_objidx = c->pop_pack ();
- else c->pop_discard ();
- }
-
-
- if (!default_uvs_objidx && !non_default_uvs_objidx)
- c->revert (snap);
-
- return hb_pair (default_uvs_objidx, non_default_uvs_objidx);
- }
-
- HBUINT24 varSelector; /* Variation selector. */
- Offset32To<DefaultUVS>
- defaultUVS; /* Offset to Default UVS Table. May be 0. */
- Offset32To<NonDefaultUVS>
- nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
+ UINT24 varSelector; /* Variation selector. */
+ LOffsetTo<DefaultUVS>
+ defaultUVS; /* Offset to Default UVS Table. May be 0. */
+ LOffsetTo<NonDefaultUVS>
+ nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
public:
DEFINE_SIZE_STATIC (11);
};
struct CmapSubtableFormat14
{
- glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph) const
- { return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); }
-
- void collect_variation_selectors (hb_set_t *out) const
- {
- for (const auto& a : record.as_array ())
- out->add (a.varSelector);
- }
- void collect_variation_unicodes (hb_codepoint_t variation_selector,
- hb_set_t *out) const
- { record.bsearch (variation_selector).collect_unicodes (out, this); }
-
- void serialize (hb_serialize_context_t *c,
- const hb_set_t *unicodes,
- const hb_set_t *glyphs_requested,
- const hb_map_t *glyph_map,
- const void *base)
- {
- auto snap = c->snapshot ();
- unsigned table_initpos = c->length ();
- const char* init_tail = c->tail;
-
- if (unlikely (!c->extend_min (this))) return;
- this->format = 14;
-
- auto src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (base);
-
- /*
- * Some versions of OTS require that offsets are in order. Due to the use
- * of push()/pop_pack() serializing the variation records in order results
- * in the offsets being in reverse order (first record has the largest
- * offset). While this is perfectly valid, it will cause some versions of
- * OTS to consider this table bad.
- *
- * So to prevent this issue we serialize the variation records in reverse
- * order, so that the offsets are ordered from small to large. Since
- * variation records are supposed to be in increasing order of varSelector
- * we then have to reverse the order of the written variation selector
- * records after everything is finalized.
- */
- hb_vector_t<hb_pair_t<unsigned, unsigned>> obj_indices;
- for (int i = src_tbl->record.len - 1; i >= 0; i--)
- {
- hb_pair_t<unsigned, unsigned> result = src_tbl->record[i].copy (c, unicodes, glyphs_requested, glyph_map, base);
- if (result.first || result.second)
- obj_indices.push (result);
- }
-
- if (c->length () - table_initpos == CmapSubtableFormat14::min_size)
- {
- c->revert (snap);
- return;
- }
-
- if (unlikely (!c->check_success (!obj_indices.in_error ())))
- return;
-
- int tail_len = init_tail - c->tail;
- c->check_assign (this->length, c->length () - table_initpos + tail_len,
- HB_SERIALIZE_ERROR_INT_OVERFLOW);
- c->check_assign (this->record.len,
- (c->length () - table_initpos - CmapSubtableFormat14::min_size) /
- VariationSelectorRecord::static_size,
- HB_SERIALIZE_ERROR_INT_OVERFLOW);
-
- /* Correct the incorrect write order by reversing the order of the variation
- records array. */
- _reverse_variation_records ();
-
- /* Now that records are in the right order, we can set up the offsets. */
- _add_links_to_variation_records (c, obj_indices);
- }
-
- void _reverse_variation_records ()
- {
- record.as_array ().reverse ();
- }
-
- void _add_links_to_variation_records (hb_serialize_context_t *c,
- const hb_vector_t<hb_pair_t<unsigned, unsigned>>& obj_indices)
- {
- for (unsigned i = 0; i < obj_indices.length; i++)
- {
- /*
- * Since the record array has been reversed (see comments in copy())
- * but obj_indices has not been, the indices at obj_indices[i]
- * are for the variation record at record[j].
- */
- int j = obj_indices.length - 1 - i;
- c->add_link (record[j].defaultUVS, obj_indices[i].first);
- c->add_link (record[j].nonDefaultUVS, obj_indices[i].second);
- }
- }
-
- void closure_glyphs (const hb_set_t *unicodes,
- hb_set_t *glyphset) const
+ inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph) const
{
- + hb_iter (record)
- | hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS)
- | hb_map (&VariationSelectorRecord::nonDefaultUVS)
- | hb_map (hb_add (this))
- | hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); })
- ;
+ return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
}
- void collect_unicodes (hb_set_t *out) const
- {
- for (const VariationSelectorRecord& _ : record)
- _.collect_unicodes (out, this);
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping /* OUT */) const
- {
- for (const VariationSelectorRecord& _ : record)
- _.collect_mapping (this, unicodes, mapping);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -1333,9 +405,9 @@ struct CmapSubtableFormat14
}
protected:
- HBUINT16 format; /* Format number is set to 14. */
- HBUINT32 length; /* Byte length of this subtable. */
- SortedArray32Of<VariationSelectorRecord>
+ 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:
@@ -1346,81 +418,22 @@ struct CmapSubtable
{
/* Note: We intentionally do NOT implement subtable formats 2 and 8. */
- bool get_glyph (hb_codepoint_t codepoint,
- hb_codepoint_t *glyph) const
+ inline bool get_glyph (hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph) const
{
switch (u.format) {
- case 0: return u.format0 .get_glyph (codepoint, glyph);
- case 4: return u.format4 .get_glyph (codepoint, glyph);
- case 6: return u.format6 .get_glyph (codepoint, glyph);
- case 10: return u.format10.get_glyph (codepoint, glyph);
- case 12: return u.format12.get_glyph (codepoint, glyph);
- case 13: return u.format13.get_glyph (codepoint, glyph);
+ case 0: return u.format0 .get_glyph(codepoint, glyph);
+ case 4: return u.format4 .get_glyph(codepoint, glyph);
+ case 6: return u.format6 .get_glyph(codepoint, glyph);
+ case 10: return u.format10.get_glyph(codepoint, glyph);
+ case 12: return u.format12.get_glyph(codepoint, glyph);
+ case 13: return u.format13.get_glyph(codepoint, glyph);
case 14:
default: return false;
}
}
- void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const
- {
- switch (u.format) {
- case 0: u.format0 .collect_unicodes (out); return;
- case 4: u.format4 .collect_unicodes (out); return;
- case 6: u.format6 .collect_unicodes (out); return;
- case 10: u.format10.collect_unicodes (out); return;
- case 12: u.format12.collect_unicodes (out, num_glyphs); return;
- case 13: u.format13.collect_unicodes (out, num_glyphs); return;
- case 14:
- default: return;
- }
- }
-
- void collect_mapping (hb_set_t *unicodes, /* OUT */
- hb_map_t *mapping, /* OUT */
- unsigned num_glyphs = UINT_MAX) const
- {
- switch (u.format) {
- case 0: u.format0 .collect_mapping (unicodes, mapping); return;
- case 4: u.format4 .collect_mapping (unicodes, mapping); return;
- case 6: u.format6 .collect_mapping (unicodes, mapping); return;
- case 10: u.format10.collect_mapping (unicodes, mapping); return;
- case 12: u.format12.collect_mapping (unicodes, mapping, num_glyphs); return;
- case 13: u.format13.collect_mapping (unicodes, mapping, num_glyphs); return;
- case 14:
- default: return;
- }
- }
-
- unsigned get_language () const
- {
- switch (u.format) {
- case 0: return u.format0 .get_language ();
- case 4: return u.format4 .get_language ();
- case 6: return u.format6 .get_language ();
- case 10: return u.format10.get_language ();
- case 12: return u.format12.get_language ();
- case 13: return u.format13.get_language ();
- case 14:
- default: return 0;
- }
- }
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it,
- unsigned format,
- const hb_subset_plan_t *plan,
- const void *base)
- {
- switch (format) {
- case 4: return u.format4.serialize (c, it);
- case 12: return u.format12.serialize (c, it);
- case 14: return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base);
- default: return;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
@@ -1438,7 +451,7 @@ struct CmapSubtable
public:
union {
- HBUINT16 format; /* Format identifier */
+ UINT16 format; /* Format identifier */
CmapSubtableFormat0 format0;
CmapSubtableFormat4 format4;
CmapSubtableFormat6 format6;
@@ -1454,7 +467,7 @@ struct CmapSubtable
struct EncodingRecord
{
- int cmp (const EncodingRecord &other) const
+ inline int cmp (const EncodingRecord &other) const
{
int ret;
ret = platformID.cmp (other.platformID);
@@ -1464,628 +477,190 @@ struct EncodingRecord
return 0;
}
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
subtable.sanitize (c, base));
}
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- EncodingRecord* copy (hb_serialize_context_t *c,
- Iterator it,
- unsigned format,
- const void *base,
- const hb_subset_plan_t *plan,
- /* INOUT */ unsigned *objidx) const
- {
- TRACE_SERIALIZE (this);
- auto snap = c->snapshot ();
- auto *out = c->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
- out->subtable = 0;
-
- if (*objidx == 0)
- {
- CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
- unsigned origin_length = c->length ();
- cmapsubtable->serialize (c, it, format, plan, &(base+subtable));
- if (c->length () - origin_length > 0) *objidx = c->pop_pack ();
- else c->pop_discard ();
- }
-
- if (*objidx == 0)
- {
- c->revert (snap);
- return_trace (nullptr);
- }
-
- c->add_link (out->subtable, *objidx);
- return_trace (out);
- }
-
- HBUINT16 platformID; /* Platform ID. */
- HBUINT16 encodingID; /* Platform-specific encoding ID. */
- Offset32To<CmapSubtable>
+ 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);
};
-struct cmap;
-
-struct SubtableUnicodesCache {
-
- private:
- hb_blob_ptr_t<cmap> base_blob;
- const char* base;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> cached_unicodes;
-
- public:
-
- static SubtableUnicodesCache* create (hb_blob_ptr_t<cmap> source_table)
- {
- SubtableUnicodesCache* cache =
- (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache));
- new (cache) SubtableUnicodesCache (source_table);
- return cache;
- }
-
- static void destroy (void* value) {
- if (!value) return;
-
- SubtableUnicodesCache* cache = (SubtableUnicodesCache*) value;
- cache->~SubtableUnicodesCache ();
- hb_free (cache);
- }
-
- SubtableUnicodesCache(const void* cmap_base)
- : base_blob(),
- base ((const char*) cmap_base),
- cached_unicodes ()
- {}
-
- SubtableUnicodesCache(hb_blob_ptr_t<cmap> base_blob_)
- : base_blob(base_blob_),
- base ((const char *) base_blob.get()),
- cached_unicodes ()
- {}
-
- ~SubtableUnicodesCache()
- {
- base_blob.destroy ();
- }
-
- bool same_base(const void* other) const
- {
- return other == (const void*) base;
- }
-
- const hb_set_t* set_for (const EncodingRecord* record,
- SubtableUnicodesCache& mutable_cache) const
- {
- if (cached_unicodes.has ((unsigned) ((const char *) record - base)))
- return cached_unicodes.get ((unsigned) ((const char *) record - base));
-
- return mutable_cache.set_for (record);
- }
-
- const hb_set_t* set_for (const EncodingRecord* record)
- {
- if (!cached_unicodes.has ((unsigned) ((const char *) record - base)))
- {
- hb_set_t *s = hb_set_create ();
- if (unlikely (s->in_error ()))
- return hb_set_get_empty ();
-
- (base+record->subtable).collect_unicodes (s);
-
- if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr<hb_set_t> {s})))
- return hb_set_get_empty ();
-
- return s;
- }
- return cached_unicodes.get ((unsigned) ((const char *) record - base));
- }
-
-};
-
-static inline uint_fast16_t
-_hb_symbol_pua_map (unsigned codepoint)
-{
- 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:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
- * under "Non-Standard (Symbol) Fonts". */
- return 0xF000u + codepoint;
- }
- return 0;
-}
-
struct cmap
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
-
-
- static SubtableUnicodesCache* create_filled_cache(hb_blob_ptr_t<cmap> source_table) {
- const cmap* cmap = source_table.get();
- auto it =
- + hb_iter (cmap->encodingRecord)
- | hb_filter ([&](const EncodingRecord& _) {
- return cmap::filter_encoding_records_for_subset (cmap, _);
- })
- ;
-
- SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table);
- for (const EncodingRecord& _ : it)
- cache->set_for(&_); // populate the cache for this encoding record.
-
- return cache;
- }
+ static const hb_tag_t tableTag = HB_OT_TAG_cmap;
- template<typename Iterator, typename EncodingRecIter,
- hb_requires (hb_is_iterator (EncodingRecIter))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- EncodingRecIter encodingrec_iter,
- const void *base,
- hb_subset_plan_t *plan,
- bool drop_format_4 = false)
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
- if (unlikely (!c->extend_min ((*this)))) return false;
- this->version = 0;
-
- unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
- auto snap = c->snapshot ();
-
- SubtableUnicodesCache local_unicodes_cache (base);
- const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache;
-
- if (plan->accelerator &&
- plan->accelerator->cmap_cache &&
- plan->accelerator->cmap_cache->same_base (base))
- unicodes_cache = plan->accelerator->cmap_cache;
-
- for (const EncodingRecord& _ : encodingrec_iter)
- {
- if (c->in_error ())
- return false;
-
- unsigned format = (base+_.subtable).u.format;
- if (format != 4 && format != 12 && format != 14) continue;
-
- const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache);
-
- if (!drop_format_4 && format == 4)
- {
- c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 4u, base, plan, &format4objidx);
- if (c->in_error () && c->only_overflow ())
- {
- // cmap4 overflowed, reset and retry serialization without format 4 subtables.
- c->revert (snap);
- return serialize (c, it,
- encodingrec_iter,
- base,
- plan,
- true);
- }
- }
-
- else if (format == 12)
- {
- if (_can_drop (_,
- *unicodes_set,
- base,
- *unicodes_cache,
- local_unicodes_cache,
- + it | hb_map (hb_first), encodingrec_iter))
- continue;
- c->copy (_, + it | hb_filter (*unicodes_set, hb_first), 12u, base, plan, &format12objidx);
- }
- else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx);
- }
- c->check_assign(this->encodingRecord.len,
- (c->length () - cmap::min_size)/EncodingRecord::static_size,
- HB_SERIALIZE_ERROR_INT_OVERFLOW);
-
- // Fail if format 4 was dropped and there is no cmap12.
- return !drop_format_4 || format12objidx;
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ likely (version == 0) &&
+ encodingRecord.sanitize (c, this));
}
- template<typename Iterator, typename EncodingRecordIterator,
- hb_requires (hb_is_iterator (Iterator)),
- hb_requires (hb_is_iterator (EncodingRecordIterator))>
- bool _can_drop (const EncodingRecord& cmap12,
- const hb_set_t& cmap12_unicodes,
- const void* base,
- const SubtableUnicodesCache& unicodes_cache,
- SubtableUnicodesCache& local_unicodes_cache,
- Iterator subset_unicodes,
- EncodingRecordIterator encoding_records)
+ struct accelerator_t
{
- for (auto cp : + subset_unicodes | hb_filter (cmap12_unicodes))
- {
- if (cp >= 0x10000) return false;
- }
-
- unsigned target_platform;
- unsigned target_encoding;
- unsigned target_language = (base+cmap12.subtable).get_language ();
-
- if (cmap12.platformID == 0 && cmap12.encodingID == 4)
- {
- target_platform = 0;
- target_encoding = 3;
- } else if (cmap12.platformID == 3 && cmap12.encodingID == 10) {
- target_platform = 3;
- target_encoding = 1;
- } else {
- return false;
- }
-
- for (const auto& _ : encoding_records)
- {
- if (_.platformID != target_platform
- || _.encodingID != target_encoding
- || (base+_.subtable).get_language() != target_language)
- continue;
-
- const hb_set_t* sibling_unicodes = unicodes_cache.set_for (&_, local_unicodes_cache);
-
- auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes);
- auto sibling = + subset_unicodes | hb_filter (*sibling_unicodes);
- for (; cmap12 && sibling; cmap12++, sibling++)
+ 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)
{
- unsigned a = *cmap12;
- unsigned b = *sibling;
- if (a != b) return false;
+ subtable = cmap->find_subtable (3, 0);
+ if (subtable) symbol = true;
}
+ /* Meh. */
+ if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
- return !cmap12 && !sibling;
- }
-
- return false;
- }
-
- void closure_glyphs (const hb_set_t *unicodes,
- hb_set_t *glyphset) const
- {
- + hb_iter (encodingRecord)
- | hb_map (&EncodingRecord::subtable)
- | hb_map (hb_add (this))
- | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; })
- | hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); })
- ;
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- cmap *cmap_prime = c->serializer->start_embed<cmap> ();
- if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
-
- auto encodingrec_iter =
- + hb_iter (encodingRecord)
- | hb_filter ([&](const EncodingRecord& _) {
- return cmap::filter_encoding_records_for_subset (this, _);
- })
- ;
-
- if (unlikely (!encodingrec_iter.len ())) return_trace (false);
-
- const EncodingRecord *unicode_bmp= nullptr, *unicode_ucs4 = nullptr, *ms_bmp = nullptr, *ms_ucs4 = nullptr;
- bool has_format12 = false;
-
- for (const EncodingRecord& _ : encodingrec_iter)
- {
- unsigned format = (this + _.subtable).u.format;
- if (format == 12) has_format12 = true;
-
- const EncodingRecord *table = std::addressof (_);
- if (_.platformID == 0 && _.encodingID == 3) unicode_bmp = table;
- else if (_.platformID == 0 && _.encodingID == 4) unicode_ucs4 = table;
- else if (_.platformID == 3 && _.encodingID == 1) ms_bmp = table;
- else if (_.platformID == 3 && _.encodingID == 10) ms_ucs4 = table;
- }
-
- if (unlikely (!has_format12 && !unicode_bmp && !ms_bmp)) return_trace (false);
- if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
-
- auto it =
- + c->plan->unicode_to_new_gid_list.iter ()
- | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
- { return (_.second != HB_MAP_VALUE_INVALID); })
- ;
-
- return_trace (cmap_prime->serialize (c->serializer,
- it,
- encodingrec_iter,
- this,
- c->plan));
- }
-
- const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const
- {
- if (symbol) *symbol = false;
-
- const CmapSubtable *subtable;
-
- /* Symbol subtable.
- * Prefer symbol if available.
- * https://github.com/harfbuzz/harfbuzz/issues/1918 */
- if ((subtable = this->find_subtable (3, 0)))
- {
- if (symbol) *symbol = true;
- return subtable;
- }
-
- /* 32-bit subtables. */
- if ((subtable = this->find_subtable (3, 10))) return subtable;
- if ((subtable = this->find_subtable (0, 6))) return subtable;
- if ((subtable = this->find_subtable (0, 4))) return subtable;
-
- /* 16-bit subtables. */
- if ((subtable = this->find_subtable (3, 1))) return subtable;
- if ((subtable = this->find_subtable (0, 3))) return subtable;
- if ((subtable = this->find_subtable (0, 2))) return subtable;
- if ((subtable = this->find_subtable (0, 1))) return subtable;
- if ((subtable = this->find_subtable (0, 0))) return subtable;
-
- /* Meh. */
- return &Null (CmapSubtable);
- }
-
- struct accelerator_t
- {
- using cache_t = hb_cache_t<21, 16, 8, true>;
-
- accelerator_t (hb_face_t *face)
- {
- this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
- bool symbol;
- this->subtable = table->find_best_subtable (&symbol);
- this->subtable_uvs = &Null (CmapSubtableFormat14);
+ /* UVS subtable. */
+ if (!subtable_uvs)
{
- const CmapSubtable *st = table->find_subtable (0, 5);
+ 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))
- {
- switch ((unsigned) face->table.OS2->get_font_page ()) {
- case OS2::font_page_t::FONT_PAGE_NONE:
- this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_symbol_pua_map>;
- break;
-#ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK
- case OS2::font_page_t::FONT_PAGE_SIMP_ARABIC:
- this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_simp_map>;
- break;
- case OS2::font_page_t::FONT_PAGE_TRAD_ARABIC:
- this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable, _hb_arabic_pua_trad_map>;
- break;
-#endif
- default:
- this->get_glyph_funcZ = get_glyph_from<CmapSubtable>;
- break;
- }
- }
+ 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_funcZ = get_glyph_from<CmapSubtable>;
- break;
- case 12:
- this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
- break;
+ 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_funcZ = this->format4_accel.get_glyph_func;
+ {
+ 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;
}
- }
- }
}
- ~accelerator_t () { this->table.destroy (); }
- inline bool _cached_get (hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- cache_t *cache) const
+ inline void fini (void)
{
- unsigned v;
- if (cache && cache->get (unicode, &v))
- {
- *glyph = v;
- return true;
- }
- bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
-
- if (cache && ret)
- cache->set (unicode, *glyph);
- return ret;
- }
-
- bool get_nominal_glyph (hb_codepoint_t unicode,
- hb_codepoint_t *glyph,
- cache_t *cache = nullptr) const
- {
- if (unlikely (!this->get_glyph_funcZ)) return 0;
- return _cached_get (unicode, glyph, cache);
+ hb_blob_destroy (this->blob);
}
- unsigned int get_nominal_glyphs (unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- cache_t *cache = nullptr) const
+ inline bool get_nominal_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t *glyph) const
{
- if (unlikely (!this->get_glyph_funcZ)) return 0;
-
- unsigned int done;
- for (done = 0;
- done < count && _cached_get (*first_unicode, first_glyph, cache);
- done++)
- {
- first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- }
- return done;
+ return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
}
- bool get_variation_glyph (hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph,
- cache_t *cache = nullptr) const
+ inline bool get_variation_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph) const
{
- switch (this->subtable_uvs->get_glyph_variant (unicode,
- variation_selector,
- glyph))
+ switch (this->uvs_table->get_glyph_variant (unicode,
+ variation_selector,
+ glyph))
{
- case GLYPH_VARIANT_NOT_FOUND: return false;
- case GLYPH_VARIANT_FOUND: return true;
- case GLYPH_VARIANT_USE_DEFAULT: break;
+ 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, cache);
+ return get_nominal_glyph (unicode, glyph);
}
- void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const
- { subtable->collect_unicodes (out, num_glyphs); }
- void collect_mapping (hb_set_t *unicodes, hb_map_t *mapping,
- unsigned num_glyphs = UINT_MAX) const
- { subtable->collect_mapping (unicodes, mapping, num_glyphs); }
- void collect_variation_selectors (hb_set_t *out) const
- { subtable_uvs->collect_variation_selectors (out); }
- void collect_variation_unicodes (hb_codepoint_t variation_selector,
- hb_set_t *out) const
- { subtable_uvs->collect_variation_unicodes (variation_selector, out); }
-
protected:
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph);
- typedef uint_fast16_t (*hb_pua_remap_func_t) (unsigned);
template <typename Type>
- HB_INTERNAL static bool get_glyph_from (const void *obj,
- hb_codepoint_t codepoint,
- hb_codepoint_t *glyph)
+ 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, hb_pua_remap_func_t remap>
- HB_INTERNAL static bool get_glyph_from_symbol (const void *obj,
- hb_codepoint_t codepoint,
- hb_codepoint_t *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 (hb_codepoint_t c = remap (codepoint))
- return typed_obj->get_glyph (c, glyph);
+ 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_nonnull_ptr_t<const CmapSubtable> subtable;
- hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs;
-
- hb_cmap_get_glyph_func_t get_glyph_funcZ;
+ hb_cmap_get_glyph_func_t get_glyph_func;
const void *get_glyph_data;
+ OT::CmapSubtableFormat4::accelerator_t format4_accel;
- CmapSubtableFormat4::accelerator_t format4_accel;
-
- public:
- hb_blob_ptr_t<cmap> table;
+ const OT::CmapSubtableFormat14 *uvs_table;
+ hb_blob_t *blob;
};
protected:
- const CmapSubtable *find_subtable (unsigned int platform_id,
- unsigned int encoding_id) const
+ inline const CmapSubtable *find_subtable (unsigned int platform_id,
+ unsigned int encoding_id) const
{
EncodingRecord key;
- key.platformID = platform_id;
- key.encodingID = encoding_id;
-
- const EncodingRecord &result = encodingRecord.bsearch (key);
- if (!result.subtable)
+ key.platformID.set (platform_id);
+ key.encodingID.set (encoding_id);
+
+ /* Note: We can use bsearch, but since it has no performance
+ * implications, we use lsearch and as such accept fonts with
+ * unsorted subtable list. */
+ int result = encodingRecord./*bsearch*/lsearch (key);
+ if (result == -1 || !encodingRecord[result].subtable)
return nullptr;
- return &(this+result.subtable);
- }
-
- const EncodingRecord *find_encodingrec (unsigned int platform_id,
- unsigned int encoding_id) const
- {
- EncodingRecord key;
- key.platformID = platform_id;
- key.encodingID = encoding_id;
-
- return encodingRecord.as_array ().bsearch (key);
- }
-
- bool find_subtable (unsigned format) const
- {
- auto it =
- + hb_iter (encodingRecord)
- | hb_map (&EncodingRecord::subtable)
- | hb_map (hb_add (this))
- | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; })
- ;
-
- return it.len ();
- }
-
- public:
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version == 0) &&
- encodingRecord.sanitize (c, this));
- }
-
- private:
-
- static bool filter_encoding_records_for_subset(const cmap* cmap,
- const EncodingRecord& _)
- {
- return
- (_.platformID == 0 && _.encodingID == 3) ||
- (_.platformID == 0 && _.encodingID == 4) ||
- (_.platformID == 3 && _.encodingID == 1) ||
- (_.platformID == 3 && _.encodingID == 10) ||
- (cmap + _.subtable).u.format == 14;
+ return &(this+encodingRecord[result].subtable);
}
protected:
- HBUINT16 version; /* Table version number (0). */
- SortedArray16Of<EncodingRecord>
- encodingRecord; /* Encoding tables. */
+ UINT16 version; /* Table version number (0). */
+ SortedArrayOf<EncodingRecord>
+ encodingRecord; /* Encoding tables. */
public:
DEFINE_SIZE_ARRAY (4, encodingRecord);
};
-struct cmap_accelerator_t : cmap::accelerator_t {
- cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
-};
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc
deleted file mode 100644
index 37d42e08d94..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright © 2016 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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): Sascha Brawer, Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_COLOR
-
-#include "hb-ot.h"
-
-#include "OT/Color/CBDT/CBDT.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "OT/Color/CPAL/CPAL.hh"
-#include "OT/Color/sbix/sbix.hh"
-#include "OT/Color/svg/svg.hh"
-
-
-/**
- * SECTION:hb-ot-color
- * @title: hb-ot-color
- * @short_description: OpenType Color Fonts
- * @include: hb-ot.h
- *
- * Functions for fetching color-font information from OpenType font faces.
- *
- * HarfBuzz supports `COLR`/`CPAL`, `sbix`, `CBDT`, and `SVG` color fonts.
- **/
-
-
-/*
- * CPAL
- */
-
-
-/**
- * hb_ot_color_has_palettes:
- * @face: #hb_face_t to work upon
- *
- * Tests whether a face includes a `CPAL` color-palette table.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.1.0
- */
-hb_bool_t
-hb_ot_color_has_palettes (hb_face_t *face)
-{
- return face->table.CPAL->has_data ();
-}
-
-/**
- * hb_ot_color_palette_get_count:
- * @face: #hb_face_t to work upon
- *
- * Fetches the number of color palettes in a face.
- *
- * Return value: the number of palettes found
- *
- * Since: 2.1.0
- */
-unsigned int
-hb_ot_color_palette_get_count (hb_face_t *face)
-{
- return face->table.CPAL->get_palette_count ();
-}
-
-/**
- * hb_ot_color_palette_get_name_id:
- * @face: #hb_face_t to work upon
- * @palette_index: The index of the color palette
- *
- * Fetches the `name` table Name ID that provides display names for
- * a `CPAL` color palette.
- *
- * Palette display names can be generic (e.g., "Default") or provide
- * specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
- *
- * Return value: the Named ID found for the palette.
- * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
- *
- * Since: 2.1.0
- */
-hb_ot_name_id_t
-hb_ot_color_palette_get_name_id (hb_face_t *face,
- unsigned int palette_index)
-{
- return face->table.CPAL->get_palette_name_id (palette_index);
-}
-
-/**
- * hb_ot_color_palette_color_get_name_id:
- * @face: #hb_face_t to work upon
- * @color_index: The index of the color
- *
- * Fetches the `name` table Name ID that provides display names for
- * the specified color in a face's `CPAL` color palette.
- *
- * Display names can be generic (e.g., "Background") or specific
- * (e.g., "Eye color").
- *
- * Return value: the Name ID found for the color.
- *
- * Since: 2.1.0
- */
-hb_ot_name_id_t
-hb_ot_color_palette_color_get_name_id (hb_face_t *face,
- unsigned int color_index)
-{
- return face->table.CPAL->get_color_name_id (color_index);
-}
-
-/**
- * hb_ot_color_palette_get_flags:
- * @face: #hb_face_t to work upon
- * @palette_index: The index of the color palette
- *
- * Fetches the flags defined for a color palette.
- *
- * Return value: the #hb_ot_color_palette_flags_t of the requested color palette
- *
- * Since: 2.1.0
- */
-hb_ot_color_palette_flags_t
-hb_ot_color_palette_get_flags (hb_face_t *face,
- unsigned int palette_index)
-{
- return face->table.CPAL->get_palette_flags (palette_index);
-}
-
-/**
- * hb_ot_color_palette_get_colors:
- * @face: #hb_face_t to work upon
- * @palette_index: the index of the color palette to query
- * @start_offset: offset of the first color to retrieve
- * @color_count: (inout) (optional): Input = the maximum number of colors to return;
- * Output = the actual number of colors returned (may be zero)
- * @colors: (out) (array length=color_count) (nullable): The array of #hb_color_t records found
- *
- * Fetches a list of the colors in a color palette.
- *
- * After calling this function, @colors will be filled with the palette
- * colors. If @colors is NULL, the function will just return the number
- * of total colors without storing any actual colors; this can be used
- * for allocating a buffer of suitable size before calling
- * hb_ot_color_palette_get_colors() a second time.
- *
- * The RGBA values in the palette are unpremultiplied. See the
- * OpenType spec [CPAL](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal)
- * section for details.
- *
- * Return value: the total number of colors in the palette
- *
- * Since: 2.1.0
- */
-unsigned int
-hb_ot_color_palette_get_colors (hb_face_t *face,
- unsigned int palette_index,
- unsigned int start_offset,
- unsigned int *colors_count /* IN/OUT. May be NULL. */,
- hb_color_t *colors /* OUT. May be NULL. */)
-{
- return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
-}
-
-
-/*
- * COLR
- */
-
-/**
- * hb_ot_color_has_layers:
- * @face: #hb_face_t to work upon
- *
- * Tests whether a face includes a `COLR` table
- * with data according to COLRv0.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.1.0
- */
-hb_bool_t
-hb_ot_color_has_layers (hb_face_t *face)
-{
- return face->table.COLR->has_v0_data ();
-}
-
-/**
- * hb_ot_color_has_paint:
- * @face: #hb_face_t to work upon
- *
- * Tests where a face includes a `COLR` table
- * with data according to COLRv1.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 7.0.0
- */
-hb_bool_t
-hb_ot_color_has_paint (hb_face_t *face)
-{
- return face->table.COLR->has_v1_data ();
-}
-
-/**
- * hb_ot_color_glyph_has_paint:
- * @face: #hb_face_t to work upon
- * @glyph: The glyph index to query
- *
- * Tests where a face includes COLRv1 paint
- * data for @glyph.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 7.0.0
- */
-hb_bool_t
-hb_ot_color_glyph_has_paint (hb_face_t *face,
- hb_codepoint_t glyph)
-{
- return face->table.COLR->has_paint_for_glyph (glyph);
-}
-
-/**
- * hb_ot_color_glyph_get_layers:
- * @face: #hb_face_t to work upon
- * @glyph: The glyph index to query
- * @start_offset: offset of the first layer to retrieve
- * @layer_count: (inout) (optional): Input = the maximum number of layers to return;
- * Output = the actual number of layers returned (may be zero)
- * @layers: (out) (array length=layer_count) (nullable): The array of layers found
- *
- * Fetches a list of all color layers for the specified glyph index in the specified
- * face. The list returned will begin at the offset provided.
- *
- * Return value: Total number of layers available for the glyph index queried
- *
- * Since: 2.1.0
- */
-unsigned int
-hb_ot_color_glyph_get_layers (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int start_offset,
- unsigned int *layer_count, /* IN/OUT. May be NULL. */
- hb_ot_color_layer_t *layers /* OUT. May be NULL. */)
-{
- return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
-}
-
-
-/*
- * SVG
- */
-
-/**
- * hb_ot_color_has_svg:
- * @face: #hb_face_t to work upon.
- *
- * Tests whether a face includes any `SVG` glyph images.
- *
- * Return value: `true` if data found, `false` otherwise.
- *
- * Since: 2.1.0
- */
-hb_bool_t
-hb_ot_color_has_svg (hb_face_t *face)
-{
- return face->table.SVG->has_data ();
-}
-
-/**
- * hb_ot_color_glyph_reference_svg:
- * @face: #hb_face_t to work upon
- * @glyph: a svg glyph index
- *
- * Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
- *
- * If the glyph has no SVG document, the singleton empty blob is returned.
- *
- * Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
- *
- * Since: 2.1.0
- */
-hb_blob_t *
-hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
-{
- return face->table.SVG->reference_blob_for_glyph (glyph);
-}
-
-
-/*
- * PNG: CBDT or sbix
- */
-
-/**
- * hb_ot_color_has_png:
- * @face: #hb_face_t to work upon
- *
- * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables).
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.1.0
- */
-hb_bool_t
-hb_ot_color_has_png (hb_face_t *face)
-{
- return face->table.CBDT->has_data () || face->table.sbix->has_data ();
-}
-
-/**
- * hb_ot_color_glyph_reference_png:
- * @font: #hb_font_t to work upon
- * @glyph: a glyph index
- *
- * Fetches the PNG image for a glyph. This function takes a font object, not a face object,
- * as input. To get an optimally sized PNG blob, the PPEM values must be set on the @font
- * object. If PPEM is unset, the blob returned will be the largest PNG available.
- *
- * If the glyph has no PNG image, the singleton empty blob is returned.
- *
- * Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
- *
- * Since: 2.1.0
- */
-hb_blob_t *
-hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
-{
- hb_blob_t *blob = hb_blob_get_empty ();
-
- if (font->face->table.sbix->has_data ())
- blob = font->face->table.sbix->reference_png (font, glyph, nullptr, nullptr, nullptr);
-
- if (!blob->length && font->face->table.CBDT->has_data ())
- blob = font->face->table.CBDT->reference_png (font, glyph);
-
- return blob;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h
deleted file mode 100644
index 22ee497e388..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-color.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright © 2016 Google, Inc.
- * Copyright © 2018 Khaled Hosny
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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): Sascha Brawer, Behdad Esfahbod
- */
-
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_COLOR_H
-#define HB_OT_COLOR_H
-
-#include "hb.h"
-#include "hb-ot-name.h"
-
-HB_BEGIN_DECLS
-
-
-/*
- * Color palettes.
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_palettes (hb_face_t *face);
-
-HB_EXTERN unsigned int
-hb_ot_color_palette_get_count (hb_face_t *face);
-
-HB_EXTERN hb_ot_name_id_t
-hb_ot_color_palette_get_name_id (hb_face_t *face,
- unsigned int palette_index);
-
-HB_EXTERN hb_ot_name_id_t
-hb_ot_color_palette_color_get_name_id (hb_face_t *face,
- unsigned int color_index);
-
-/**
- * hb_ot_color_palette_flags_t:
- * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: Default indicating that there is nothing special
- * to note about a color palette.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: Flag indicating that the color
- * palette is appropriate to use when displaying the font on a light background such as white.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color
- * palette is appropriate to use when displaying the font on a dark background such as black.
- *
- * Flags that describe the properties of color palette.
- *
- * Since: 2.1.0
- */
-typedef enum { /*< flags >*/
- HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u,
- HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND = 0x00000001u,
- HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND = 0x00000002u
-} hb_ot_color_palette_flags_t;
-
-HB_EXTERN hb_ot_color_palette_flags_t
-hb_ot_color_palette_get_flags (hb_face_t *face,
- unsigned int palette_index);
-
-HB_EXTERN unsigned int
-hb_ot_color_palette_get_colors (hb_face_t *face,
- unsigned int palette_index,
- unsigned int start_offset,
- unsigned int *color_count, /* IN/OUT. May be NULL. */
- hb_color_t *colors /* OUT. May be NULL. */);
-
-
-/*
- * Color layers.
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_layers (hb_face_t *face);
-
-/**
- * hb_ot_color_layer_t:
- * @glyph: the glyph ID of the layer
- * @color_index: the palette color index of the layer
- *
- * Pairs of glyph and color index.
- *
- * A color index of 0xFFFF does not refer to a palette
- * color, but indicates that the foreground color should
- * be used.
- *
- * Since: 2.1.0
- **/
-typedef struct hb_ot_color_layer_t {
- hb_codepoint_t glyph;
- unsigned int color_index;
-} hb_ot_color_layer_t;
-
-HB_EXTERN unsigned int
-hb_ot_color_glyph_get_layers (hb_face_t *face,
- hb_codepoint_t glyph,
- unsigned int start_offset,
- unsigned int *layer_count, /* IN/OUT. May be NULL. */
- hb_ot_color_layer_t *layers /* OUT. May be NULL. */);
-
-/* COLRv1 */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_paint (hb_face_t *face);
-
-HB_EXTERN hb_bool_t
-hb_ot_color_glyph_has_paint (hb_face_t *face,
- hb_codepoint_t glyph);
-
-/*
- * SVG
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_svg (hb_face_t *face);
-
-HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph);
-
-/*
- * PNG: CBDT or sbix
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_color_has_png (hb_face_t *face);
-
-HB_EXTERN hb_blob_t *
-hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph);
-
-
-HB_END_DECLS
-
-#endif /* HB_OT_COLOR_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h
deleted file mode 100644
index 60672ab1283..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-deprecated.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright © 2018 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
- */
-
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_DEPRECATED_H
-#define HB_OT_DEPRECATED_H
-
-#include "hb.h"
-#include "hb-ot-name.h"
-
-
-HB_BEGIN_DECLS
-
-#ifndef HB_DISABLE_DEPRECATED
-
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1734 */
-/**
- * HB_MATH_GLYPH_PART_FLAG_EXTENDER:
- *
- * Use #HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER instead.
- *
- * Deprecated: 2.5.1
- */
-#define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER
-
-/* https://github.com/harfbuzz/harfbuzz/pull/3417 */
-/**
- * HB_OT_MATH_SCRIPT:
- *
- * Use #HB_SCRIPT_MATH or #HB_OT_TAG_MATH_SCRIPT instead.
- *
- * <note>Previous versions of this documentation recommended passing
- * #HB_OT_MATH_SCRIPT to hb_buffer_set_script() to enable math shaping, but this
- * usage is no longer supported. Use #HB_SCRIPT_MATH instead.</note>
- *
- * Since: 1.3.3
- * Deprecated: 3.4.0
- */
-#define HB_OT_MATH_SCRIPT HB_OT_TAG_MATH_SCRIPT
-
-
-/* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
-HB_DEPRECATED_FOR (hb_ot_layout_table_select_script)
-HB_EXTERN hb_bool_t
-hb_ot_layout_table_choose_script (hb_face_t *face,
- hb_tag_t table_tag,
- const hb_tag_t *script_tags,
- unsigned int *script_index,
- hb_tag_t *chosen_script);
-
-HB_DEPRECATED_FOR (hb_ot_layout_script_select_language)
-HB_EXTERN hb_bool_t
-hb_ot_layout_script_find_language (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_index,
- hb_tag_t language_tag,
- unsigned int *language_index);
-
-HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language)
-HB_EXTERN void
-hb_ot_tags_from_script (hb_script_t script,
- hb_tag_t *script_tag_1,
- hb_tag_t *script_tag_2);
-
-HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language)
-HB_EXTERN hb_tag_t
-hb_ot_tag_from_language (hb_language_t language);
-
-
-/**
- * HB_OT_VAR_NO_AXIS_INDEX:
- *
- * Do not use.
- *
- * Since: 1.4.2
- * Deprecated: 2.2.0
- */
-#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu
-
-/**
- * hb_ot_var_axis_t:
- * @tag: axis tag
- * @name_id: axis name identifier
- * @min_value: minimum value of the axis
- * @default_value: default value of the axis
- * @max_value: maximum value of the axis
- *
- * Use #hb_ot_var_axis_info_t instead.
- *
- * Since: 1.4.2
- * Deprecated: 2.2.0
- */
-typedef struct hb_ot_var_axis_t {
- hb_tag_t tag;
- hb_ot_name_id_t name_id;
- float min_value;
- float default_value;
- float max_value;
-} hb_ot_var_axis_t;
-
-HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos)
-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_DEPRECATED_FOR (hb_ot_var_find_axis_info)
-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);
-
-
-#endif
-
-HB_END_DECLS
-
-#endif /* HB_OT_DEPRECATED_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh
deleted file mode 100644
index b552dfdd9da..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-face-table-list.hh
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2012,2013 Google, Inc.
- * Copyright © 2019, Facebook 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
- * Google Author(s): Behdad Esfahbod
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_FACE_TABLE_LIST_HH
-#define HB_OT_FACE_TABLE_LIST_HH
-#endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
-
-#ifndef HB_OT_CORE_TABLE
-#define HB_OT_CORE_TABLE(Namespace, Type) HB_OT_TABLE (Namespace, Type)
-#define _HB_OT_CORE_TABLE_UNDEF
-#endif
-
-#ifndef HB_OT_ACCELERATOR
-#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
-#define _HB_OT_ACCELERATOR_UNDEF
-#endif
-
-
-/* This lists font tables that the hb_face_t will contain and lazily
- * load. Don't add a table unless it's used though. This is not
- * exactly zero-cost. */
-
-/* v--- Add new tables in the right place here. */
-
-
-/* OpenType fundamentals. */
-HB_OT_CORE_TABLE (OT, head)
-HB_OT_CORE_TABLE (OT, maxp)
-#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
-HB_OT_ACCELERATOR (OT, cmap)
-#endif
-HB_OT_CORE_TABLE (OT, hhea)
-HB_OT_ACCELERATOR (OT, hmtx)
-HB_OT_CORE_TABLE (OT, OS2)
-#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE)
-HB_OT_ACCELERATOR (OT, post)
-#endif
-#ifndef HB_NO_NAME
-HB_OT_ACCELERATOR (OT, name)
-#endif
-#ifndef HB_NO_STYLE
-HB_OT_CORE_TABLE (OT, STAT)
-#endif
-#ifndef HB_NO_META
-HB_OT_ACCELERATOR (OT, meta)
-#endif
-
-/* Vertical layout. */
-#ifndef HB_NO_VERTICAL
-HB_OT_CORE_TABLE (OT, vhea)
-HB_OT_ACCELERATOR (OT, vmtx)
-HB_OT_CORE_TABLE (OT, VORG)
-#endif
-
-/* TrueType outlines. */
-HB_OT_CORE_TABLE (OT, loca) // Also used to determine number of glyphs
-HB_OT_ACCELERATOR (OT, glyf)
-
-/* CFF outlines. */
-#ifndef HB_NO_CFF
-HB_OT_ACCELERATOR (OT, cff1)
-HB_OT_ACCELERATOR (OT, cff2)
-#endif
-
-/* OpenType variations. */
-#ifndef HB_NO_VAR
-HB_OT_CORE_TABLE (OT, fvar)
-HB_OT_CORE_TABLE (OT, avar)
-HB_OT_CORE_TABLE (OT, cvar)
-HB_OT_ACCELERATOR (OT, gvar)
-HB_OT_CORE_TABLE (OT, MVAR)
-#endif
-
-/* Legacy kern. */
-#ifndef HB_NO_OT_KERN
-HB_OT_CORE_TABLE (OT, kern)
-#endif
-
-/* OpenType shaping. */
-#ifndef HB_NO_OT_LAYOUT
-HB_OT_ACCELERATOR (OT, GDEF)
-HB_OT_ACCELERATOR (OT, GSUB)
-HB_OT_ACCELERATOR (OT, GPOS)
-//HB_OT_CORE_TABLE (OT, JSTF)
-#endif
-
-/* OpenType baseline. */
-#ifndef HB_NO_BASE
-HB_OT_CORE_TABLE (OT, BASE)
-#endif
-
-/* AAT shaping. */
-#ifndef HB_NO_AAT
-HB_OT_TABLE (AAT, morx)
-HB_OT_TABLE (AAT, mort)
-HB_OT_TABLE (AAT, kerx)
-HB_OT_TABLE (AAT, ankr)
-HB_OT_TABLE (AAT, trak)
-HB_OT_TABLE (AAT, ltag)
-HB_OT_TABLE (AAT, feat)
-// HB_OT_TABLE (AAT, opbd)
-#endif
-
-/* OpenType color fonts. */
-#ifndef HB_NO_COLOR
-HB_OT_CORE_TABLE (OT, COLR)
-HB_OT_CORE_TABLE (OT, CPAL)
-HB_OT_ACCELERATOR (OT, CBDT)
-HB_OT_ACCELERATOR (OT, sbix)
-HB_OT_ACCELERATOR (OT, SVG)
-#endif
-
-/* OpenType math. */
-#ifndef HB_NO_MATH
-HB_OT_CORE_TABLE (OT, MATH)
-#endif
-
-
-#ifdef _HB_OT_ACCELERATOR_UNDEF
-#undef HB_OT_ACCELERATOR
-#endif
-
-#ifdef _HB_OT_CORE_TABLE_UNDEF
-#undef HB_OT_CORE_TABLE
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-face.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-face.hh
deleted file mode 100644
index 415dae8e209..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-face.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2012,2013 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_FACE_HH
-#define HB_OT_FACE_HH
-
-#include "hb.hh"
-
-#include "hb-machinery.hh"
-
-
-/*
- * hb_ot_face_t
- */
-
-/* Declare tables. */
-#define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
-#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t)
-#include "hb-ot-face-table-list.hh"
-#undef HB_OT_ACCELERATOR
-#undef HB_OT_TABLE
-
-struct hb_ot_face_t
-{
- HB_INTERNAL void init0 (hb_face_t *face);
- HB_INTERNAL void fini ();
-
-#define HB_OT_TABLE_ORDER(Namespace, Type) \
- HB_PASTE (ORDER_, HB_PASTE (Namespace, HB_PASTE (_, Type)))
- enum order_t
- {
- ORDER_ZERO,
-#define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type),
-#include "hb-ot-face-table-list.hh"
-#undef HB_OT_TABLE
- };
-
- hb_face_t *face; /* MUST be JUST before the lazy loaders. */
-#define HB_OT_TABLE(Namespace, Type) \
- hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
-#define HB_OT_CORE_TABLE(Namespace, Type) \
- hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type), true> Type;
-#define HB_OT_ACCELERATOR(Namespace, Type) \
- hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
-#include "hb-ot-face-table-list.hh"
-#undef HB_OT_ACCELERATOR
-#undef HB_OT_CORE_TABLE
-#undef HB_OT_TABLE
-};
-
-
-#endif /* HB_OT_FACE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
index 06f7092a59d..9864064b112 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
@@ -24,137 +24,78 @@
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_FONT
+#include "hb-private.hh"
#include "hb-ot.h"
-#include "hb-cache.hh"
-#include "hb-font.hh"
-#include "hb-machinery.hh"
-#include "hb-ot-face.hh"
-#include "hb-outline.hh"
+#include "hb-font-private.hh"
#include "hb-ot-cmap-table.hh"
+#include "hb-ot-cbdt-table.hh"
#include "hb-ot-glyf-table.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
#include "hb-ot-hmtx-table.hh"
+#include "hb-ot-kern-table.hh"
#include "hb-ot-post-table.hh"
-#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-ot-vorg-table.hh"
-#include "OT/Color/CBDT/CBDT.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "OT/Color/sbix/sbix.hh"
-#include "OT/Color/svg/svg.hh"
-
-/**
- * SECTION:hb-ot-font
- * @title: hb-ot-font
- * @short_description: OpenType font implementation
- * @include: hb-ot.h
- *
- * Functions for using OpenType fonts with hb_shape(). Note that fonts returned
- * by hb_font_create() default to using these functions, so most clients would
- * never need to call these functions directly.
- **/
-
-using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>;
-using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
-
-static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
struct hb_ot_font_t
{
- const hb_ot_face_t *ot_face;
-
- hb_ot_font_cmap_cache_t *cmap_cache;
-
- /* h_advance caching */
- mutable hb_atomic_int_t cached_coords_serial;
- mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
+ 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;
};
+
static hb_ot_font_t *
-_hb_ot_font_create (hb_font_t *font)
+_hb_ot_font_create (hb_face_t *face)
{
- hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
+ hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
+
if (unlikely (!ot_font))
return nullptr;
- ot_font->ot_face = &font->face->table;
-
- // retry:
- auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
- &hb_ot_font_cmap_cache_user_data_key);
- if (!cmap_cache)
- {
- cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
- if (unlikely (!cmap_cache)) goto out;
- cmap_cache->init ();
- if (unlikely (!hb_face_set_user_data (font->face,
- &hb_ot_font_cmap_cache_user_data_key,
- cmap_cache,
- hb_free,
- false)))
- {
- hb_free (cmap_cache);
- cmap_cache = nullptr;
- /* Normally we would retry here, but that would
- * infinite-loop if the face is the empty-face.
- * Just let it go and this font will be uncached if it
- * happened to collide with another thread creating the
- * cache at the same time. */
- // goto retry;
- }
- }
- out:
- ot_font->cmap_cache = cmap_cache;
+ ot_font->cmap.init (face);
+ 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 (void *font_data)
+_hb_ot_font_destroy (void *data)
{
- hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
+ hb_ot_font_t *ot_font = (hb_ot_font_t *) data;
- auto *cache = ot_font->advance_cache.get_relaxed ();
- hb_free (cache);
+ 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 ();
- hb_free (ot_font);
+ free (ot_font);
}
+
static hb_bool_t
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
-{
- const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
- return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
-}
-static unsigned int
-hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
- void *font_data,
- unsigned int count,
- const hb_codepoint_t *first_unicode,
- unsigned int unicode_stride,
- hb_codepoint_t *first_glyph,
- unsigned int glyph_stride,
- void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
- return ot_face->cmap->get_nominal_glyphs (count,
- first_unicode, unicode_stride,
- first_glyph, glyph_stride,
- ot_font->cmap_cache);
+ return ot_font->cmap.get_nominal_glyph (unicode, glyph);
}
static hb_bool_t
@@ -166,464 +107,169 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
- return ot_face->cmap->get_variation_glyph (unicode,
- variation_selector, glyph,
- ot_font->cmap_cache);
+ return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph);
}
-static void
-hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
- unsigned count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride,
- void *user_data HB_UNUSED)
+static hb_position_t
+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;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
- const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
-
- hb_position_t *orig_first_advance = first_advance;
-
-#ifndef HB_NO_VAR
- const OT::HVAR &HVAR = *hmtx.var_table;
- const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
- OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
-
- bool use_cache = font->num_coords;
-#else
- OT::VariationStore::cache_t *varStore_cache = nullptr;
- bool use_cache = false;
-#endif
-
- hb_ot_font_advance_cache_t *cache = nullptr;
- if (use_cache)
- {
- retry:
- cache = ot_font->advance_cache.get_acquire ();
- if (unlikely (!cache))
- {
- cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t));
- if (unlikely (!cache))
- {
- use_cache = false;
- goto out;
- }
-
- cache->init ();
- if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
- {
- hb_free (cache);
- goto retry;
- }
- ot_font->cached_coords_serial.set_release (font->serial_coords);
- }
- }
- out:
-
- if (!use_cache)
- {
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
- else
- { /* Use cache. */
- if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords)
- {
- ot_font->advance_cache->init ();
- ot_font->cached_coords_serial.set_release (font->serial_coords);
- }
-
- for (unsigned int i = 0; i < count; i++)
- {
- hb_position_t v;
- unsigned cv;
- if (ot_font->advance_cache->get (*first_glyph, &cv))
- v = cv;
- else
- {
- v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache);
- ot_font->advance_cache->set (*first_glyph, v);
- }
- *first_advance = font->em_scale_x (v);
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
-
-#ifndef HB_NO_VAR
- OT::VariationStore::destroy_cache (varStore_cache);
-#endif
-
- if (font->x_strength && !font->embolden_in_place)
- {
- /* Emboldening. */
- hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength;
- first_advance = orig_first_advance;
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance += *first_advance ? x_strength : 0;
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
+ return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font));
}
-#ifndef HB_NO_VERTICAL
-static void
-hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
- unsigned count,
- const hb_codepoint_t *first_glyph,
- unsigned glyph_stride,
- hb_position_t *first_advance,
- unsigned advance_stride,
- void *user_data HB_UNUSED)
+static hb_position_t
+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;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
-
- hb_position_t *orig_first_advance = first_advance;
-
- if (vmtx.has_data ())
- {
-#ifndef HB_NO_VAR
- const OT::VVAR &VVAR = *vmtx.var_table;
- const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
- OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
-#else
- OT::VariationStore::cache_t *varStore_cache = nullptr;
-#endif
-
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
-
-#ifndef HB_NO_VAR
- OT::VariationStore::destroy_cache (varStore_cache);
-#endif
- }
- else
- {
- hb_font_extents_t font_extents;
- font->get_h_extents_with_fallback (&font_extents);
- hb_position_t advance = -(font_extents.ascender - font_extents.descender);
-
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance = advance;
- first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
-
- if (font->y_strength && !font->embolden_in_place)
- {
- /* Emboldening. */
- hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength;
- first_advance = orig_first_advance;
- for (unsigned int i = 0; i < count; i++)
- {
- *first_advance += *first_advance ? y_strength : 0;
- first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
- }
- }
+ return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font));
}
-#endif
-#ifndef HB_NO_VERTICAL
-static hb_bool_t
-hb_ot_get_glyph_v_origin (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y,
- void *user_data HB_UNUSED)
+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;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
-
- *x = font->get_glyph_h_advance (glyph) / 2;
-
- const OT::VORG &VORG = *ot_face->VORG;
- if (VORG.has_data ())
- {
- float delta = 0;
-
-#ifndef HB_NO_VAR
- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
- const OT::VVAR &VVAR = *vmtx.var_table;
- if (font->num_coords)
- VVAR.get_vorg_delta_unscaled (glyph,
- font->coords, font->num_coords,
- &delta);
-#endif
-
- *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta);
- return true;
- }
-
- hb_glyph_extents_t extents = {0};
- if (ot_face->glyf->get_extents (font, glyph, &extents))
- {
- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
- int tsb = 0;
- if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb))
- {
- *y = extents.y_bearing + font->em_scale_y (tsb);
- return true;
- }
-
- hb_font_extents_t font_extents;
- font->get_h_extents_with_fallback (&font_extents);
- hb_position_t advance = font_extents.ascender - font_extents.descender;
- int diff = advance - -extents.height;
- *y = extents.y_bearing + (diff >> 1);
- return true;
- }
-
- hb_font_extents_t font_extents;
- font->get_h_extents_with_fallback (&font_extents);
- *y = font_extents.ascender;
-
- return true;
+ return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
}
-#endif
static hb_bool_t
-hb_ot_get_glyph_extents (hb_font_t *font,
+hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
-
-#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
- if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
- if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
-#endif
-#if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT)
- if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
-#endif
- if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
-#ifndef HB_NO_OT_FONT_CFF
- if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
- if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
-#endif
-
- return false;
+ 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);
+ extents->height = font->em_scale_y (extents->height);
+ return ret;
}
-#ifndef HB_NO_OT_FONT_GLYPH_NAMES
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)
+ 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;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
-
- if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
-#ifndef HB_NO_OT_FONT_CFF
- if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
-#endif
- return false;
+ 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)
+ 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;
- const hb_ot_face_t *ot_face = ot_font->ot_face;
-
- if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
-#ifndef HB_NO_OT_FONT_CFF
- if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
-#endif
- return false;
+ return ot_font->post->get_glyph_from_name (name, len, glyph);
}
-#endif
static hb_bool_t
-hb_ot_get_font_h_extents (hb_font_t *font,
- void *font_data HB_UNUSED,
+hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
+ void *font_data,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
- bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
- _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
- _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
-
- /* Embolden */
- int y_shift = font->y_strength;
- if (font->y_scale < 0) y_shift = -y_shift;
- metrics->ascender += y_shift;
-
- return ret;
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ 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;
}
-#ifndef HB_NO_VERTICAL
static hb_bool_t
-hb_ot_get_font_v_extents (hb_font_t *font,
- void *font_data HB_UNUSED,
+hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
+ void *font_data,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
- return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_ASCENDER, &metrics->ascender) &&
- _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) &&
- _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap);
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ 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;
}
-#endif
-
-#ifndef HB_NO_DRAW
-static void
-hb_ot_draw_glyph (hb_font_t *font,
- void *font_data HB_UNUSED,
- hb_codepoint_t glyph,
- hb_draw_funcs_t *draw_funcs, void *draw_data,
- void *user_data)
-{
- bool embolden = font->x_strength || font->y_strength;
- hb_outline_t outline;
-
- { // Need draw_session to be destructed before emboldening.
- hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs,
- embolden ? &outline : draw_data, font->slant_xy);
- if (!font->face->table.glyf->get_path (font, glyph, draw_session))
-#ifndef HB_NO_CFF
- if (!font->face->table.cff1->get_path (font, glyph, draw_session))
- if (!font->face->table.cff2->get_path (font, glyph, draw_session))
-#endif
- {}
- }
- if (embolden)
- {
- float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2;
- float y_shift = (float) font->y_strength / 2;
- if (font->x_scale < 0) x_shift = -x_shift;
- if (font->y_scale < 0) y_shift = -y_shift;
- outline.embolden (font->x_strength, font->y_strength,
- x_shift, y_shift);
-
- outline.replay (draw_funcs, draw_data);
- }
-}
-#endif
+static hb_font_funcs_t *static_ot_funcs = nullptr;
-#ifndef HB_NO_PAINT
-static void
-hb_ot_paint_glyph (hb_font_t *font,
- void *font_data,
- hb_codepoint_t glyph,
- hb_paint_funcs_t *paint_funcs, void *paint_data,
- unsigned int palette,
- hb_color_t foreground,
- void *user_data)
+#ifdef HB_USE_ATEXIT
+static
+void free_static_ot_funcs (void)
{
-#ifndef HB_NO_COLOR
- if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return;
- if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
-#ifndef HB_NO_OT_FONT_BITMAP
- if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
- if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
-#endif
-#endif
- if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
-#ifndef HB_NO_CFF
- if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
- if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
-#endif
+ hb_font_funcs_destroy (static_ot_funcs);
}
#endif
-static inline void free_static_ot_funcs ();
-
-static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
+static hb_font_funcs_t *
+_hb_ot_get_font_funcs (void)
{
- static hb_font_funcs_t *create ()
+retry:
+ hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs);
+
+ if (unlikely (!funcs))
{
- hb_font_funcs_t *funcs = hb_font_funcs_create ();
+ funcs = hb_font_funcs_create ();
+ 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_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
-
- hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, 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);
-
-#ifndef HB_NO_VERTICAL
- hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
-#endif
-
-#ifndef HB_NO_DRAW
- hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr);
-#endif
-
-#ifndef HB_NO_PAINT
- hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr);
-#endif
-
+ //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);
-
-#ifndef HB_NO_OT_FONT_GLYPH_NAMES
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);
-#endif
hb_font_funcs_make_immutable (funcs);
- hb_atexit (free_static_ot_funcs);
-
- return funcs;
- }
-} static_ot_funcs;
+ if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, nullptr, funcs)) {
+ hb_font_funcs_destroy (funcs);
+ goto retry;
+ }
-static inline
-void free_static_ot_funcs ()
-{
- static_ot_funcs.free_instance ();
-}
+#ifdef HB_USE_ATEXIT
+ atexit (free_static_ot_funcs); /* First person registers atexit() callback. */
+#endif
+ };
-static hb_font_funcs_t *
-_hb_ot_get_font_funcs ()
-{
- return static_ot_funcs.get_unconst ();
+ return funcs;
}
/**
* hb_ot_font_set_funcs:
- * @font: #hb_font_t to work upon
- *
- * Sets the font functions to use when working with @font.
*
* Since: 0.9.28
**/
void
hb_ot_font_set_funcs (hb_font_t *font)
{
- hb_ot_font_t *ot_font = _hb_ot_font_create (font);
+ hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
if (unlikely (!ot_font))
return;
@@ -632,5 +278,3 @@ hb_ot_font_set_funcs (hb_font_t *font)
ot_font,
_hb_ot_font_destroy);
}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h
index e7959d1ae28..80eaa54b1ad 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
*/
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh
deleted file mode 100644
index f2a9cad464b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-gasp-table.hh
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_OT_GASP_TABLE_HH
-#define HB_OT_GASP_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-hhea-table.hh"
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-var-hvar-table.hh"
-
-/*
- * gasp -- Grid-fitting and Scan-conversion Procedure
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gasp
- */
-#define HB_OT_TAG_gasp HB_TAG('g','a','s','p')
-
-
-namespace OT {
-
-struct GaspRange
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT16 rangeMaxPPEM; /* Upper limit of range, in PPEM */
- HBUINT16 rangeGaspBehavior;
- /* Flags describing desired rasterizer behavior. */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct gasp
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_gasp;
-
- const GaspRange &get_gasp_range (unsigned int i) const
- { return gaspRanges[i]; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- gaspRanges.sanitize (c));
- }
-
- protected:
- HBUINT16 version; /* Version number (set to 1) */
- Array16Of<GaspRange>
- gaspRanges; /* Number of records to follow
- * Sorted by ppem */
- public:
- DEFINE_SIZE_ARRAY (4, gaspRanges);
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_GASP_TABLE_HH */
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 c32ff7636d5..88d3850b6ef 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh
@@ -1,7 +1,5 @@
/*
* Copyright © 2015 Google, Inc.
- * Copyright © 2019 Adobe Inc.
- * Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -23,13 +21,160 @@
* 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, Garret Rieger, Roderick Sheeter
- * Adobe Author(s): Michiharu Ariza
+ * Google Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_GLYF_TABLE_HH
#define HB_OT_GLYF_TABLE_HH
-#include "OT/glyf/glyf.hh"
+#include "hb-open-type-private.hh"
+#include "hb-ot-head-table.hh"
+
+
+namespace OT {
+
+
+/*
+ * loca -- Index to Location
+ */
+
+#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
+
+
+struct loca
+{
+ friend struct glyf;
+
+ static const hb_tag_t tableTag = HB_OT_TAG_loca;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (true);
+ }
+
+ protected:
+ UINT8 dataX[VAR]; /* Location data. */
+ DEFINE_SIZE_ARRAY (0, dataX);
+};
+
+
+/*
+ * glyf -- TrueType Glyph Data
+ */
+
+#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
+
+
+struct glyf
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_glyf;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ /* We don't check for anything specific here. The users of the
+ * struct do all the hard work... */
+ return_trace (true);
+ }
+
+ 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);
+};
+
+} /* namespace OT */
+
#endif /* HB_OT_GLYF_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh
deleted file mode 100644
index 3bfd75502a4..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hdmx-table.hh
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger
- */
-
-#ifndef HB_OT_HDMX_TABLE_HH
-#define HB_OT_HDMX_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * hdmx -- Horizontal Device Metrics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx
- */
-#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x')
-
-
-namespace OT {
-
-
-struct DeviceRecord
-{
- static unsigned int get_size (unsigned count)
- { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it)
- {
- TRACE_SERIALIZE (this);
-
- unsigned length = it.len ();
-
- if (unlikely (!c->extend (this, length))) return_trace (false);
-
- this->pixelSize = pixelSize;
- this->maxWidth =
- + it
- | hb_reduce (hb_max, 0u);
-
- + it
- | hb_sink (widthsZ.as_array (length));
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned sizeDeviceRecord) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- c->check_range (this, sizeDeviceRecord)));
- }
-
- HBUINT8 pixelSize; /* Pixel size for following widths (as ppem). */
- HBUINT8 maxWidth; /* Maximum width. */
- UnsizedArrayOf<HBUINT8> widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */
- public:
- DEFINE_SIZE_UNBOUNDED (2);
-};
-
-
-struct hdmx
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_hdmx;
-
- unsigned int get_size () const
- { return min_size + numRecords * sizeDeviceRecord; }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
- {
- TRACE_SERIALIZE (this);
-
- if (unlikely (!c->extend_min ((*this)))) return_trace (false);
-
- this->version = version;
- this->numRecords = it.len ();
- this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
-
- for (const hb_item_type<Iterator>& _ : +it)
- c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
-
- return_trace (c->successful ());
- }
-
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- hdmx *hdmx_prime = c->serializer->start_embed <hdmx> ();
- if (unlikely (!hdmx_prime)) return_trace (false);
-
- auto it =
- + hb_range ((unsigned) numRecords)
- | hb_map ([c, this] (unsigned _)
- {
- const DeviceRecord *device_record =
- &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
- _ * sizeDeviceRecord);
- auto row =
- + hb_range (c->plan->num_output_glyphs ())
- | hb_map (c->plan->reverse_glyph_map)
- | hb_map ([this, c, device_record] (hb_codepoint_t _)
- {
- if (c->plan->is_empty_glyph (_))
- return Null (HBUINT8);
- return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
- })
- ;
- return hb_pair ((unsigned) device_record->pixelSize, +row);
- })
- ;
-
- hdmx_prime->serialize (c->serializer, version, it);
- return_trace (true);
- }
-
- unsigned get_num_glyphs () const
- {
- return sizeDeviceRecord - DeviceRecord::min_size;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
- min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord &&
- sizeDeviceRecord >= DeviceRecord::min_size &&
- c->check_range (this, get_size ()));
- }
-
- protected:
- HBUINT16 version; /* Table version number (0) */
- HBUINT16 numRecords; /* Number of device records. */
- HBUINT32 sizeDeviceRecord;
- /* Size of a device record, 32-bit aligned. */
- DeviceRecord firstDeviceRecord;
- /* Array of device records. */
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_HDMX_TABLE_HH */
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 770cf52d173..dd4349ef85a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -29,77 +29,30 @@
#ifndef HB_OT_HEAD_TABLE_HH
#define HB_OT_HEAD_TABLE_HH
-#include "hb-open-type.hh"
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
/*
* head -- Font Header
- * https://docs.microsoft.com/en-us/typography/opentype/spec/head
*/
-#define HB_OT_TAG_head HB_TAG('h','e','a','d')
-
-
-namespace OT {
+#define HB_OT_TAG_head HB_TAG('h','e','a','d')
struct head
{
- friend struct OpenTypeOffsetTable;
+ static const hb_tag_t tableTag = HB_OT_TAG_head;
- static constexpr hb_tag_t tableTag = HB_OT_TAG_head;
-
- unsigned int get_upem () const
+ inline unsigned int get_upem (void) const
{
unsigned int upem = unitsPerEm;
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
return 16 <= upem && upem <= 16384 ? upem : 1000;
}
- bool serialize (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace ((bool) c->embed (this));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- head *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (c->plan->normalized_coords)
- {
- if (unlikely (!c->serializer->check_assign (out->xMin, c->plan->head_maxp_info.xMin,
- HB_SERIALIZE_ERROR_INT_OVERFLOW)))
- return_trace (false);
- if (unlikely (!c->serializer->check_assign (out->xMax, c->plan->head_maxp_info.xMax,
- HB_SERIALIZE_ERROR_INT_OVERFLOW)))
- return_trace (false);
- if (unlikely (!c->serializer->check_assign (out->yMin, c->plan->head_maxp_info.yMin,
- HB_SERIALIZE_ERROR_INT_OVERFLOW)))
- return_trace (false);
- if (unlikely (!c->serializer->check_assign (out->yMax, c->plan->head_maxp_info.yMax,
- HB_SERIALIZE_ERROR_INT_OVERFLOW)))
- return_trace (false);
- }
- return_trace (true);
- }
-
- enum mac_style_flag_t {
- BOLD = 1u<<0,
- ITALIC = 1u<<1,
- UNDERLINE = 1u<<2,
- OUTLINE = 1u<<3,
- SHADOW = 1u<<4,
- CONDENSED = 1u<<5,
- EXPANDED = 1u<<6,
- };
-
- bool is_bold () const { return macStyle & BOLD; }
- bool is_italic () const { return macStyle & ITALIC; }
- bool is_condensed () const { return macStyle & CONDENSED; }
- bool is_expanded () const { return macStyle & EXPANDED; }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -111,12 +64,11 @@ struct head
FixedVersion<>version; /* Version of the head table--currently
* 0x00010000u for version 1.0. */
FixedVersion<>fontRevision; /* Set by font manufacturer. */
- HBUINT32 checkSumAdjustment; /* To compute: set it to 0, sum the
- * entire font as HBUINT32, then store
+ UINT32 checkSumAdjustment; /* To compute: set it to 0, sum the
+ * entire font as UINT32, then store
* 0xB1B0AFBAu - sum. */
- HBUINT32 magicNumber; /* Set to 0x5F0F3CF5u. */
- public:
- HBUINT16 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
@@ -124,6 +76,7 @@ struct head
* ppem sizes if this bit is clear;
* Bit 4: Instructions may alter advance width
* (the advance widths might not scale linearly);
+
* Bits 5-10: These should be set according to
* Apple's specification. However, they are not
* implemented in OpenType.
@@ -143,6 +96,7 @@ struct head
* contains any strong right-to-left glyphs.
* Bit 10: This bit should be set if the font
* contains Indic-style rearrangement effects.
+
* Bit 11: Font data is 'lossless,' as a result
* of having been compressed and decompressed
* with the Agfa MicroType Express engine.
@@ -160,21 +114,18 @@ struct head
* encoded in the cmap subtables represent proper
* support for those code points.
* Bit 15: Reserved, set to 0. */
- protected:
- HBUINT16 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 */
- public:
- HBINT16 xMin; /* For all glyph bounding boxes. */
- HBINT16 yMin; /* For all glyph bounding boxes. */
- HBINT16 xMax; /* For all glyph bounding boxes. */
- HBINT16 yMax; /* For all glyph bounding boxes. */
- protected:
- HBUINT16 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)
@@ -182,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). */
- HBUINT16 lowestRecPPEM; /* Smallest readable size in pixels. */
- HBINT16 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:
- HBUINT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */
- HBUINT16 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 d9c9bd35377..dca014148ea 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -27,74 +27,68 @@
#ifndef HB_OT_HHEA_TABLE_HH
#define HB_OT_HHEA_TABLE_HH
-#include "hb-open-type.hh"
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
/*
- * hhea -- Horizontal Header
- * https://docs.microsoft.com/en-us/typography/opentype/spec/hhea
- * vhea -- Vertical Header
- * https://docs.microsoft.com/en-us/typography/opentype/spec/vhea
+ * hhea -- The Horizontal Header Table
+ * vhea -- The Vertical Header Table
*/
+
#define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
#define HB_OT_TAG_vhea HB_TAG('v','h','e','a')
-namespace OT {
-
-
-template <typename T>
struct _hea
{
- bool has_data () const { return version.major; }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && likely (version.major == 1));
}
public:
- FixedVersion<>version; /* 0x00010000u for version 1.0. */
- FWORD ascender; /* Typographic ascent. */
- FWORD descender; /* Typographic descent. */
- FWORD lineGap; /* Typographic line gap. */
- UFWORD advanceMax; /* Maximum advance width/height value in
- * metrics table. */
- FWORD minLeadingBearing;
- /* Minimum left/top sidebearing value in
- * metrics table. */
- FWORD minTrailingBearing;
- /* Minimum right/bottom sidebearing value;
- * calculated as Min(aw - lsb -
- * (xMax - xMin)) for horizontal. */
- FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)),
- * vertical: minLeadingBearing+(yMax-yMin). */
- HBINT16 caretSlopeRise; /* Used to calculate the slope of the
- * cursor (rise/run); 1 for vertical caret,
- * 0 for horizontal.*/
- HBINT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
- HBINT16 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. */
- HBINT16 reserved1; /* Set to 0. */
- HBINT16 reserved2; /* Set to 0. */
- HBINT16 reserved3; /* Set to 0. */
- HBINT16 reserved4; /* Set to 0. */
- HBINT16 metricDataFormat;/* 0 for current format. */
- HBUINT16 numberOfLongMetrics;
- /* Number of LongMetric entries in metric
- * table. */
+ FixedVersion<>version; /* 0x00010000u for version 1.0. */
+ FWORD ascender; /* Typographic ascent. */
+ FWORD descender; /* Typographic descent. */
+ FWORD lineGap; /* Typographic line gap. */
+ UFWORD advanceMax; /* Maximum advance width/height value in
+ * metrics table. */
+ FWORD minLeadingBearing; /* Minimum left/top sidebearing value in
+ * metrics table. */
+ FWORD minTrailingBearing; /* Minimum right/bottom sidebearing value;
+ * calculated as Min(aw - lsb -
+ * (xMax - xMin)) for horizontal. */
+ FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)),
+ * vertical: minLeadingBearing+(yMax-yMin). */
+ INT16 caretSlopeRise; /* Used to calculate the slope of the
+ * cursor (rise/run); 1 for vertical caret,
+ * 0 for horizontal.*/
+ 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. */
+ 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);
};
-struct hhea : _hea<hhea> {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_hhea;
+struct hhea : _hea {
+ static const hb_tag_t tableTag = HB_OT_TAG_hhea;
};
-struct vhea : _hea<vhea> {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_vhea;
+struct vhea : _hea {
+ static const hb_tag_t tableTag = HB_OT_TAG_vhea;
};
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 835a1a585e8..e710aee42ec 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -21,55 +21,42 @@
* 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, Roderick Sheeter
+ * Google Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_HMTX_TABLE_HH
#define HB_OT_HMTX_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-maxp-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"
-#include "hb-ot-var-mvar-table.hh"
-#include "hb-ot-metrics.hh"
-/*
- * hmtx -- Horizontal Metrics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
- * vmtx -- Vertical Metrics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/vmtx
- */
-#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
-#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
+namespace OT {
-HB_INTERNAL bool
-_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb);
-
-HB_INTERNAL unsigned
-_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
-
-HB_INTERNAL bool
-_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb);
+/*
+ * hmtx -- The Horizontal Metrics Table
+ * vmtx -- The Vertical Metrics Table
+ */
-namespace OT {
+#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
+#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
struct LongMetric
{
UFWORD advance; /* Advance width/height. */
- FWORD sb; /* Leading (left/top) side bearing. */
+ FWORD lsb; /* Leading (left/top) side bearing. */
public:
DEFINE_SIZE_STATIC (4);
};
-
-template <typename T/*Data table type*/, typename H/*Header table type*/, typename V/*Var table type*/>
+template <typename T>
struct hmtxvmtx
{
- bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
/* We don't check for anything specific here. The users of the
@@ -77,390 +64,143 @@ struct hmtxvmtx
return_trace (true);
}
- const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>>* get_mtx_map (const hb_subset_plan_t *plan) const
- { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; }
-
- bool subset_update_header (hb_subset_context_t *c,
- unsigned int num_hmetrics,
- const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
- const hb_map_t *bounds_map) const
+ struct accelerator_t
{
- hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (c->plan->source, H::tableTag);
- hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
- hb_blob_destroy (src_blob);
-
- if (unlikely (!dest_blob)) {
- return false;
- }
-
- unsigned int length;
- H *table = (H *) hb_blob_get_data (dest_blob, &length);
- c->serializer->check_assign (table->numberOfLongMetrics, num_hmetrics, HB_SERIALIZE_ERROR_INT_OVERFLOW);
-
-#ifndef HB_NO_VAR
- if (c->plan->normalized_coords)
+ inline void init (hb_face_t *face,
+ unsigned int default_advance_ = 0)
{
- auto &MVAR = *c->plan->source->table.MVAR;
- if (T::is_horizontal)
- {
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, caretSlopeRise);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, caretSlopeRun);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, caretOffset);
- }
- else
- {
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RISE, caretSlopeRise);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RUN, caretSlopeRun);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET, caretOffset);
- }
-
- int min_lsb = 0x7FFF;
- int min_rsb = 0x7FFF;
- int max_extent = -0x7FFF;
- unsigned max_adv = 0;
- for (const auto _ : *mtx_map)
- {
- hb_codepoint_t gid = _.first;
- unsigned adv = _.second.first;
- int lsb = _.second.second;
- max_adv = hb_max (max_adv, adv);
+ default_advance = default_advance_ ? default_advance_ : face->get_upem ();
- if (bounds_map->has (gid))
- {
- unsigned bound_width = bounds_map->get (gid);
- int rsb = adv - lsb - bound_width;
- int extent = lsb + bound_width;
- min_lsb = hb_min (min_lsb, lsb);
- min_rsb = hb_min (min_rsb, rsb);
- max_extent = hb_max (max_extent, extent);
- }
- }
-
- table->advanceMax = max_adv;
- if (!bounds_map->is_empty ())
+ bool got_font_extents = false;
+ if (T::os2Tag)
{
- table->minLeadingBearing = min_lsb;
- table->minTrailingBearing = min_rsb;
- table->maxExtent = max_extent;
+ 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);
}
- }
-#endif
-
- bool result = c->plan->add_table (H::tableTag, dest_blob);
- hb_blob_destroy (dest_blob);
- return result;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it,
- unsigned num_long_metrics)
- {
- unsigned idx = 0;
- for (auto _ : it)
- {
- if (idx < num_long_metrics)
- {
- LongMetric lm;
- lm.advance = _.first;
- lm.sb = _.second;
- if (unlikely (!c->embed<LongMetric> (&lm))) return;
- }
- else if (idx < 0x10000u)
+ 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)
{
- FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
- if (unlikely (!sb)) return;
- *sb = _.second;
+ ascender = _hea_table->ascender;
+ descender = _hea_table->descender;
+ line_gap = _hea_table->lineGap;
+ got_font_extents = (ascender | descender) != 0;
}
- else
- {
- // TODO: This does not do tail optimization.
- UFWORD *adv = c->allocate_size<UFWORD> (UFWORD::static_size);
- if (unlikely (!adv)) return;
- *adv = _.first;
- }
- idx++;
- }
- }
+ hb_blob_destroy (_hea_blob);
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
+ has_font_extents = got_font_extents;
- T *table_prime = c->serializer->start_embed <T> ();
- if (unlikely (!table_prime)) return_trace (false);
+ blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (T::tableTag));
- accelerator_t _mtx (c->plan->source);
- unsigned num_long_metrics;
- const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map = get_mtx_map (c->plan);
- {
- /* Determine num_long_metrics to encode. */
- auto& plan = c->plan;
+ /* 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;
- num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
- unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
- while (num_long_metrics > 1 &&
- last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx))
+ /* We MUST set num_metrics to zero if num_advances is zero.
+ * Our get_advance() depends on that. */
+ if (unlikely (!num_advances))
{
- num_long_metrics--;
+ num_metrics = num_advances = 0;
+ hb_blob_destroy (blob);
+ blob = hb_blob_get_empty ();
}
- }
-
- auto it =
- + hb_range (c->plan->num_output_glyphs ())
- | hb_map ([c, &_mtx, mtx_map] (unsigned _)
- {
- if (!mtx_map->has (_))
- {
- hb_codepoint_t old_gid;
- if (!c->plan->old_gid_for_new_gid (_, &old_gid))
- return hb_pair (0u, 0);
- int lsb = 0;
- if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
- (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb);
- return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
- }
- return mtx_map->get (_);
- })
- ;
-
- table_prime->serialize (c->serializer, it, num_long_metrics);
-
- if (unlikely (c->serializer->in_error ()))
- return_trace (false);
-
- // Amend header num hmetrics
- if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map,
- T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map)))
- return_trace (false);
-
- return_trace (true);
- }
-
- struct accelerator_t
- {
- friend struct hmtxvmtx;
-
- accelerator_t (hb_face_t *face)
- {
- table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
- var_table = hb_sanitize_context_t ().reference_table<V> (face, T::variationsTag);
-
- default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face);
+ table = Sanitizer<hmtxvmtx>::lock_instance (blob);
- /* Populate count variables and sort them out as we go */
-
- unsigned int len = table.get_length ();
- if (len & 1)
- len--;
-
- num_long_metrics = T::is_horizontal ?
- face->table.hhea->numberOfLongMetrics :
-#ifndef HB_NO_VERTICAL
- face->table.vhea->numberOfLongMetrics
-#else
- 0
-#endif
- ;
- if (unlikely (num_long_metrics * 4 > len))
- num_long_metrics = len / 4;
- len -= num_long_metrics * 4;
-
- num_bearings = face->table.maxp->get_num_glyphs ();
-
- if (unlikely (num_bearings < num_long_metrics))
- num_bearings = num_long_metrics;
- if (unlikely ((num_bearings - num_long_metrics) * 2 > len))
- num_bearings = num_long_metrics + len / 2;
- len -= (num_bearings - num_long_metrics) * 2;
-
- /* We MUST set num_bearings to zero if num_long_metrics is zero.
- * Our get_advance() depends on that. */
- if (unlikely (!num_long_metrics))
- num_bearings = num_long_metrics = 0;
-
- num_advances = num_bearings + len / 2;
- num_glyphs = face->get_num_glyphs ();
- if (num_glyphs < num_advances)
- num_glyphs = num_advances;
- }
- ~accelerator_t ()
- {
- table.destroy ();
- var_table.destroy ();
+ var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (T::variationsTag));
+ var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob);
}
- bool has_data () const { return (bool) num_bearings; }
-
- bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph,
- int *lsb) const
+ inline void fini (void)
{
- if (glyph < num_long_metrics)
- {
- *lsb = table->longMetricZ[glyph].sb;
- return true;
- }
-
- if (unlikely (glyph >= num_bearings))
- return false;
-
- const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
- *lsb = bearings[glyph - num_long_metrics];
- return true;
+ hb_blob_destroy (blob);
+ hb_blob_destroy (var_blob);
}
- bool get_leading_bearing_with_var_unscaled (hb_font_t *font,
- hb_codepoint_t glyph,
- int *lsb) const
+ inline unsigned int get_advance (hb_codepoint_t glyph,
+ hb_font_t *font) const
{
- if (!font->num_coords)
- return get_leading_bearing_without_var_unscaled (glyph, lsb);
-
-#ifndef HB_NO_VAR
- float delta;
- if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) &&
- get_leading_bearing_without_var_unscaled (glyph, lsb))
+ if (unlikely (glyph >= num_metrics))
{
- *lsb += roundf (delta);
- return true;
+ /* 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 _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb);
-#else
- return false;
-#endif
- }
-
- unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const
- {
- /* OpenType case. */
- if (glyph < num_bearings)
- return table->longMetricZ[hb_min (glyph, (uint32_t) num_long_metrics - 1)].advance;
-
- /* If num_advances is zero, it means we don't have the metrics table
- * for this direction: return default advance. Otherwise, there's a
- * well-defined answer. */
- if (unlikely (!num_advances))
- return default_advance;
-
-#ifdef HB_NO_BEYOND_64K
- return 0;
-#endif
-
- if (unlikely (glyph >= num_glyphs))
- return 0;
-
- /* num_bearings <= glyph < num_glyphs;
- * num_bearings <= num_advances */
-
- if (num_bearings == num_advances)
- return get_advance_without_var_unscaled (num_bearings - 1);
-
- const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics];
- const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics];
-
- return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)];
+ return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance
+ + var_table->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
}
- unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph,
- hb_font_t *font,
- VariationStore::cache_t *store_cache = nullptr) const
- {
- unsigned int advance = get_advance_without_var_unscaled (glyph);
-
-#ifndef HB_NO_VAR
- if (unlikely (glyph >= num_bearings) || !font->num_coords)
- return advance;
-
- if (var_table.get_length ())
- return advance + roundf (var_table->get_advance_delta_unscaled (glyph,
- font->coords, font->num_coords,
- store_cache));
-
- return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
-#else
- return advance;
-#endif
- }
-
- protected:
- // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs
- unsigned num_long_metrics;
- unsigned num_bearings;
- unsigned num_advances;
- unsigned num_glyphs;
-
+ 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;
- public:
- hb_blob_ptr_t<hmtxvmtx> table;
- hb_blob_ptr_t<V> var_table;
+ const hmtxvmtx *table;
+ hb_blob_t *blob;
+ const HVARVVAR *var_table;
+ hb_blob_t *var_blob;
};
- /* get advance: when no variations, call get_advance_without_var_unscaled.
- * when there're variations, get advance value from mtx_map in subset_plan*/
- unsigned get_new_gid_advance_unscaled (const hb_subset_plan_t *plan,
- const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
- unsigned new_gid,
- const accelerator_t &_mtx) const
- {
- if (mtx_map->is_empty ())
- {
- hb_codepoint_t old_gid = 0;
- return plan->old_gid_for_new_gid (new_gid, &old_gid) ?
- _mtx.get_advance_without_var_unscaled (old_gid) : 0;
- }
- return mtx_map->get (new_gid).first;
- }
-
protected:
- UnsizedArrayOf<LongMetric>
- longMetricZ; /* Paired advance width and leading
- * bearing values for each glyph. The
- * value numOfHMetrics comes from
- * the 'hhea' table. If the font is
- * monospaced, only one entry need
- * be in the array, but that entry is
- * required. The last entry applies to
- * all subsequent glyphs. */
-/*UnsizedArrayOf<FWORD> leadingBearingX;*/
- /* Here the advance is assumed
- * to be the same as the advance
- * for the last entry above. The
- * number of entries in this array is
- * derived from numGlyphs (from 'maxp'
- * table) minus numberOfLongMetrics.
- * This generally is used with a run
- * of monospaced glyphs (e.g., Kanji
- * fonts or Courier fonts). Only one
- * run is allowed and it must be at
- * the end. This allows a monospaced
- * font to vary the side bearing
- * values for each glyph. */
-/*UnsizedArrayOf<UFWORD>advancesX;*/
- /* TODO Document. */
+ LongMetric longMetric[VAR]; /* Paired advance width and leading
+ * bearing values for each glyph. The
+ * value numOfHMetrics comes from
+ * the 'hhea' table. If the font is
+ * monospaced, only one entry need
+ * be in the array, but that entry is
+ * required. The last entry applies to
+ * all subsequent glyphs. */
+ FWORD leadingBearingX[VAR]; /* Here the advance is assumed
+ * to be the same as the advance
+ * for the last entry above. The
+ * number of entries in this array is
+ * derived from numGlyphs (from 'maxp'
+ * table) minus numberOfLongMetrics.
+ * This generally is used with a run
+ * of monospaced glyphs (e.g., Kanji
+ * fonts or Courier fonts). Only one
+ * run is allowed and it must be at
+ * the end. This allows a monospaced
+ * font to vary the side bearing
+ * values for each glyph. */
public:
- DEFINE_SIZE_ARRAY (0, longMetricZ);
-};
-
-struct hmtx : hmtxvmtx<hmtx, hhea, HVAR> {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
- static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
- static constexpr bool is_horizontal = true;
-};
-struct vmtx : hmtxvmtx<vmtx, vhea, VVAR> {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
- static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
- static constexpr bool is_horizontal = false;
+ DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
};
-struct hmtx_accelerator_t : hmtx::accelerator_t {
- hmtx_accelerator_t (hb_face_t *face) : hmtx::accelerator_t (face) {}
+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_accelerator_t : vmtx::accelerator_t {
- vmtx_accelerator_t (hb_face_t *face) : vmtx::accelerator_t (face) {}
+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
index ffa11bc2496..e07faca63f3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
@@ -27,330 +27,365 @@
#ifndef HB_OT_KERN_TABLE_HH
#define HB_OT_KERN_TABLE_HH
-#include "hb-aat-layout-kerx-table.hh"
+#include "hb-open-type-private.hh"
+
+namespace OT {
/*
* kern -- Kerning
- * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
*/
+
#define HB_OT_TAG_kern HB_TAG('k','e','r','n')
+struct hb_glyph_pair_t
+{
+ hb_codepoint_t left;
+ hb_codepoint_t right;
+};
-namespace OT {
+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);
+};
-template <typename KernSubTableHeader>
-struct KernSubTableFormat3
+struct KernSubTableFormat0
{
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
- hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
- hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
- hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
- hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
-
- unsigned int leftC = leftClass[left];
- unsigned int rightC = rightClass[right];
- if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
+ hb_glyph_pair_t pair = {left, right};
+ int i = pairs.bsearch (pair);
+ if (i == -1)
return 0;
- unsigned int i = leftC * rightClassCount + rightC;
- return kernValue[kernIndex[i]];
+ return pairs[i].get_kerning ();
}
- bool apply (AAT::hb_aat_apply_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
- TRACE_APPLY (this);
+ TRACE_SANITIZE (this);
+ return_trace (pairs.sanitize (c));
+ }
- if (!c->plan->requested_kerning)
- return false;
+ protected:
+ BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
+ public:
+ DEFINE_SIZE_ARRAY (8, pairs);
+};
- if (header.coverage & header.Backwards)
- return false;
+struct KernClassTable
+{
+ inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
- hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
- machine.kern (c->font, c->buffer, c->plan->kern_mask);
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
+ }
- return_trace (true);
+ 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;
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- c->check_range (kernValueZ,
- kernValueCount * sizeof (FWORD) +
- glyphCount * 2 +
- leftClassCount * rightClassCount));
+ return_trace (rowWidth.sanitize (c) &&
+ leftClassTable.sanitize (c, this) &&
+ rightClassTable.sanitize (c, this) &&
+ array.sanitize (c, this));
}
protected:
- KernSubTableHeader
- header;
- HBUINT16 glyphCount; /* The number of glyphs in this font. */
- HBUINT8 kernValueCount; /* The number of kerning values. */
- HBUINT8 leftClassCount; /* The number of left-hand classes. */
- HBUINT8 rightClassCount;/* The number of right-hand classes. */
- HBUINT8 flags; /* Set to zero (reserved for future use). */
- UnsizedArrayOf<FWORD>
- kernValueZ; /* The kerning values.
- * Length kernValueCount. */
-#if 0
- UnsizedArrayOf<HBUINT8>
- leftClass; /* The left-hand classes.
- * Length glyphCount. */
- UnsizedArrayOf<HBUINT8>
- rightClass; /* The right-hand classes.
- * Length glyphCount. */
- UnsizedArrayOf<HBUINT8>kernIndex;
- /* The indices into the kernValue array.
- * Length leftClassCount * rightClassCount */
-#endif
+ 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_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
+ DEFINE_SIZE_MIN (8);
};
-template <typename KernSubTableHeader>
struct KernSubTable
{
- unsigned int get_size () const { return u.header.length; }
- unsigned int get_type () const { return u.header.format; }
-
- int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
{
- switch (get_type ()) {
- /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */
+ switch (format) {
case 0: return u.format0.get_kerning (left, right);
+ case 2: return u.format2.get_kerning (left, right, end);
default:return 0;
}
}
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- unsigned int subtable_type = get_type ();
- TRACE_DISPATCH (this, subtable_type);
- switch (subtable_type) {
- case 0: return_trace (c->dispatch (u.format0));
-#ifndef HB_NO_AAT_SHAPE
- case 1: return_trace (u.header.apple ? c->dispatch (u.format1, std::forward<Ts> (ds)...) : c->default_return_value ());
-#endif
- case 2: return_trace (c->dispatch (u.format2));
-#ifndef HB_NO_AAT_SHAPE
- case 3: return_trace (u.header.apple ? c->dispatch (u.format3, std::forward<Ts> (ds)...) : c->default_return_value ());
-#endif
- default: return_trace (c->default_return_value ());
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
{
TRACE_SANITIZE (this);
- if (unlikely (!u.header.sanitize (c) ||
- u.header.length < u.header.min_size ||
- !c->check_range (this, u.header.length))) return_trace (false);
-
- return_trace (dispatch (c));
+ switch (format) {
+ case 0: return_trace (u.format0.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ default:return_trace (true);
+ }
}
- public:
+ protected:
union {
- KernSubTableHeader header;
- AAT::KerxSubTableFormat0<KernSubTableHeader> format0;
- AAT::KerxSubTableFormat1<KernSubTableHeader> format1;
- AAT::KerxSubTableFormat2<KernSubTableHeader> format2;
- KernSubTableFormat3<KernSubTableHeader> format3;
+ KernSubTableFormat0 format0;
+ KernSubTableFormat2 format2;
} u;
public:
- DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
+ DEFINE_SIZE_MIN (0);
};
-struct KernOTSubTableHeader
+template <typename T>
+struct KernSubTableWrapper
{
- static constexpr bool apple = false;
- typedef AAT::ObsoleteTypes Types;
+ /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+ inline const T* thiz (void) const { return static_cast<const T *> (this); }
- unsigned tuple_count () const { return 0; }
- bool is_horizontal () const { return (coverage & Horizontal); }
+ inline bool is_horizontal (void) const
+ { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
- enum Coverage
- {
- Horizontal = 0x01u,
- Minimum = 0x02u,
- CrossStream = 0x04u,
- Override = 0x08u,
-
- /* Not supported: */
- Backwards = 0x00u,
- Variation = 0x00u,
- };
+ 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); }
- bool sanitize (hb_sanitize_context_t *c) const
+ 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 (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));
}
-
- public:
- HBUINT16 versionZ; /* Unused. */
- HBUINT16 length; /* Length of the subtable (including this header). */
- HBUINT8 format; /* Subtable format. */
- HBUINT8 coverage; /* Coverage bits. */
- public:
- DEFINE_SIZE_STATIC (6);
};
-struct KernOT : AAT::KerxTable<KernOT>
+template <typename T>
+struct KernTable
{
- friend struct AAT::KerxTable<KernOT>;
+ /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+ inline const T* thiz (void) const { return static_cast<const T *> (this); }
- static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
- static constexpr unsigned minVersion = 0u;
+ 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;
+ }
- typedef KernOTSubTableHeader SubTableHeader;
- typedef SubTableHeader::Types Types;
- typedef KernSubTable<SubTableHeader> SubTable;
+ 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);
+ }
- protected:
- HBUINT16 version; /* Version--0x0000u */
- HBUINT16 tableCount; /* Number of subtables in the kerning table. */
- SubTable firstSubTable; /* Subtables. */
- public:
- DEFINE_SIZE_MIN (4);
+ return_trace (true);
+ }
};
-
-struct KernAATSubTableHeader
+struct KernOT : KernTable<KernOT>
{
- static constexpr bool apple = true;
- typedef AAT::ObsoleteTypes Types;
+ friend struct KernTable<KernOT>;
- unsigned tuple_count () const { return 0; }
- bool is_horizontal () const { return !(coverage & Vertical); }
+ static const uint16_t VERSION = 0x0000u;
- enum Coverage
+ struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
{
- Vertical = 0x80u,
- CrossStream = 0x40u,
- Variation = 0x20u,
-
- /* Not supported: */
- Backwards = 0x00u,
+ 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);
};
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT32 length; /* Length of the subtable (including this header). */
- HBUINT8 coverage; /* Coverage bits. */
- HBUINT8 format; /* Subtable format. */
- HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
- * This value specifies which tuple this subtable covers.
- * Note: We don't implement. */
+ protected:
+ UINT16 version; /* Version--0x0000u */
+ UINT16 nTables; /* Number of subtables in the kerning table. */
+ UINT8 data[VAR];
public:
- DEFINE_SIZE_STATIC (8);
+ DEFINE_SIZE_ARRAY (4, data);
};
-struct KernAAT : AAT::KerxTable<KernAAT>
+struct KernAAT : KernTable<KernAAT>
{
- friend struct AAT::KerxTable<KernAAT>;
+ friend struct KernTable<KernAAT>;
- static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
- static constexpr unsigned minVersion = 0x00010000u;
+ static const uint32_t VERSION = 0x00010000u;
- typedef KernAATSubTableHeader SubTableHeader;
- typedef SubTableHeader::Types Types;
- typedef KernSubTable<SubTableHeader> SubTable;
+ 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:
- HBUINT32 version; /* Version--0x00010000u */
- HBUINT32 tableCount; /* Number of subtables in the kerning table. */
- SubTable firstSubTable; /* Subtables. */
+ UINT32 version; /* Version--0x00010000u */
+ UINT32 nTables; /* Number of subtables in the kerning table. */
+ UINT8 data[VAR];
public:
- DEFINE_SIZE_MIN (8);
+ DEFINE_SIZE_ARRAY (8, data);
};
struct kern
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
+ static const hb_tag_t tableTag = HB_OT_TAG_kern;
- bool has_data () const { return u.version32; }
- unsigned get_type () const { return u.major; }
-
- bool has_state_machine () const
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
{
- switch (get_type ()) {
- case 0: return u.ot.has_state_machine ();
-#ifndef HB_NO_AAT_SHAPE
- case 1: return u.aat.has_state_machine ();
-#endif
- default:return false;
+ 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;
}
}
- bool has_cross_stream () const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
- switch (get_type ()) {
- case 0: return u.ot.has_cross_stream ();
-#ifndef HB_NO_AAT_SHAPE
- case 1: return u.aat.has_cross_stream ();
-#endif
- default:return false;
+ 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);
}
}
- int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ struct accelerator_t
{
- switch (get_type ()) {
- case 0: return u.ot.get_h_kerning (left, right);
-#ifndef HB_NO_AAT_SHAPE
- case 1: return u.aat.get_h_kerning (left, right);
-#endif
- default:return 0;
+ 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);
}
- }
-
- bool apply (AAT::hb_aat_apply_context_t *c) const
- { return dispatch (c); }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- unsigned int subtable_type = get_type ();
- TRACE_DISPATCH (this, subtable_type);
- switch (subtable_type) {
- case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
-#ifndef HB_NO_AAT_SHAPE
- case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
-#endif
- default: return_trace (c->default_return_value ());
+ inline void fini (void)
+ {
+ hb_blob_destroy (blob);
}
- }
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.version32.sanitize (c)) return_trace (false);
- return_trace (dispatch (c));
- }
+ 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 {
- HBUINT32 version32;
- HBUINT16 major;
+ UINT16 major;
KernOT ot;
-#ifndef HB_NO_AAT_SHAPE
KernAAT aat;
-#endif
} u;
public:
- DEFINE_SIZE_UNION (4, version32);
+ DEFINE_SIZE_UNION (2, major);
};
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh
deleted file mode 100644
index 8179e5acd52..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-base-table.hh
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright © 2016 Elie Roux <[email protected]>
- * Copyright © 2018 Google, Inc.
- * Copyright © 2018-2019 Ebrahim Byagowi
- *
- * 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_LAYOUT_BASE_TABLE_HH
-#define HB_OT_LAYOUT_BASE_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-
-namespace OT {
-
-/*
- * BASE -- Baseline
- * https://docs.microsoft.com/en-us/typography/opentype/spec/base
- */
-
-struct BaseCoordFormat1
-{
- hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
- {
- return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- FWORD coordinate; /* X or Y value, in design units */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct BaseCoordFormat2
-{
- hb_position_t get_coord (hb_font_t *font, hb_direction_t direction) const
- {
- /* TODO */
- return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (coordinate) : font->em_scale_x (coordinate);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- FWORD coordinate; /* X or Y value, in design units */
- HBGlyphID16 referenceGlyph; /* Glyph ID of control glyph */
- HBUINT16 coordPoint; /* Index of contour point on the
- * reference glyph */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct BaseCoordFormat3
-{
- hb_position_t get_coord (hb_font_t *font,
- const VariationStore &var_store,
- hb_direction_t direction) const
- {
- const Device &device = this+deviceTable;
-
- return HB_DIRECTION_IS_HORIZONTAL (direction)
- ? font->em_scale_y (coordinate) + device.get_y_delta (font, var_store)
- : font->em_scale_x (coordinate) + device.get_x_delta (font, var_store);
- }
-
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- deviceTable.sanitize (c, this)));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 3 */
- FWORD coordinate; /* X or Y value, in design units */
- Offset16To<Device>
- deviceTable; /* Offset to Device table for X or
- * Y value, from beginning of
- * BaseCoord table (may be NULL). */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct BaseCoord
-{
- bool has_data () const { return u.format; }
-
- hb_position_t get_coord (hb_font_t *font,
- const VariationStore &var_store,
- hb_direction_t direction) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coord (font, direction);
- case 2: return u.format2.get_coord (font, direction);
- case 3: return u.format3.get_coord (font, var_store, direction);
- default:return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!u.format.sanitize (c))) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 3: return_trace (u.format3.sanitize (c));
- default:return_trace (false);
- }
- }
-
- protected:
- union {
- HBUINT16 format;
- BaseCoordFormat1 format1;
- BaseCoordFormat2 format2;
- BaseCoordFormat3 format3;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-struct FeatMinMaxRecord
-{
- int cmp (hb_tag_t key) const { return tag.cmp (key); }
-
- bool has_data () const { return tag; }
-
- void get_min_max (const BaseCoord **min, const BaseCoord **max) const
- {
- if (likely (min)) *min = &(this+minCoord);
- if (likely (max)) *max = &(this+maxCoord);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- minCoord.sanitize (c, this) &&
- maxCoord.sanitize (c, this)));
- }
-
- protected:
- Tag tag; /* 4-byte feature identification tag--must
- * match feature tag in FeatureList */
- Offset16To<BaseCoord>
- minCoord; /* Offset to BaseCoord table that defines
- * the minimum extent value, from beginning
- * of MinMax table (may be NULL) */
- Offset16To<BaseCoord>
- maxCoord; /* Offset to BaseCoord table that defines
- * the maximum extent value, from beginning
- * of MinMax table (may be NULL) */
- public:
- DEFINE_SIZE_STATIC (8);
-
-};
-
-struct MinMax
-{
- void get_min_max (hb_tag_t feature_tag,
- const BaseCoord **min,
- const BaseCoord **max) const
- {
- const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
- if (minMaxCoord.has_data ())
- minMaxCoord.get_min_max (min, max);
- else
- {
- if (likely (min)) *min = &(this+minCoord);
- if (likely (max)) *max = &(this+maxCoord);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- minCoord.sanitize (c, this) &&
- maxCoord.sanitize (c, this) &&
- featMinMaxRecords.sanitize (c, this)));
- }
-
- protected:
- Offset16To<BaseCoord>
- minCoord; /* Offset to BaseCoord table that defines
- * minimum extent value, from the beginning
- * of MinMax table (may be NULL) */
- Offset16To<BaseCoord>
- maxCoord; /* Offset to BaseCoord table that defines
- * maximum extent value, from the beginning
- * of MinMax table (may be NULL) */
- SortedArray16Of<FeatMinMaxRecord>
- featMinMaxRecords;
- /* Array of FeatMinMaxRecords, in alphabetical
- * order by featureTableTag */
- public:
- DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
-};
-
-struct BaseValues
-{
- const BaseCoord &get_base_coord (int baseline_tag_index) const
- {
- if (baseline_tag_index == -1) baseline_tag_index = defaultIndex;
- return this+baseCoords[baseline_tag_index];
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- baseCoords.sanitize (c, this)));
- }
-
- protected:
- Index defaultIndex; /* Index number of default baseline for this
- * script — equals index position of baseline tag
- * in baselineTags array of the BaseTagList */
- Array16OfOffset16To<BaseCoord>
- baseCoords; /* Number of BaseCoord tables defined — should equal
- * baseTagCount in the BaseTagList
- *
- * Array of offsets to BaseCoord tables, from beginning of
- * BaseValues table — order matches baselineTags array in
- * the BaseTagList */
- public:
- DEFINE_SIZE_ARRAY (4, baseCoords);
-};
-
-struct BaseLangSysRecord
-{
- int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
-
- bool has_data () const { return baseLangSysTag; }
-
- const MinMax &get_min_max () const { return this+minMax; }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- minMax.sanitize (c, this)));
- }
-
- protected:
- Tag baseLangSysTag; /* 4-byte language system identification tag */
- Offset16To<MinMax>
- minMax; /* Offset to MinMax table, from beginning
- * of BaseScript table */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct BaseScript
-{
- const MinMax &get_min_max (hb_tag_t language_tag) const
- {
- const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
- return record.has_data () ? record.get_min_max () : this+defaultMinMax;
- }
-
- const BaseCoord &get_base_coord (int baseline_tag_index) const
- { return (this+baseValues).get_base_coord (baseline_tag_index); }
-
- bool has_data () const { return baseValues; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- baseValues.sanitize (c, this) &&
- defaultMinMax.sanitize (c, this) &&
- baseLangSysRecords.sanitize (c, this)));
- }
-
- protected:
- Offset16To<BaseValues>
- baseValues; /* Offset to BaseValues table, from beginning
- * of BaseScript table (may be NULL) */
- Offset16To<MinMax>
- defaultMinMax; /* Offset to MinMax table, from beginning of
- * BaseScript table (may be NULL) */
- SortedArray16Of<BaseLangSysRecord>
- baseLangSysRecords;
- /* Number of BaseLangSysRecords
- * defined — may be zero (0) */
-
- public:
- DEFINE_SIZE_ARRAY (6, baseLangSysRecords);
-};
-
-struct BaseScriptList;
-struct BaseScriptRecord
-{
- int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
-
- bool has_data () const { return baseScriptTag; }
-
- const BaseScript &get_base_script (const BaseScriptList *list) const
- { return list+baseScript; }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- baseScript.sanitize (c, base)));
- }
-
- protected:
- Tag baseScriptTag; /* 4-byte script identification tag */
- Offset16To<BaseScript>
- baseScript; /* Offset to BaseScript table, from beginning
- * of BaseScriptList */
-
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct BaseScriptList
-{
- const BaseScript &get_base_script (hb_tag_t script) const
- {
- const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
- if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
- return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- baseScriptRecords.sanitize (c, this));
- }
-
- protected:
- SortedArray16Of<BaseScriptRecord>
- baseScriptRecords;
-
- public:
- DEFINE_SIZE_ARRAY (2, baseScriptRecords);
-};
-
-struct Axis
-{
- bool get_baseline (hb_tag_t baseline_tag,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- const BaseCoord **coord) const
- {
- const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (!base_script.has_data ())
- {
- *coord = nullptr;
- return false;
- }
-
- if (likely (coord))
- {
- unsigned int tag_index = 0;
- if (!(this+baseTagList).bfind (baseline_tag, &tag_index))
- {
- *coord = nullptr;
- return false;
- }
- *coord = &base_script.get_base_coord (tag_index);
- }
-
- return true;
- }
-
- bool get_min_max (hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_tag_t feature_tag,
- const BaseCoord **min_coord,
- const BaseCoord **max_coord) const
- {
- const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (!base_script.has_data ())
- {
- *min_coord = *max_coord = nullptr;
- return false;
- }
-
- base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
-
- return true;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- (this+baseTagList).sanitize (c) &&
- (this+baseScriptList).sanitize (c)));
- }
-
- protected:
- Offset16To<SortedArray16Of<Tag>>
- baseTagList; /* Offset to BaseTagList table, from beginning
- * of Axis table (may be NULL)
- * Array of 4-byte baseline identification tags — must
- * be in alphabetical order */
- Offset16To<BaseScriptList>
- baseScriptList; /* Offset to BaseScriptList table, from beginning
- * of Axis table
- * Array of BaseScriptRecords, in alphabetical order
- * by baseScriptTag */
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct BASE
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_BASE;
-
- const Axis &get_axis (hb_direction_t direction) const
- { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; }
-
- const VariationStore &get_var_store () const
- { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; }
-
- bool get_baseline (hb_font_t *font,
- hb_tag_t baseline_tag,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_position_t *base) const
- {
- const BaseCoord *base_coord = nullptr;
- if (unlikely (!get_axis (direction).get_baseline (baseline_tag, script_tag, language_tag, &base_coord) ||
- !base_coord || !base_coord->has_data ()))
- return false;
-
- if (likely (base))
- *base = base_coord->get_coord (font, get_var_store (), direction);
-
- return true;
- }
-
- /* TODO: Expose this separately sometime? */
- bool get_min_max (hb_font_t *font,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_tag_t feature_tag,
- hb_position_t *min,
- hb_position_t *max)
- {
- const BaseCoord *min_coord, *max_coord;
- if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag,
- &min_coord, &max_coord))
- return false;
-
- const VariationStore &var_store = get_var_store ();
- if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction);
- if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction);
- return true;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- likely (version.major == 1) &&
- hAxis.sanitize (c, this) &&
- vAxis.sanitize (c, this) &&
- (version.to_int () < 0x00010001u || varStore.sanitize (c, this))));
- }
-
- protected:
- FixedVersion<>version; /* Version of the BASE table */
- Offset16To<Axis>hAxis; /* Offset to horizontal Axis table, from beginning
- * of BASE table (may be NULL) */
- Offset16To<Axis>vAxis; /* Offset to vertical Axis table, from beginning
- * of BASE table (may be NULL) */
- Offset32To<VariationStore>
- varStore; /* Offset to the table of Item Variation
- * Store--from beginning of BASE
- * header (may be NULL). Introduced
- * in version 0x00010001. */
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_LAYOUT_BASE_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
new file mode 100644
index 00000000000..5e699e1967f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -0,0 +1,1772 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#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"
+
+
+#ifndef HB_MAX_NESTING_LEVEL
+#define HB_MAX_NESTING_LEVEL 6
+#endif
+#ifndef HB_MAX_CONTEXT_LENGTH
+#define HB_MAX_CONTEXT_LENGTH 64
+#endif
+
+
+namespace OT {
+
+
+#define NOT_COVERED ((unsigned int) -1)
+
+
+
+/*
+ *
+ * OpenType Layout Common Table Formats
+ *
+ */
+
+
+/*
+ * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
+ */
+
+template <typename Type>
+struct Record
+{
+ inline int cmp (hb_tag_t a) const {
+ return tag.cmp (a);
+ }
+
+ struct sanitize_closure_t {
+ hb_tag_t tag;
+ const void *list_base;
+ };
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ const sanitize_closure_t closure = {tag, base};
+ return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
+ }
+
+ Tag tag; /* 4-byte Tag identifier */
+ OffsetTo<Type>
+ offset; /* Offset from beginning of object holding
+ * the Record */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+template <typename Type>
+struct RecordArrayOf : SortedArrayOf<Record<Type> > {
+ inline const Tag& get_tag (unsigned int i) const
+ {
+ /* We cheat slightly and don't define separate Null objects
+ * for Record types. Instead, we return the correct Null(Tag)
+ * here. */
+ if (unlikely (i >= this->len)) return Null(Tag);
+ return (*this)[i].tag;
+ }
+ inline unsigned int get_tags (unsigned int start_offset,
+ unsigned int *record_count /* IN/OUT */,
+ hb_tag_t *record_tags /* OUT */) const
+ {
+ if (record_count) {
+ const Record<Type> *arr = this->sub_array (start_offset, record_count);
+ unsigned int count = *record_count;
+ for (unsigned int i = 0; i < count; i++)
+ record_tags[i] = arr[i].tag;
+ }
+ return this->len;
+ }
+ inline bool find_index (hb_tag_t tag, unsigned int *index) const
+ {
+ /* If we want to allow non-sorted data, we can lsearch(). */
+ int i = this->/*lsearch*/bsearch (tag);
+ if (i != -1) {
+ if (index) *index = i;
+ return true;
+ } else {
+ if (index) *index = Index::NOT_FOUND_INDEX;
+ return false;
+ }
+ }
+};
+
+template <typename Type>
+struct RecordListOf : RecordArrayOf<Type>
+{
+ inline const Type& operator [] (unsigned int i) const
+ { return this+RecordArrayOf<Type>::operator [](i).offset; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (RecordArrayOf<Type>::sanitize (c, this));
+ }
+};
+
+
+struct RangeRecord
+{
+ inline int cmp (hb_codepoint_t g) const {
+ return g < start ? -1 : g <= end ? 0 : +1 ;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ inline bool intersects (const hb_set_t *glyphs) const {
+ return glyphs->intersects (start, end);
+ }
+
+ template <typename set_t>
+ 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 */
+ UINT16 value; /* Value */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+DEFINE_NULL_DATA (RangeRecord, "\000\001");
+
+
+struct IndexArray : ArrayOf<Index>
+{
+ inline unsigned int get_indexes (unsigned int start_offset,
+ unsigned int *_count /* IN/OUT */,
+ unsigned int *_indexes /* OUT */) const
+ {
+ if (_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];
+ }
+ return this->len;
+ }
+};
+
+
+struct Script;
+struct LangSys;
+struct Feature;
+
+
+struct LangSys
+{
+ inline unsigned int get_feature_count (void) const
+ { return featureIndex.len; }
+ inline hb_tag_t get_feature_index (unsigned int i) const
+ { return featureIndex[i]; }
+ inline unsigned int get_feature_indexes (unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ unsigned int *feature_indexes /* OUT */) const
+ { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
+
+ inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; }
+ inline unsigned int get_required_feature_index (void) const
+ {
+ if (reqFeatureIndex == 0xFFFFu)
+ return Index::NOT_FOUND_INDEX;
+ return reqFeatureIndex;;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<LangSys>::sanitize_closure_t * = nullptr) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && featureIndex.sanitize (c));
+ }
+
+ Offset16 lookupOrderZ; /* = Null (reserved for an offset to a
+ * reordering table) */
+ UINT16 reqFeatureIndex;/* Index of a feature required for this
+ * language system--if no required features
+ * = 0xFFFFu */
+ IndexArray featureIndex; /* Array of indices into the FeatureList */
+ public:
+ DEFINE_SIZE_ARRAY (6, featureIndex);
+};
+DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
+
+
+struct Script
+{
+ inline unsigned int get_lang_sys_count (void) const
+ { return langSys.len; }
+ inline const Tag& get_lang_sys_tag (unsigned int i) const
+ { return langSys.get_tag (i); }
+ inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+ unsigned int *lang_sys_count /* IN/OUT */,
+ hb_tag_t *lang_sys_tags /* OUT */) const
+ { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+ inline const LangSys& get_lang_sys (unsigned int i) const
+ {
+ if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+ return this+langSys[i].offset;
+ }
+ inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+ { return langSys.find_index (tag, index); }
+
+ inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+ 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 * = nullptr) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<LangSys>
+ defaultLangSys; /* Offset to DefaultLangSys table--from
+ * beginning of Script table--may be Null */
+ RecordArrayOf<LangSys>
+ langSys; /* Array of LangSysRecords--listed
+ * alphabetically by LangSysTag */
+ public:
+ DEFINE_SIZE_ARRAY (4, langSys);
+};
+
+typedef RecordListOf<Script> ScriptList;
+
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+struct FeatureParamsSize
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return_trace (false);
+
+ /* This subtable has some "history", if you will. Some earlier versions of
+ * Adobe tools calculated the offset of the FeatureParams sutable from the
+ * beginning of the FeatureList table! Now, that is dealt with in the
+ * Feature implementation. But we still need to be able to tell junk from
+ * real data. Note: We don't check that the nameID actually exists.
+ *
+ * Read Roberts wrote on 9/15/06 on [email protected] :
+ *
+ * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
+ * coming out soon, and that the makeotf program will build a font with a
+ * 'size' feature that is correct by the specification.
+ *
+ * The specification for this feature tag is in the "OpenType Layout Tag
+ * Registry". You can see a copy of this at:
+ * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size
+ *
+ * Here is one set of rules to determine if the 'size' feature is built
+ * correctly, or as by the older versions of MakeOTF. You may be able to do
+ * better.
+ *
+ * Assume that the offset to the size feature is according to specification,
+ * and make the following value checks. If it fails, assume the the size
+ * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
+ * If this fails, reject the 'size' feature. The older makeOTF's calculated the
+ * offset from the beginning of the FeatureList table, rather than from the
+ * beginning of the 'size' Feature table.
+ *
+ * If "design size" == 0:
+ * fails check
+ *
+ * Else if ("subfamily identifier" == 0 and
+ * "range start" == 0 and
+ * "range end" == 0 and
+ * "range start" == 0 and
+ * "menu name ID" == 0)
+ * passes check: this is the format used when there is a design size
+ * specified, but there is no recommended size range.
+ *
+ * Else if ("design size" < "range start" or
+ * "design size" > "range end" or
+ * "range end" <= "range start" or
+ * "menu name ID" < 256 or
+ * "menu name ID" > 32767 or
+ * menu name ID is not a name ID which is actually in the name table)
+ * fails test
+ * Else
+ * passes test.
+ */
+
+ if (!designSize)
+ return_trace (false);
+ else if (subfamilyID == 0 &&
+ subfamilyNameID == 0 &&
+ rangeStart == 0 &&
+ rangeEnd == 0)
+ return_trace (true);
+ else if (designSize < rangeStart ||
+ designSize > rangeEnd ||
+ subfamilyNameID < 256 ||
+ subfamilyNameID > 32767)
+ return_trace (false);
+ else
+ return_trace (true);
+ }
+
+ 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. */
+ 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
+ * differ only by size range shall have the
+ * same subfamily value, and no fonts which
+ * differ in weight or style shall have the
+ * same subfamily value. If this value is
+ * zero, the remaining fields in the array
+ * will be ignored. */
+ 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
+ * contain English-language strings encoded
+ * in Windows Unicode and Macintosh Roman,
+ * and may contain additional strings
+ * localized to other scripts and languages.
+ * Each of these strings is the name an
+ * application should use, in combination
+ * with the family name, to represent the
+ * subfamily in a menu. Applications will
+ * choose the appropriate version based on
+ * their selection criteria. */
+ UINT16 rangeStart; /* Large end of the recommended usage range
+ * (inclusive), stored in 720/inch units
+ * (decipoints). */
+ UINT16 rangeEnd; /* Small end of the recommended usage range
+ (exclusive), stored in 720/inch units
+ * (decipoints). */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
+struct FeatureParamsStylisticSet
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ /* Right now minorVersion is at zero. Which means, any table supports
+ * the uiNameID field. */
+ return_trace (c->check_struct (this));
+ }
+
+ 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. */
+
+ 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
+ * sampleTextNameId are expected to be in the
+ * font-specific name ID range (256-32767),
+ * though that is not a requirement in this
+ * Feature Parameters specification. The
+ * user-interface label for the feature can
+ * be provided in multiple languages. An
+ * English string should be included as a
+ * fallback. The string should be kept to a
+ * minimal length to fit comfortably with
+ * different application interfaces. */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
+struct FeatureParamsCharacterVariants
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ characters.sanitize (c));
+ }
+
+ 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 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
+ * nullptr.) */
+ UINT16 sampleTextNameID; /* The ‘name’ table name ID that
+ * specifies sample text that
+ * illustrates the effect of this
+ * feature. (May be nullptr.) */
+ UINT16 numNamedParameters; /* Number of named parameters. (May
+ * be zero.) */
+ UINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID
+ * used to specify strings for
+ * user-interface labels for the
+ * feature parameters. (Must be zero
+ * if numParameters is zero.) */
+ ArrayOf<UINT24>
+ characters; /* Array of the Unicode Scalar Value
+ * of the characters for which this
+ * feature provides glyph variants.
+ * (May be zero.) */
+ public:
+ DEFINE_SIZE_ARRAY (14, characters);
+};
+
+struct FeatureParams
+{
+ inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
+ {
+ TRACE_SANITIZE (this);
+ if (tag == HB_TAG ('s','i','z','e'))
+ return_trace (u.size.sanitize (c));
+ if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+ return_trace (u.stylisticSet.sanitize (c));
+ if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+ return_trace (u.characterVariants.sanitize (c));
+ return_trace (true);
+ }
+
+ inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const
+ {
+ if (tag == HB_TAG ('s','i','z','e'))
+ return u.size;
+ return Null(FeatureParamsSize);
+ }
+
+ private:
+ union {
+ FeatureParamsSize size;
+ FeatureParamsStylisticSet stylisticSet;
+ FeatureParamsCharacterVariants characterVariants;
+ } u;
+ DEFINE_SIZE_STATIC (17);
+};
+
+struct Feature
+{
+ inline unsigned int get_lookup_count (void) const
+ { return lookupIndex.len; }
+ inline hb_tag_t get_lookup_index (unsigned int i) const
+ { return lookupIndex[i]; }
+ inline unsigned int get_lookup_indexes (unsigned int start_index,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_tags /* OUT */) const
+ { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
+
+ inline const FeatureParams &get_feature_params (void) const
+ { return this+featureParams; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<Feature>::sanitize_closure_t *closure = nullptr) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
+ return_trace (false);
+
+ /* Some earlier versions of Adobe tools calculated the offset of the
+ * FeatureParams subtable from the beginning of the FeatureList table!
+ *
+ * If sanitizing "failed" for the FeatureParams subtable, try it with the
+ * alternative location. We would know sanitize "failed" if old value
+ * of the offset was non-zero, but it's zeroed now.
+ *
+ * Only do this for the 'size' feature, since at the time of the faulty
+ * Adobe tools, only the 'size' feature had FeatureParams defined.
+ */
+
+ OffsetTo<FeatureParams> orig_offset = featureParams;
+ if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
+ return_trace (false);
+
+ if (likely (orig_offset.is_null ()))
+ return_trace (true);
+
+ if (featureParams == 0 && closure &&
+ closure->tag == HB_TAG ('s','i','z','e') &&
+ closure->list_base && closure->list_base < this)
+ {
+ unsigned int new_offset_int = (unsigned int) orig_offset -
+ (((char *) this) - ((char *) closure->list_base));
+
+ OffsetTo<FeatureParams> new_offset;
+ /* Check that it did not overflow. */
+ new_offset.set (new_offset_int);
+ if (new_offset == new_offset_int &&
+ c->try_set (&featureParams, new_offset) &&
+ !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
+ return_trace (false);
+
+ if (c->edit_count > 1)
+ c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */
+ }
+
+ return_trace (true);
+ }
+
+ OffsetTo<FeatureParams>
+ featureParams; /* Offset to Feature Parameters table (if one
+ * has been defined for the feature), relative
+ * to the beginning of the Feature Table; = Null
+ * if not required */
+ IndexArray lookupIndex; /* Array of LookupList indices */
+ public:
+ DEFINE_SIZE_ARRAY (4, lookupIndex);
+};
+
+typedef RecordListOf<Feature> FeatureList;
+
+
+struct LookupFlag : UINT16
+{
+ enum Flags {
+ RightToLeft = 0x0001u,
+ IgnoreBaseGlyphs = 0x0002u,
+ IgnoreLigatures = 0x0004u,
+ IgnoreMarks = 0x0008u,
+ IgnoreFlags = 0x000Eu,
+ UseMarkFilteringSet = 0x0010u,
+ Reserved = 0x00E0u,
+ MarkAttachmentType = 0xFF00u
+ };
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+} /* namespace OT */
+/* This has to be outside the namespace. */
+HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags);
+namespace OT {
+
+struct Lookup
+{
+ inline unsigned int get_subtable_count (void) const { return subTable.len; }
+
+ template <typename SubTableType>
+ inline const SubTableType& get_subtable (unsigned int i) const
+ { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; }
+
+ template <typename SubTableType>
+ inline const OffsetArrayOf<SubTableType>& get_subtables (void) const
+ { return CastR<OffsetArrayOf<SubTableType> > (subTable); }
+ template <typename SubTableType>
+ inline OffsetArrayOf<SubTableType>& get_subtables (void)
+ { return CastR<OffsetArrayOf<SubTableType> > (subTable); }
+
+ inline unsigned int get_type (void) const { return lookupType; }
+
+ /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
+ * higher 16-bit is mark-filtering-set if the lookup uses one.
+ * Not to be confused with glyph_props which is very similar. */
+ inline uint32_t get_props (void) const
+ {
+ unsigned int flag = lookupFlag;
+ if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
+ {
+ const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
+ flag += (markFilteringSet << 16);
+ }
+ return flag;
+ }
+
+ template <typename SubTableType, typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ unsigned int lookup_type = get_type ();
+ TRACE_DISPATCH (this, lookup_type);
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return_trace (r);
+ }
+ return_trace (c->default_return_value ());
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ unsigned int lookup_type,
+ uint32_t lookup_props,
+ unsigned int num_subtables)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ lookupType.set (lookup_type);
+ lookupFlag.set (lookup_props & 0xFFFFu);
+ if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
+ if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+ {
+ UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
+ markFilteringSet.set (lookup_props >> 16);
+ }
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ /* Real sanitize of the subtables is done by GSUB/GPOS/... */
+ if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
+ if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+ {
+ const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
+ if (!markFilteringSet.sanitize (c)) return_trace (false);
+ }
+ return_trace (true);
+ }
+
+ private:
+ UINT16 lookupType; /* Different enumerations for GSUB and GPOS */
+ UINT16 lookupFlag; /* Lookup qualifiers */
+ ArrayOf<Offset16>
+ subTable; /* Array of SubTables */
+ 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:
+ DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
+};
+
+typedef OffsetListOf<Lookup> LookupList;
+
+
+/*
+ * Coverage Table
+ */
+
+struct CoverageFormat1
+{
+ friend struct Coverage;
+
+ private:
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ int i = glyphArray.bsearch (glyph_id);
+ static_assert ((((unsigned int) -1) == NOT_COVERED), "");
+ return i;
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ glyphArray.len.set (num_glyphs);
+ if (unlikely (!c->extend (glyphArray))) return_trace (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ glyphArray[i] = glyphs[i];
+ glyphs.advance (num_glyphs);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (glyphArray.sanitize (c));
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ return glyphs->has (glyphArray[index]);
+ }
+
+ template <typename set_t>
+ inline bool add_coverage (set_t *glyphs) const {
+ return glyphs->add_sorted_array (glyphArray.array, glyphArray.len);
+ }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct Iter {
+ inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
+ inline bool more (void) { return i < c->glyphArray.len; }
+ inline void next (void) { i++; }
+ inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; }
+ inline unsigned int get_coverage (void) { return i; }
+
+ private:
+ const struct CoverageFormat1 *c;
+ unsigned int i;
+ };
+ private:
+
+ protected:
+ UINT16 coverageFormat; /* Format identifier--format = 1 */
+ SortedArrayOf<GlyphID>
+ glyphArray; /* Array of GlyphIDs--in numerical order */
+ public:
+ DEFINE_SIZE_ARRAY (4, glyphArray);
+};
+
+struct CoverageFormat2
+{
+ friend struct Coverage;
+
+ private:
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ int i = rangeRecord.bsearch (glyph_id);
+ if (i != -1) {
+ const RangeRecord &range = rangeRecord[i];
+ return (unsigned int) range.value + (glyph_id - range.start);
+ }
+ return NOT_COVERED;
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+
+ if (unlikely (!num_glyphs))
+ {
+ rangeRecord.len.set (0);
+ return_trace (true);
+ }
+
+ unsigned int num_ranges = 1;
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i])
+ num_ranges++;
+ rangeRecord.len.set (num_ranges);
+ if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+
+ unsigned int range = 0;
+ rangeRecord[range].start = glyphs[0];
+ rangeRecord[range].value.set (0);
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i]) {
+ range++;
+ rangeRecord[range].start = glyphs[i];
+ rangeRecord[range].value.set (i);
+ rangeRecord[range].end = glyphs[i];
+ } else {
+ rangeRecord[range].end = glyphs[i];
+ }
+ glyphs.advance (num_glyphs);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rangeRecord.sanitize (c));
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ unsigned int i;
+ unsigned int count = rangeRecord.len;
+ for (i = 0; i < count; i++) {
+ const RangeRecord &range = rangeRecord[i];
+ if (range.value <= index &&
+ index < (unsigned int) range.value + (range.end - range.start) &&
+ range.intersects (glyphs))
+ return true;
+ else if (index < range.value)
+ return false;
+ }
+ return false;
+ }
+
+ template <typename set_t>
+ inline bool add_coverage (set_t *glyphs) const {
+ unsigned int count = rangeRecord.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+ return false;
+ return true;
+ }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct Iter
+ {
+ inline void init (const CoverageFormat2 &c_)
+ {
+ c = &c_;
+ coverage = 0;
+ i = 0;
+ j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0;
+ }
+ inline bool more (void) { return i < c->rangeRecord.len; }
+ inline void next (void)
+ {
+ if (j >= c->rangeRecord[i].end)
+ {
+ i++;
+ if (more ())
+ {
+ j = c->rangeRecord[i].start;
+ coverage = c->rangeRecord[i].value;
+ }
+ return;
+ }
+ coverage++;
+ j++;
+ }
+ inline hb_codepoint_t get_glyph (void) { return j; }
+ inline unsigned int get_coverage (void) { return coverage; }
+
+ private:
+ const struct CoverageFormat2 *c;
+ unsigned int i, j, coverage;
+ };
+ private:
+
+ protected:
+ UINT16 coverageFormat; /* Format identifier--format = 2 */
+ SortedArrayOf<RangeRecord>
+ rangeRecord; /* Array of glyph ranges--ordered by
+ * Start GlyphID. rangeCount entries
+ * long */
+ public:
+ DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct Coverage
+{
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_coverage(glyph_id);
+ case 2: return u.format2.get_coverage(glyph_id);
+ default:return NOT_COVERED;
+ }
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ unsigned int num_ranges = 1;
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (glyphs[i - 1] + 1 != glyphs[i])
+ num_ranges++;
+ u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
+ switch (u.format) {
+ case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs));
+ case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs));
+ default:return_trace (false);
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ inline bool intersects (const hb_set_t *glyphs) const {
+ /* TODO speed this up */
+ Coverage::Iter iter;
+ for (iter.init (*this); iter.more (); iter.next ()) {
+ if (glyphs->has (iter.get_glyph ()))
+ return true;
+ }
+ return false;
+ }
+
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_coverage (glyphs, index);
+ case 2: return u.format2.intersects_coverage (glyphs, index);
+ default:return false;
+ }
+ }
+
+ /* 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;
+ }
+ }
+
+ struct Iter {
+ Iter (void) : format (0), u () {};
+ inline void init (const Coverage &c_) {
+ format = c_.u.format;
+ switch (format) {
+ case 1: u.format1.init (c_.u.format1); return;
+ case 2: u.format2.init (c_.u.format2); return;
+ default: return;
+ }
+ }
+ inline bool more (void) {
+ switch (format) {
+ case 1: return u.format1.more ();
+ case 2: return u.format2.more ();
+ default:return false;
+ }
+ }
+ inline void next (void) {
+ switch (format) {
+ case 1: u.format1.next (); break;
+ case 2: u.format2.next (); break;
+ default: break;
+ }
+ }
+ inline hb_codepoint_t get_glyph (void) {
+ switch (format) {
+ case 1: return u.format1.get_glyph ();
+ case 2: return u.format2.get_glyph ();
+ default:return 0;
+ }
+ }
+ inline unsigned int get_coverage (void) {
+ switch (format) {
+ case 1: return u.format1.get_coverage ();
+ case 2: return u.format2.get_coverage ();
+ default:return -1;
+ }
+ }
+
+ private:
+ unsigned int format;
+ union {
+ CoverageFormat2::Iter format2; /* Put this one first since it's larger; helps shut up compiler. */
+ CoverageFormat1::Iter format1;
+ } u;
+ };
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ CoverageFormat1 format1;
+ CoverageFormat2 format2;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Class Definition Table
+ */
+
+struct ClassDefFormat1
+{
+ friend struct ClassDef;
+
+ private:
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ unsigned int i = (unsigned int) (glyph_id - startGlyph);
+ if (unlikely (i < classValue.len))
+ return classValue[i];
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && classValue.sanitize (c));
+ }
+
+ template <typename set_t>
+ 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 {
+ unsigned int count = classValue.len;
+ if (klass == 0)
+ {
+ /* Match if there's any glyph that is not listed! */
+ hb_codepoint_t g = -1;
+ if (!hb_set_next (glyphs, &g))
+ return false;
+ if (g < startGlyph)
+ return true;
+ g = startGlyph + count - 1;
+ if (hb_set_next (glyphs, &g))
+ return true;
+ /* Fall through. */
+ }
+ for (unsigned int i = 0; i < count; i++)
+ if (classValue[i] == klass && glyphs->has (startGlyph + i))
+ return true;
+ return false;
+ }
+
+ protected:
+ UINT16 classFormat; /* Format identifier--format = 1 */
+ GlyphID startGlyph; /* First GlyphID of the classValueArray */
+ ArrayOf<UINT16>
+ classValue; /* Array of Class Values--one per GlyphID */
+ public:
+ DEFINE_SIZE_ARRAY (6, classValue);
+};
+
+struct ClassDefFormat2
+{
+ friend struct ClassDef;
+
+ private:
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ int i = rangeRecord.bsearch (glyph_id);
+ if (unlikely (i != -1))
+ return rangeRecord[i].value;
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rangeRecord.sanitize (c));
+ }
+
+ template <typename set_t>
+ 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)
+ if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+ return false;
+ }
+ return true;
+ }
+
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+ unsigned int count = rangeRecord.len;
+ if (klass == 0)
+ {
+ /* Match if there's any glyph that is not listed! */
+ hb_codepoint_t g = (hb_codepoint_t) -1;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (!hb_set_next (glyphs, &g))
+ break;
+ if (g < rangeRecord[i].start)
+ return true;
+ g = rangeRecord[i].end;
+ }
+ if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g))
+ return true;
+ /* Fall through. */
+ }
+ for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
+ return true;
+ return false;
+ }
+
+ protected:
+ UINT16 classFormat; /* Format identifier--format = 2 */
+ SortedArrayOf<RangeRecord>
+ rangeRecord; /* Array of glyph ranges--ordered by
+ * Start GlyphID */
+ public:
+ DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct ClassDef
+{
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_class(glyph_id);
+ case 2: return u.format2.get_class(glyph_id);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ /* 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: return u.format1.add_class (glyphs, klass);
+ case 2: return u.format2.add_class (glyphs, klass);
+ default:return false;
+ }
+ }
+
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_class (glyphs, klass);
+ case 2: return u.format2.intersects_class (glyphs, klass);
+ default:return false;
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ClassDefFormat1 format1;
+ ClassDefFormat2 format2;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Item Variation Store
+ */
+
+struct VarRegionAxis
+{
+ inline float evaluate (int coord) const
+ {
+ int start = startCoord, peak = peakCoord, end = endCoord;
+
+ /* TODO Move these to sanitize(). */
+ if (unlikely (start > peak || peak > end))
+ return 1.;
+ if (unlikely (start < 0 && end > 0 && peak != 0))
+ return 1.;
+
+ if (peak == 0 || coord == peak)
+ return 1.;
+
+ if (coord <= start || end <= coord)
+ return 0.;
+
+ /* Interpolate */
+ if (coord < peak)
+ return float (coord - start) / (peak - start);
+ else
+ return float (end - coord) / (end - peak);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ /* TODO Handle invalid start/peak/end configs, so we don't
+ * have to do that at runtime. */
+ }
+
+ public:
+ F2DOT14 startCoord;
+ F2DOT14 peakCoord;
+ F2DOT14 endCoord;
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct VarRegionList
+{
+ inline float evaluate (unsigned int region_index,
+ int *coords, unsigned int coord_len) const
+ {
+ if (unlikely (region_index >= regionCount))
+ return 0.;
+
+ const VarRegionAxis *axes = axesZ + (region_index * axisCount);
+
+ float v = 1.;
+ unsigned int count = MIN (coord_len, (unsigned int) axisCount);
+ for (unsigned int i = 0; i < count; i++)
+ {
+ float factor = axes[i].evaluate (coords[i]);
+ if (factor == 0.)
+ return 0.;
+ v *= factor;
+ }
+ return v;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (axesZ, axesZ[0].static_size,
+ (unsigned int) axisCount * (unsigned int) regionCount));
+ }
+
+ protected:
+ UINT16 axisCount;
+ UINT16 regionCount;
+ VarRegionAxis axesZ[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (4, axesZ);
+};
+
+struct VarData
+{
+ inline unsigned int get_row_size (void) const
+ { return shortCount + regionIndices.len; }
+
+ inline unsigned int get_size (void) const
+ { return itemCount * get_row_size (); }
+
+ inline float get_delta (unsigned int inner,
+ int *coords, unsigned int coord_count,
+ const VarRegionList &regions) const
+ {
+ if (unlikely (inner >= itemCount))
+ return 0.;
+
+ unsigned int count = regionIndices.len;
+ unsigned int scount = shortCount;
+
+ const UINT8 *bytes = &StructAfter<UINT8> (regionIndices);
+ const UINT8 *row = bytes + inner * (scount + count);
+
+ float delta = 0.;
+ unsigned int i = 0;
+
+ const INT16 *scursor = reinterpret_cast<const INT16 *> (row);
+ for (; i < scount; i++)
+ {
+ float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
+ delta += scalar * *scursor++;
+ }
+ const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor);
+ for (; i < count; i++)
+ {
+ float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
+ delta += scalar * *bcursor++;
+ }
+
+ return delta;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ regionIndices.sanitize(c) &&
+ shortCount <= regionIndices.len &&
+ c->check_array (&StructAfter<UINT8> (regionIndices),
+ get_row_size (), itemCount));
+ }
+
+ protected:
+ UINT16 itemCount;
+ UINT16 shortCount;
+ ArrayOf<UINT16> regionIndices;
+ UINT8 bytesX[VAR];
+ public:
+ DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
+};
+
+struct VariationStore
+{
+ inline float get_delta (unsigned int outer, unsigned int inner,
+ int *coords, unsigned int coord_count) const
+ {
+ if (unlikely (outer >= dataSets.len))
+ return 0.;
+
+ return (this+dataSets[outer]).get_delta (inner,
+ coords, coord_count,
+ 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);
+ return_trace (c->check_struct (this) &&
+ format == 1 &&
+ regions.sanitize (c, this) &&
+ dataSets.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format;
+ LOffsetTo<VarRegionList> regions;
+ OffsetArrayOf<VarData, UINT32> dataSets;
+ public:
+ DEFINE_SIZE_ARRAY (8, dataSets);
+};
+
+/*
+ * Feature Variations
+ */
+
+struct ConditionFormat1
+{
+ friend struct Condition;
+
+ private:
+ inline bool evaluate (const int *coords, unsigned int coord_len) const
+ {
+ int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
+ return filterRangeMinValue <= coord && coord <= filterRangeMaxValue;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ UINT16 axisIndex;
+ F2DOT14 filterRangeMinValue;
+ F2DOT14 filterRangeMaxValue;
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct Condition
+{
+ inline bool evaluate (const int *coords, unsigned int coord_len) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.evaluate (coords, coord_len);
+ default:return false;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ConditionFormat1 format1;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+struct ConditionSet
+{
+ inline bool evaluate (const int *coords, unsigned int coord_len) const
+ {
+ unsigned int count = conditions.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+conditions.array[i]).evaluate (coords, coord_len))
+ return false;
+ return true;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (conditions.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<Condition, UINT32> conditions;
+ public:
+ DEFINE_SIZE_ARRAY (2, conditions);
+};
+
+struct FeatureTableSubstitutionRecord
+{
+ friend struct FeatureTableSubstitution;
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && feature.sanitize (c, base));
+ }
+
+ protected:
+ UINT16 featureIndex;
+ LOffsetTo<Feature> feature;
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct FeatureTableSubstitution
+{
+ inline const Feature *find_substitute (unsigned int feature_index) const
+ {
+ unsigned int count = substitutions.len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const FeatureTableSubstitutionRecord &record = substitutions.array[i];
+ if (record.featureIndex == feature_index)
+ return &(this+record.feature);
+ }
+ return nullptr;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ substitutions.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion<> version; /* Version--0x00010000u */
+ ArrayOf<FeatureTableSubstitutionRecord>
+ substitutions;
+ public:
+ DEFINE_SIZE_ARRAY (6, substitutions);
+};
+
+struct FeatureVariationRecord
+{
+ friend struct FeatureVariations;
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (conditions.sanitize (c, base) &&
+ substitutions.sanitize (c, base));
+ }
+
+ protected:
+ LOffsetTo<ConditionSet>
+ conditions;
+ LOffsetTo<FeatureTableSubstitution>
+ substitutions;
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct FeatureVariations
+{
+ static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu;
+
+ inline bool find_index (const int *coords, unsigned int coord_len,
+ unsigned int *index) const
+ {
+ unsigned int count = varRecords.len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const FeatureVariationRecord &record = varRecords.array[i];
+ if ((this+record.conditions).evaluate (coords, coord_len))
+ {
+ *index = i;
+ return true;
+ }
+ }
+ *index = NOT_FOUND_INDEX;
+ return false;
+ }
+
+ inline const Feature *find_substitute (unsigned int variations_index,
+ unsigned int feature_index) const
+ {
+ const FeatureVariationRecord &record = varRecords[variations_index];
+ return (this+record.substitutions).find_substitute (feature_index);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ varRecords.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion<> version; /* Version--0x00010000u */
+ LArrayOf<FeatureVariationRecord>
+ varRecords;
+ public:
+ DEFINE_SIZE_ARRAY (8, varRecords);
+};
+
+
+/*
+ * Device Tables
+ */
+
+struct HintingDevice
+{
+ friend struct Device;
+
+ private:
+
+ inline hb_position_t get_x_delta (hb_font_t *font) const
+ { return get_delta (font->x_ppem, font->x_scale); }
+
+ inline hb_position_t get_y_delta (hb_font_t *font) const
+ { return get_delta (font->y_ppem, font->y_scale); }
+
+ inline unsigned int get_size (void) const
+ {
+ unsigned int f = deltaFormat;
+ 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
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
+ }
+
+ private:
+
+ inline int get_delta (unsigned int ppem, int scale) const
+ {
+ if (!ppem) return 0;
+
+ int pixels = get_delta_pixels (ppem);
+
+ if (!pixels) return 0;
+
+ return (int) (pixels * (int64_t) scale / ppem);
+ }
+ inline int get_delta_pixels (unsigned int ppem_size) const
+ {
+ unsigned int f = deltaFormat;
+ if (unlikely (f < 1 || f > 3))
+ return 0;
+
+ if (ppem_size < startSize || ppem_size > endSize)
+ return 0;
+
+ unsigned int s = ppem_size - startSize;
+
+ unsigned int byte = deltaValue[s >> (4 - f)];
+ unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
+ unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
+
+ int delta = bits & mask;
+
+ if ((unsigned int) delta >= ((mask + 1) >> 1))
+ delta -= mask + 1;
+
+ return delta;
+ }
+
+ protected:
+ 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
+ */
+ UINT16 deltaValue[VAR]; /* Array of compressed data */
+ public:
+ DEFINE_SIZE_ARRAY (6, deltaValue);
+};
+
+struct VariationDevice
+{
+ friend struct Device;
+
+ private:
+
+ inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const
+ { return font->em_scalef_x (get_delta (font, store)); }
+
+ inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const
+ { return font->em_scalef_y (get_delta (font, store)); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ private:
+
+ inline float get_delta (hb_font_t *font, const VariationStore &store) const
+ {
+ return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords);
+ }
+
+ protected:
+ UINT16 outerIndex;
+ UINT16 innerIndex;
+ UINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct DeviceHeader
+{
+ protected:
+ UINT16 reserved1;
+ UINT16 reserved2;
+ public:
+ UINT16 format; /* Format identifier */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct Device
+{
+ inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
+ {
+ switch (u.b.format)
+ {
+ case 1: case 2: case 3:
+ return u.hinting.get_x_delta (font);
+ case 0x8000:
+ return u.variation.get_x_delta (font, store);
+ default:
+ return 0;
+ }
+ }
+ inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
+ {
+ switch (u.b.format)
+ {
+ case 1: case 2: case 3:
+ return u.hinting.get_y_delta (font);
+ case 0x8000:
+ return u.variation.get_y_delta (font, store);
+ default:
+ return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.b.format.sanitize (c)) return_trace (false);
+ switch (u.b.format) {
+ case 1: case 2: case 3:
+ return_trace (u.hinting.sanitize (c));
+ case 0x8000:
+ return_trace (u.variation.sanitize (c));
+ default:
+ return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ DeviceHeader b;
+ HintingDevice hinting;
+ VariationDevice variation;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (6, b);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
deleted file mode 100644
index 52b7dc254bb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
+++ /dev/null
@@ -1,3715 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_LAYOUT_COMMON_HH
-#define HB_OT_LAYOUT_COMMON_HH
-
-#include "hb.hh"
-#include "hb-ot-layout.hh"
-#include "hb-open-type.hh"
-#include "hb-set.hh"
-#include "hb-bimap.hh"
-
-#include "OT/Layout/Common/Coverage.hh"
-#include "OT/Layout/types.hh"
-
-// TODO(garretrieger): cleanup these after migration.
-using OT::Layout::Common::Coverage;
-using OT::Layout::Common::RangeRecord;
-using OT::Layout::SmallTypes;
-using OT::Layout::MediumTypes;
-
-
-namespace OT {
-
-template<typename Iterator>
-static inline bool ClassDef_serialize (hb_serialize_context_t *c,
- Iterator it);
-
-static bool ClassDef_remap_and_serialize (
- hb_serialize_context_t *c,
- const hb_set_t &klasses,
- bool use_class_zero,
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
- hb_map_t *klass_map /*IN/OUT*/);
-
-struct hb_collect_feature_substitutes_with_var_context_t
-{
- const hb_map_t *axes_index_tag_map;
- const hb_hashmap_t<hb_tag_t, int> *axes_location;
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
- hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
-
- // not stored in subset_plan
- hb_set_t *feature_indices;
- bool apply;
- unsigned cur_record_idx;
- hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
-};
-
-struct hb_prune_langsys_context_t
-{
- hb_prune_langsys_context_t (const void *table_,
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
- const hb_map_t *duplicate_feature_map_,
- hb_set_t *new_collected_feature_indexes_)
- :table (table_),
- script_langsys_map (script_langsys_map_),
- duplicate_feature_map (duplicate_feature_map_),
- new_feature_indexes (new_collected_feature_indexes_),
- script_count (0),langsys_feature_count (0) {}
-
- bool visitScript ()
- { return script_count++ < HB_MAX_SCRIPTS; }
-
- bool visitLangsys (unsigned feature_count)
- {
- langsys_feature_count += feature_count;
- return langsys_feature_count < HB_MAX_LANGSYS_FEATURE_COUNT;
- }
-
- public:
- const void *table;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
- const hb_map_t *duplicate_feature_map;
- hb_set_t *new_feature_indexes;
-
- private:
- unsigned script_count;
- unsigned langsys_feature_count;
-};
-
-struct hb_subset_layout_context_t :
- hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET>
-{
- const char *get_name () { return "SUBSET_LAYOUT"; }
- static return_t default_return_value () { return hb_empty_t (); }
-
- bool visitScript ()
- {
- return script_count++ < HB_MAX_SCRIPTS;
- }
-
- bool visitLangSys ()
- {
- return langsys_count++ < HB_MAX_LANGSYS;
- }
-
- bool visitFeatureIndex (int count)
- {
- feature_index_count += count;
- return feature_index_count < HB_MAX_FEATURE_INDICES;
- }
-
- bool visitLookupIndex()
- {
- lookup_index_count++;
- return lookup_index_count < HB_MAX_LOOKUP_VISIT_COUNT;
- }
-
- hb_subset_context_t *subset_context;
- const hb_tag_t table_tag;
- const hb_map_t *lookup_index_map;
- const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
- const hb_map_t *feature_index_map;
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map;
-
- unsigned cur_script_index;
- unsigned cur_feature_var_record_idx;
-
- hb_subset_layout_context_t (hb_subset_context_t *c_,
- hb_tag_t tag_) :
- subset_context (c_),
- table_tag (tag_),
- cur_script_index (0xFFFFu),
- cur_feature_var_record_idx (0u),
- script_count (0),
- langsys_count (0),
- feature_index_count (0),
- lookup_index_count (0)
- {
- if (tag_ == HB_OT_TAG_GSUB)
- {
- lookup_index_map = &c_->plan->gsub_lookups;
- script_langsys_map = &c_->plan->gsub_langsys;
- feature_index_map = &c_->plan->gsub_features;
- feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map;
- feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map;
- }
- else
- {
- lookup_index_map = &c_->plan->gpos_lookups;
- script_langsys_map = &c_->plan->gpos_langsys;
- feature_index_map = &c_->plan->gpos_features;
- feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map;
- feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map;
- }
- }
-
- private:
- unsigned script_count;
- unsigned langsys_count;
- unsigned feature_index_count;
- unsigned lookup_index_count;
-};
-
-struct VariationStore;
-struct hb_collect_variation_indices_context_t :
- hb_dispatch_context_t<hb_collect_variation_indices_context_t>
-{
- template <typename T>
- return_t dispatch (const T &obj) { obj.collect_variation_indices (this); return hb_empty_t (); }
- static return_t default_return_value () { return hb_empty_t (); }
-
- hb_set_t *layout_variation_indices;
- hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map;
- hb_font_t *font;
- const VariationStore *var_store;
- const hb_set_t *glyph_set;
- const hb_map_t *gpos_lookups;
- float *store_cache;
-
- hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
- hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_,
- hb_font_t *font_,
- const VariationStore *var_store_,
- const hb_set_t *glyph_set_,
- const hb_map_t *gpos_lookups_,
- float *store_cache_) :
- layout_variation_indices (layout_variation_indices_),
- varidx_delta_map (varidx_delta_map_),
- font (font_),
- var_store (var_store_),
- glyph_set (glyph_set_),
- gpos_lookups (gpos_lookups_),
- store_cache (store_cache_) {}
-};
-
-template<typename OutputArray>
-struct subset_offset_array_t
-{
- subset_offset_array_t (hb_subset_context_t *subset_context_,
- OutputArray& out_,
- const void *base_) : subset_context (subset_context_),
- out (out_), base (base_) {}
-
- template <typename T>
- bool operator () (T&& offset)
- {
- auto snap = subset_context->serializer->snapshot ();
- auto *o = out.serialize_append (subset_context->serializer);
- if (unlikely (!o)) return false;
- bool ret = o->serialize_subset (subset_context, offset, base);
- if (!ret)
- {
- out.pop ();
- subset_context->serializer->revert (snap);
- }
- return ret;
- }
-
- private:
- hb_subset_context_t *subset_context;
- OutputArray &out;
- const void *base;
-};
-
-
-template<typename OutputArray, typename Arg>
-struct subset_offset_array_arg_t
-{
- subset_offset_array_arg_t (hb_subset_context_t *subset_context_,
- OutputArray& out_,
- const void *base_,
- Arg &&arg_) : subset_context (subset_context_), out (out_),
- base (base_), arg (arg_) {}
-
- template <typename T>
- bool operator () (T&& offset)
- {
- auto snap = subset_context->serializer->snapshot ();
- auto *o = out.serialize_append (subset_context->serializer);
- if (unlikely (!o)) return false;
- bool ret = o->serialize_subset (subset_context, offset, base, arg);
- if (!ret)
- {
- out.pop ();
- subset_context->serializer->revert (snap);
- }
- return ret;
- }
-
- private:
- hb_subset_context_t *subset_context;
- OutputArray &out;
- const void *base;
- Arg &&arg;
-};
-
-/*
- * Helper to subset an array of offsets. Subsets the thing pointed to by each offset
- * and discards the offset in the array if the subset operation results in an empty
- * thing.
- */
-struct
-{
- template<typename OutputArray>
- subset_offset_array_t<OutputArray>
- operator () (hb_subset_context_t *subset_context, OutputArray& out,
- const void *base) const
- { return subset_offset_array_t<OutputArray> (subset_context, out, base); }
-
- /* Variant with one extra argument passed to serialize_subset */
- template<typename OutputArray, typename Arg>
- subset_offset_array_arg_t<OutputArray, Arg>
- operator () (hb_subset_context_t *subset_context, OutputArray& out,
- const void *base, Arg &&arg) const
- { return subset_offset_array_arg_t<OutputArray, Arg> (subset_context, out, base, arg); }
-}
-HB_FUNCOBJ (subset_offset_array);
-
-template<typename OutputArray>
-struct subset_record_array_t
-{
- subset_record_array_t (hb_subset_layout_context_t *c_, OutputArray* out_,
- const void *base_) : subset_layout_context (c_),
- out (out_), base (base_) {}
-
- template <typename T>
- void
- operator () (T&& record)
- {
- auto snap = subset_layout_context->subset_context->serializer->snapshot ();
- bool ret = record.subset (subset_layout_context, base);
- if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
- else out->len++;
- }
-
- private:
- hb_subset_layout_context_t *subset_layout_context;
- OutputArray *out;
- const void *base;
-};
-
-template<typename OutputArray, typename Arg>
-struct subset_record_array_arg_t
-{
- subset_record_array_arg_t (hb_subset_layout_context_t *c_, OutputArray* out_,
- const void *base_,
- Arg &&arg_) : subset_layout_context (c_),
- out (out_), base (base_), arg (arg_) {}
-
- template <typename T>
- void
- operator () (T&& record)
- {
- auto snap = subset_layout_context->subset_context->serializer->snapshot ();
- bool ret = record.subset (subset_layout_context, base, arg);
- if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
- else out->len++;
- }
-
- private:
- hb_subset_layout_context_t *subset_layout_context;
- OutputArray *out;
- const void *base;
- Arg &&arg;
-};
-
-/*
- * Helper to subset a RecordList/record array. Subsets each Record in the array and
- * discards the record if the subset operation returns false.
- */
-struct
-{
- template<typename OutputArray>
- subset_record_array_t<OutputArray>
- operator () (hb_subset_layout_context_t *c, OutputArray* out,
- const void *base) const
- { return subset_record_array_t<OutputArray> (c, out, base); }
-
- /* Variant with one extra argument passed to subset */
- template<typename OutputArray, typename Arg>
- subset_record_array_arg_t<OutputArray, Arg>
- operator () (hb_subset_layout_context_t *c, OutputArray* out,
- const void *base, Arg &&arg) const
- { return subset_record_array_arg_t<OutputArray, Arg> (c, out, base, arg); }
-}
-HB_FUNCOBJ (subset_record_array);
-
-
-template<typename OutputArray>
-struct serialize_math_record_array_t
-{
- serialize_math_record_array_t (hb_serialize_context_t *serialize_context_,
- OutputArray& out_,
- const void *base_) : serialize_context (serialize_context_),
- out (out_), base (base_) {}
-
- template <typename T>
- bool operator () (T&& record)
- {
- if (!serialize_context->copy (record, base)) return false;
- out.len++;
- return true;
- }
-
- private:
- hb_serialize_context_t *serialize_context;
- OutputArray &out;
- const void *base;
-};
-
-/*
- * Helper to serialize an array of MATH records.
- */
-struct
-{
- template<typename OutputArray>
- serialize_math_record_array_t<OutputArray>
- operator () (hb_serialize_context_t *serialize_context, OutputArray& out,
- const void *base) const
- { return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); }
-
-}
-HB_FUNCOBJ (serialize_math_record_array);
-
-/*
- *
- * OpenType Layout Common Table Formats
- *
- */
-
-
-/*
- * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
- */
-
-struct IndexArray : Array16Of<Index>
-{
- bool intersects (const hb_map_t *indexes) const
- { return hb_any (*this, indexes); }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- hb_subset_layout_context_t *l,
- Iterator it)
- {
- if (!it) return;
- if (unlikely (!c->extend_min ((*this)))) return;
-
- for (const auto _ : it)
- {
- if (!l->visitLookupIndex()) break;
-
- Index i;
- i = _;
- c->copy (i);
- this->len++;
- }
- }
-
- unsigned int get_indexes (unsigned int start_offset,
- unsigned int *_count /* IN/OUT */,
- unsigned int *_indexes /* OUT */) const
- {
- if (_count)
- {
- + this->as_array ().sub_array (start_offset, _count)
- | hb_sink (hb_array (_indexes, *_count))
- ;
- }
- return this->len;
- }
-
- void add_indexes_to (hb_set_t* output /* OUT */) const
- {
- output->add_array (as_array ());
- }
-};
-
-
-/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
-struct FeatureParamsSize
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this))) return_trace (false);
-
- /* This subtable has some "history", if you will. Some earlier versions of
- * Adobe tools calculated the offset of the FeatureParams subtable from the
- * beginning of the FeatureList table! Now, that is dealt with in the
- * Feature implementation. But we still need to be able to tell junk from
- * real data. Note: We don't check that the nameID actually exists.
- *
- * Read Roberts wrote on 9/15/06 on [email protected] :
- *
- * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
- * coming out soon, and that the makeotf program will build a font with a
- * 'size' feature that is correct by the specification.
- *
- * The specification for this feature tag is in the "OpenType Layout Tag
- * Registry". You can see a copy of this at:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size
- *
- * Here is one set of rules to determine if the 'size' feature is built
- * correctly, or as by the older versions of MakeOTF. You may be able to do
- * better.
- *
- * Assume that the offset to the size feature is according to specification,
- * and make the following value checks. If it fails, assume the size
- * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
- * If this fails, reject the 'size' feature. The older makeOTF's calculated the
- * offset from the beginning of the FeatureList table, rather than from the
- * beginning of the 'size' Feature table.
- *
- * If "design size" == 0:
- * fails check
- *
- * Else if ("subfamily identifier" == 0 and
- * "range start" == 0 and
- * "range end" == 0 and
- * "range start" == 0 and
- * "menu name ID" == 0)
- * passes check: this is the format used when there is a design size
- * specified, but there is no recommended size range.
- *
- * Else if ("design size" < "range start" or
- * "design size" > "range end" or
- * "range end" <= "range start" or
- * "menu name ID" < 256 or
- * "menu name ID" > 32767 or
- * menu name ID is not a name ID which is actually in the name table)
- * fails test
- * Else
- * passes test.
- */
-
- if (!designSize)
- return_trace (false);
- else if (subfamilyID == 0 &&
- subfamilyNameID == 0 &&
- rangeStart == 0 &&
- rangeEnd == 0)
- return_trace (true);
- else if (designSize < rangeStart ||
- designSize > rangeEnd ||
- subfamilyNameID < 256 ||
- subfamilyNameID > 32767)
- return_trace (false);
- else
- return_trace (true);
- }
-
- void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
- { nameids_to_retain->add (subfamilyNameID); }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- return_trace ((bool) c->serializer->embed (*this));
- }
-
- HBUINT16 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. */
- HBUINT16 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
- * differ only by size range shall have the
- * same subfamily value, and no fonts which
- * differ in weight or style shall have the
- * same subfamily value. If this value is
- * zero, the remaining fields in the array
- * will be ignored. */
- NameID 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
- * contain English-language strings encoded
- * in Windows Unicode and Macintosh Roman,
- * and may contain additional strings
- * localized to other scripts and languages.
- * Each of these strings is the name an
- * application should use, in combination
- * with the family name, to represent the
- * subfamily in a menu. Applications will
- * choose the appropriate version based on
- * their selection criteria. */
- HBUINT16 rangeStart; /* Large end of the recommended usage range
- * (inclusive), stored in 720/inch units
- * (decipoints). */
- HBUINT16 rangeEnd; /* Small end of the recommended usage range
- (exclusive), stored in 720/inch units
- * (decipoints). */
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#ssxx */
-struct FeatureParamsStylisticSet
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- /* Right now minorVersion is at zero. Which means, any table supports
- * the uiNameID field. */
- return_trace (c->check_struct (this));
- }
-
- void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
- { nameids_to_retain->add (uiNameID); }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- return_trace ((bool) c->serializer->embed (*this));
- }
-
- HBUINT16 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. */
-
- NameID 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
- * sampleTextNameId are expected to be in the
- * font-specific name ID range (256-32767),
- * though that is not a requirement in this
- * Feature Parameters specification. The
- * user-interface label for the feature can
- * be provided in multiple languages. An
- * English string should be included as a
- * fallback. The string should be kept to a
- * minimal length to fit comfortably with
- * different application interfaces. */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99 */
-struct FeatureParamsCharacterVariants
-{
- unsigned
- get_characters (unsigned start_offset, unsigned *char_count, hb_codepoint_t *chars) const
- {
- if (char_count)
- {
- + characters.as_array ().sub_array (start_offset, char_count)
- | hb_sink (hb_array (chars, *char_count))
- ;
- }
- return characters.len;
- }
-
- unsigned get_size () const
- { return min_size + characters.len * HBUINT24::static_size; }
-
- void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
- {
- if (featUILableNameID) nameids_to_retain->add (featUILableNameID);
- if (featUITooltipTextNameID) nameids_to_retain->add (featUITooltipTextNameID);
- if (sampleTextNameID) nameids_to_retain->add (sampleTextNameID);
-
- if (!firstParamUILabelNameID || !numNamedParameters || numNamedParameters >= 0x7FFF)
- return;
-
- unsigned last_name_id = (unsigned) firstParamUILabelNameID + (unsigned) numNamedParameters - 1;
- if (last_name_id >= 256 && last_name_id <= 32767)
- nameids_to_retain->add_range (firstParamUILabelNameID, last_name_id);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- return_trace ((bool) c->serializer->embed (*this));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- characters.sanitize (c));
- }
-
- HBUINT16 format; /* Format number is set to 0. */
- NameID 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.) */
- NameID 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
- * nullptr.) */
- NameID sampleTextNameID; /* The ‘name’ table name ID that
- * specifies sample text that
- * illustrates the effect of this
- * feature. (May be NULL.) */
- HBUINT16 numNamedParameters; /* Number of named parameters. (May
- * be zero.) */
- NameID firstParamUILabelNameID;/* The first ‘name’ table name ID
- * used to specify strings for
- * user-interface labels for the
- * feature parameters. (Must be zero
- * if numParameters is zero.) */
- Array16Of<HBUINT24>
- characters; /* Array of the Unicode Scalar Value
- * of the characters for which this
- * feature provides glyph variants.
- * (May be zero.) */
- public:
- DEFINE_SIZE_ARRAY (14, characters);
-};
-
-struct FeatureParams
-{
- bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
- {
-#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
- return true;
-#endif
- TRACE_SANITIZE (this);
- if (tag == HB_TAG ('s','i','z','e'))
- return_trace (u.size.sanitize (c));
- if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
- return_trace (u.stylisticSet.sanitize (c));
- if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
- return_trace (u.characterVariants.sanitize (c));
- return_trace (true);
- }
-
- void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
- {
-#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
- return;
-#endif
- if (tag == HB_TAG ('s','i','z','e'))
- return (u.size.collect_name_ids (nameids_to_retain));
- if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
- return (u.stylisticSet.collect_name_ids (nameids_to_retain));
- if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
- return (u.characterVariants.collect_name_ids (nameids_to_retain));
- }
-
- bool subset (hb_subset_context_t *c, const Tag* tag) const
- {
- TRACE_SUBSET (this);
- if (!tag) return_trace (false);
- if (*tag == HB_TAG ('s','i','z','e'))
- return_trace (u.size.subset (c));
- if ((*tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
- return_trace (u.stylisticSet.subset (c));
- if ((*tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
- return_trace (u.characterVariants.subset (c));
- return_trace (false);
- }
-
-#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
- const FeatureParamsSize& get_size_params (hb_tag_t tag) const
- {
- if (tag == HB_TAG ('s','i','z','e'))
- return u.size;
- return Null (FeatureParamsSize);
- }
- const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
- {
- if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
- return u.stylisticSet;
- return Null (FeatureParamsStylisticSet);
- }
- const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
- {
- if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
- return u.characterVariants;
- return Null (FeatureParamsCharacterVariants);
- }
-#endif
-
- private:
- union {
- FeatureParamsSize size;
- FeatureParamsStylisticSet stylisticSet;
- FeatureParamsCharacterVariants characterVariants;
- } u;
- public:
- DEFINE_SIZE_MIN (0);
-};
-
-struct Record_sanitize_closure_t {
- hb_tag_t tag;
- const void *list_base;
-};
-
-struct Feature
-{
- unsigned int get_lookup_count () const
- { return lookupIndex.len; }
- hb_tag_t get_lookup_index (unsigned int i) const
- { return lookupIndex[i]; }
- unsigned int get_lookup_indexes (unsigned int start_index,
- unsigned int *lookup_count /* IN/OUT */,
- unsigned int *lookup_tags /* OUT */) const
- { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
- void add_lookup_indexes_to (hb_set_t *lookup_indexes) const
- { lookupIndex.add_indexes_to (lookup_indexes); }
-
- const FeatureParams &get_feature_params () const
- { return this+featureParams; }
-
- bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
- { return lookupIndex.intersects (lookup_indexes); }
-
- void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
- {
- if (featureParams)
- get_feature_params ().collect_name_ids (tag, nameids_to_retain);
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l,
- const Tag *tag = nullptr) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- out->featureParams.serialize_subset (c, featureParams, this, tag);
-
- auto it =
- + hb_iter (lookupIndex)
- | hb_filter (l->lookup_index_map)
- | hb_map (l->lookup_index_map)
- ;
-
- out->lookupIndex.serialize (c->serializer, l, it);
- // The decision to keep or drop this feature is already made before we get here
- // so always retain it.
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c,
- const Record_sanitize_closure_t *closure = nullptr) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
- return_trace (false);
-
- /* Some earlier versions of Adobe tools calculated the offset of the
- * FeatureParams subtable from the beginning of the FeatureList table!
- *
- * If sanitizing "failed" for the FeatureParams subtable, try it with the
- * alternative location. We would know sanitize "failed" if old value
- * of the offset was non-zero, but it's zeroed now.
- *
- * Only do this for the 'size' feature, since at the time of the faulty
- * Adobe tools, only the 'size' feature had FeatureParams defined.
- */
-
- if (likely (featureParams.is_null ()))
- return_trace (true);
-
- unsigned int orig_offset = featureParams;
- if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
- return_trace (false);
-
- if (featureParams == 0 && closure &&
- closure->tag == HB_TAG ('s','i','z','e') &&
- closure->list_base && closure->list_base < this)
- {
- unsigned int new_offset_int = orig_offset -
- (((char *) this) - ((char *) closure->list_base));
-
- Offset16To<FeatureParams> new_offset;
- /* Check that it would not overflow. */
- new_offset = new_offset_int;
- if (new_offset == new_offset_int &&
- c->try_set (&featureParams, new_offset_int) &&
- !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
- return_trace (false);
- }
-
- return_trace (true);
- }
-
- Offset16To<FeatureParams>
- featureParams; /* Offset to Feature Parameters table (if one
- * has been defined for the feature), relative
- * to the beginning of the Feature Table; = Null
- * if not required */
- IndexArray lookupIndex; /* Array of LookupList indices */
- public:
- DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex);
-};
-
-template <typename Type>
-struct Record
-{
- int cmp (hb_tag_t a) const { return tag.cmp (a); }
-
- bool subset (hb_subset_layout_context_t *c, const void *base, const void *f_sub = nullptr) const
- {
- TRACE_SUBSET (this);
- auto *out = c->subset_context->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (!f_sub)
- return_trace (out->offset.serialize_subset (c->subset_context, offset, base, c, &tag));
-
- const Feature& f = *reinterpret_cast<const Feature *> (f_sub);
- auto *s = c->subset_context->serializer;
- s->push ();
-
- out->offset = 0;
- bool ret = f.subset (c->subset_context, c, &tag);
- if (ret)
- s->add_link (out->offset, s->pop_pack ());
- else
- s->pop_discard ();
-
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- const Record_sanitize_closure_t closure = {tag, base};
- return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
- }
-
- Tag tag; /* 4-byte Tag identifier */
- Offset16To<Type>
- offset; /* Offset from beginning of object holding
- * the Record */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-template <typename Type>
-struct RecordArrayOf : SortedArray16Of<Record<Type>>
-{
- const Offset16To<Type>& get_offset (unsigned int i) const
- { return (*this)[i].offset; }
- Offset16To<Type>& get_offset (unsigned int i)
- { return (*this)[i].offset; }
- const Tag& get_tag (unsigned int i) const
- { return (*this)[i].tag; }
- unsigned int get_tags (unsigned int start_offset,
- unsigned int *record_count /* IN/OUT */,
- hb_tag_t *record_tags /* OUT */) const
- {
- if (record_count)
- {
- + this->as_array ().sub_array (start_offset, record_count)
- | hb_map (&Record<Type>::tag)
- | hb_sink (hb_array (record_tags, *record_count))
- ;
- }
- return this->len;
- }
- bool find_index (hb_tag_t tag, unsigned int *index) const
- {
- return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
- }
-};
-
-template <typename Type>
-struct RecordListOf : RecordArrayOf<Type>
-{
- const Type& operator [] (unsigned int i) const
- { return this+this->get_offset (i); }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- + this->iter ()
- | hb_apply (subset_record_array (l, out, this))
- ;
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (RecordArrayOf<Type>::sanitize (c, this));
- }
-};
-
-struct RecordListOfFeature : RecordListOf<Feature>
-{
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- + hb_enumerate (*this)
- | hb_filter (l->feature_index_map, hb_first)
- | hb_apply ([l, out, this] (const hb_pair_t<unsigned, const Record<Feature>&>& _)
- {
- const Feature *f_sub = nullptr;
- const Feature **f = nullptr;
- if (l->feature_substitutes_map->has (_.first, &f))
- f_sub = *f;
-
- subset_record_array (l, out, this, f_sub) (_.second);
- })
- ;
-
- return_trace (true);
- }
-};
-
-typedef RecordListOf<Feature> FeatureList;
-
-
-struct LangSys
-{
- unsigned int get_feature_count () const
- { return featureIndex.len; }
- hb_tag_t get_feature_index (unsigned int i) const
- { return featureIndex[i]; }
- unsigned int get_feature_indexes (unsigned int start_offset,
- unsigned int *feature_count /* IN/OUT */,
- unsigned int *feature_indexes /* OUT */) const
- { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
- void add_feature_indexes_to (hb_set_t *feature_indexes) const
- { featureIndex.add_indexes_to (feature_indexes); }
-
- bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; }
- unsigned int get_required_feature_index () const
- {
- if (reqFeatureIndex == 0xFFFFu)
- return Index::NOT_FOUND_INDEX;
- return reqFeatureIndex;
- }
-
- LangSys* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed (*this));
- }
-
- bool compare (const LangSys& o, const hb_map_t *feature_index_map) const
- {
- if (reqFeatureIndex != o.reqFeatureIndex)
- return false;
-
- auto iter =
- + hb_iter (featureIndex)
- | hb_filter (feature_index_map)
- | hb_map (feature_index_map)
- ;
-
- auto o_iter =
- + hb_iter (o.featureIndex)
- | hb_filter (feature_index_map)
- | hb_map (feature_index_map)
- ;
-
- for (; iter && o_iter; iter++, o_iter++)
- {
- unsigned a = *iter;
- unsigned b = *o_iter;
- if (a != b) return false;
- }
-
- if (iter || o_iter) return false;
-
- return true;
- }
-
- void collect_features (hb_prune_langsys_context_t *c) const
- {
- if (!has_required_feature () && !get_feature_count ()) return;
- if (has_required_feature () &&
- c->duplicate_feature_map->has (reqFeatureIndex))
- c->new_feature_indexes->add (get_required_feature_index ());
-
- + hb_iter (featureIndex)
- | hb_filter (c->duplicate_feature_map)
- | hb_sink (c->new_feature_indexes)
- ;
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l,
- const Tag *tag = nullptr) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- const uint32_t *v;
- out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
-
- if (!l->visitFeatureIndex (featureIndex.len))
- return_trace (false);
-
- auto it =
- + hb_iter (featureIndex)
- | hb_filter (l->feature_index_map)
- | hb_map (l->feature_index_map)
- ;
-
- bool ret = bool (it);
- out->featureIndex.serialize (c->serializer, l, it);
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c,
- const Record_sanitize_closure_t * = nullptr) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && featureIndex.sanitize (c));
- }
-
- Offset16 lookupOrderZ; /* = Null (reserved for an offset to a
- * reordering table) */
- HBUINT16 reqFeatureIndex;/* Index of a feature required for this
- * language system--if no required features
- * = 0xFFFFu */
- IndexArray featureIndex; /* Array of indices into the FeatureList */
- public:
- DEFINE_SIZE_ARRAY_SIZED (6, featureIndex);
-};
-DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys);
-
-struct Script
-{
- unsigned int get_lang_sys_count () const
- { return langSys.len; }
- const Tag& get_lang_sys_tag (unsigned int i) const
- { return langSys.get_tag (i); }
- unsigned int get_lang_sys_tags (unsigned int start_offset,
- unsigned int *lang_sys_count /* IN/OUT */,
- hb_tag_t *lang_sys_tags /* OUT */) const
- { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
- const LangSys& get_lang_sys (unsigned int i) const
- {
- if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
- return this+langSys[i].offset;
- }
- bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
- { return langSys.find_index (tag, index); }
-
- bool has_default_lang_sys () const { return defaultLangSys != 0; }
- const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
-
- void prune_langsys (hb_prune_langsys_context_t *c,
- unsigned script_index) const
- {
- if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
- if (!c->visitScript ()) return;
-
- if (!c->script_langsys_map->has (script_index))
- {
- if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
- return;
- }
-
- if (has_default_lang_sys ())
- {
- //only collect features from non-redundant langsys
- const LangSys& d = get_default_lang_sys ();
- if (c->visitLangsys (d.get_feature_count ())) {
- d.collect_features (c);
- }
-
- for (auto _ : + hb_enumerate (langSys))
- {
- const LangSys& l = this+_.second.offset;
- if (!c->visitLangsys (l.get_feature_count ())) continue;
- if (l.compare (d, c->duplicate_feature_map)) continue;
-
- l.collect_features (c);
- c->script_langsys_map->get (script_index)->add (_.first);
- }
- }
- else
- {
- for (auto _ : + hb_enumerate (langSys))
- {
- const LangSys& l = this+_.second.offset;
- if (!c->visitLangsys (l.get_feature_count ())) continue;
- l.collect_features (c);
- c->script_langsys_map->get (script_index)->add (_.first);
- }
- }
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l,
- const Tag *tag) const
- {
- TRACE_SUBSET (this);
- if (!l->visitScript ()) return_trace (false);
- if (tag && !c->plan->layout_scripts.has (*tag))
- return false;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- bool defaultLang = false;
- if (has_default_lang_sys ())
- {
- c->serializer->push ();
- const LangSys& ls = this+defaultLangSys;
- bool ret = ls.subset (c, l);
- if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T'))
- {
- c->serializer->pop_discard ();
- out->defaultLangSys = 0;
- }
- else
- {
- c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ());
- defaultLang = true;
- }
- }
-
- const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
- if (active_langsys)
- {
- + hb_enumerate (langSys)
- | hb_filter (active_langsys, hb_first)
- | hb_map (hb_second)
- | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
- | hb_apply (subset_record_array (l, &(out->langSys), this))
- ;
- }
-
- return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB);
- }
-
- bool sanitize (hb_sanitize_context_t *c,
- const Record_sanitize_closure_t * = nullptr) const
- {
- TRACE_SANITIZE (this);
- return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
- }
-
- protected:
- Offset16To<LangSys>
- defaultLangSys; /* Offset to DefaultLangSys table--from
- * beginning of Script table--may be Null */
- RecordArrayOf<LangSys>
- langSys; /* Array of LangSysRecords--listed
- * alphabetically by LangSysTag */
- public:
- DEFINE_SIZE_ARRAY_SIZED (4, langSys);
-};
-
-struct RecordListOfScript : RecordListOf<Script>
-{
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- for (auto _ : + hb_enumerate (*this))
- {
- auto snap = c->serializer->snapshot ();
- l->cur_script_index = _.first;
- bool ret = _.second.subset (l, this);
- if (!ret) c->serializer->revert (snap);
- else out->len++;
- }
-
- return_trace (true);
- }
-};
-
-typedef RecordListOfScript ScriptList;
-
-
-
-struct LookupFlag : HBUINT16
-{
- enum Flags {
- RightToLeft = 0x0001u,
- IgnoreBaseGlyphs = 0x0002u,
- IgnoreLigatures = 0x0004u,
- IgnoreMarks = 0x0008u,
- IgnoreFlags = 0x000Eu,
- UseMarkFilteringSet = 0x0010u,
- Reserved = 0x00E0u,
- MarkAttachmentType = 0xFF00u
- };
- public:
- DEFINE_SIZE_STATIC (2);
-};
-
-} /* namespace OT */
-/* This has to be outside the namespace. */
-HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags);
-namespace OT {
-
-struct Lookup
-{
- unsigned int get_subtable_count () const { return subTable.len; }
-
- template <typename TSubTable>
- const Array16OfOffset16To<TSubTable>& get_subtables () const
- { return reinterpret_cast<const Array16OfOffset16To<TSubTable> &> (subTable); }
- template <typename TSubTable>
- Array16OfOffset16To<TSubTable>& get_subtables ()
- { return reinterpret_cast<Array16OfOffset16To<TSubTable> &> (subTable); }
-
- template <typename TSubTable>
- const TSubTable& get_subtable (unsigned int i) const
- { return this+get_subtables<TSubTable> ()[i]; }
- template <typename TSubTable>
- TSubTable& get_subtable (unsigned int i)
- { return this+get_subtables<TSubTable> ()[i]; }
-
- unsigned int get_size () const
- {
- const HBUINT16 &markFilteringSet = StructAfter<const HBUINT16> (subTable);
- if (lookupFlag & LookupFlag::UseMarkFilteringSet)
- return (const char *) &StructAfter<const char> (markFilteringSet) - (const char *) this;
- return (const char *) &markFilteringSet - (const char *) this;
- }
-
- unsigned int get_type () const { return lookupType; }
-
- /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
- * higher 16-bit is mark-filtering-set if the lookup uses one.
- * Not to be confused with glyph_props which is very similar. */
- uint32_t get_props () const
- {
- unsigned int flag = lookupFlag;
- if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
- {
- const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
- flag += (markFilteringSet << 16);
- }
- return flag;
- }
-
- template <typename TSubTable, typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- unsigned int lookup_type = get_type ();
- TRACE_DISPATCH (this, lookup_type);
- unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++) {
- typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
- if (c->stop_sublookup_iteration (r))
- return_trace (r);
- }
- return_trace (c->default_return_value ());
- }
-
- bool serialize (hb_serialize_context_t *c,
- unsigned int lookup_type,
- uint32_t lookup_props,
- unsigned int num_subtables)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- lookupType = lookup_type;
- lookupFlag = lookup_props & 0xFFFFu;
- if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
- if (lookupFlag & LookupFlag::UseMarkFilteringSet)
- {
- if (unlikely (!c->extend (this))) return_trace (false);
- HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
- markFilteringSet = lookup_props >> 16;
- }
- return_trace (true);
- }
-
- template <typename TSubTable>
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
- out->lookupType = lookupType;
- out->lookupFlag = lookupFlag;
-
- const hb_set_t *glyphset = c->plan->glyphset_gsub ();
- unsigned int lookup_type = get_type ();
- + hb_iter (get_subtables <TSubTable> ())
- | hb_filter ([this, glyphset, lookup_type] (const Offset16To<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
- | hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, lookup_type))
- ;
-
- if (lookupFlag & LookupFlag::UseMarkFilteringSet)
- {
- if (unlikely (!c->serializer->extend (out))) return_trace (false);
- const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
- HBUINT16 &outMarkFilteringSet = StructAfter<HBUINT16> (out->subTable);
- outMarkFilteringSet = markFilteringSet;
- }
-
- // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup
- // indices being consistent with those computed during planning. So if an empty lookup is
- // discarded during the subset phase it will invalidate all subsequent lookup indices.
- // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning
- // phase, but it can happen in rare cases such as when during closure subtable is considered
- // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853)
- return_trace (true);
- }
-
- template <typename TSubTable>
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
-
- unsigned subtables = get_subtable_count ();
- if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
-
- if (lookupFlag & LookupFlag::UseMarkFilteringSet)
- {
- const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
- if (!markFilteringSet.sanitize (c)) return_trace (false);
- }
-
- if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
- return_trace (false);
-
- if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
- {
- /* The spec says all subtables of an Extension lookup should
- * have the same type, which shall not be the Extension type
- * itself (but we already checked for that).
- * This is specially important if one has a reverse type!
- *
- * We only do this if sanitizer edit_count is zero. Otherwise,
- * some of the subtables might have become insane after they
- * were sanity-checked by the edits of subsequent subtables.
- * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
- */
- unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
- for (unsigned int i = 1; i < subtables; i++)
- if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
- return_trace (false);
- }
- return_trace (true);
- }
-
- protected:
- HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */
- HBUINT16 lookupFlag; /* Lookup qualifiers */
- Array16Of<Offset16>
- subTable; /* Array of SubTables */
-/*HBUINT16 markFilteringSetX[HB_VAR_ARRAY];*//* Index (base 0) into GDEF mark glyph sets
- * structure. This field is only present if bit
- * UseMarkFilteringSet of lookup flags is set. */
- public:
- DEFINE_SIZE_ARRAY (6, subTable);
-};
-
-template <typename Types>
-using LookupList = List16OfOffsetTo<Lookup, typename Types::HBUINT>;
-
-template <typename TLookup, typename OffsetType>
-struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType>
-{
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- + hb_enumerate (*this)
- | hb_filter (l->lookup_index_map, hb_first)
- | hb_map (hb_second)
- | hb_apply (subset_offset_array (c, *out, this))
- ;
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (List16OfOffset16To<TLookup>::sanitize (c, this));
- }
-};
-
-
-/*
- * Coverage Table
- */
-
-
-static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c,
- const hb_set_t &klasses,
- bool use_class_zero,
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
- hb_map_t *klass_map /*IN/OUT*/)
-{
- if (!klass_map)
- return ClassDef_serialize (c, glyph_and_klass.iter ());
-
- /* any glyph not assigned a class value falls into Class zero (0),
- * if any glyph assigned to class 0, remapping must start with 0->0*/
- if (!use_class_zero)
- klass_map->set (0, 0);
-
- unsigned idx = klass_map->has (0) ? 1 : 0;
- for (const unsigned k: klasses)
- {
- if (klass_map->has (k)) continue;
- klass_map->set (k, idx);
- idx++;
- }
-
-
- for (unsigned i = 0; i < glyph_and_klass.length; i++)
- {
- hb_codepoint_t klass = glyph_and_klass[i].second;
- glyph_and_klass[i].second = klass_map->get (klass);
- }
-
- c->propagate_error (glyph_and_klass, klasses);
- return ClassDef_serialize (c, glyph_and_klass.iter ());
-}
-
-/*
- * Class Definition Table
- */
-
-template <typename Types>
-struct ClassDefFormat1_3
-{
- friend struct ClassDef;
-
- private:
- unsigned int get_class (hb_codepoint_t glyph_id) const
- {
- return classValue[(unsigned int) (glyph_id - startGlyph)];
- }
-
- unsigned get_population () const
- {
- return classValue.len;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- if (unlikely (!it))
- {
- classFormat = 1;
- startGlyph = 0;
- classValue.len = 0;
- return_trace (true);
- }
-
- hb_codepoint_t glyph_min = (*it).first;
- hb_codepoint_t glyph_max = + it
- | hb_map (hb_first)
- | hb_reduce (hb_max, 0u);
- unsigned glyph_count = glyph_max - glyph_min + 1;
-
- startGlyph = glyph_min;
- if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false);
- for (const hb_pair_t<hb_codepoint_t, uint32_t> gid_klass_pair : + it)
- {
- unsigned idx = gid_klass_pair.first - glyph_min;
- classValue[idx] = gid_klass_pair.second;
- }
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c,
- hb_map_t *klass_map = nullptr /*OUT*/,
- bool keep_empty_table = true,
- bool use_class_zero = true,
- const Coverage* glyph_filter = nullptr) const
- {
- TRACE_SUBSET (this);
- const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
-
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
- hb_set_t orig_klasses;
-
- hb_codepoint_t start = startGlyph;
- hb_codepoint_t end = start + classValue.len;
-
- for (const hb_codepoint_t gid : + hb_range (start, end))
- {
- hb_codepoint_t new_gid = glyph_map[gid];
- if (new_gid == HB_MAP_VALUE_INVALID) continue;
- if (glyph_filter && !glyph_filter->has(gid)) continue;
-
- unsigned klass = classValue[gid - start];
- if (!klass) continue;
-
- glyph_and_klass.push (hb_pair (new_gid, klass));
- orig_klasses.add (klass);
- }
-
- unsigned glyph_count = glyph_filter
- ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
- : glyph_map.get_population ();
- use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
- if (!ClassDef_remap_and_serialize (c->serializer,
- orig_klasses,
- use_class_zero,
- glyph_and_klass,
- klass_map))
- return_trace (false);
- return_trace (keep_empty_table || (bool) glyph_and_klass);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && classValue.sanitize (c));
- }
-
- unsigned cost () const { return 1; }
-
- template <typename set_t>
- bool collect_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>
- bool collect_class (set_t *glyphs, unsigned 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;
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- hb_codepoint_t start = startGlyph;
- hb_codepoint_t end = startGlyph + classValue.len;
- for (hb_codepoint_t iter = startGlyph - 1;
- glyphs->next (&iter) && iter < end;)
- if (classValue[iter - start]) return true;
- return false;
- }
- bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
- {
- unsigned int count = classValue.len;
- if (klass == 0)
- {
- /* Match if there's any glyph that is not listed! */
- hb_codepoint_t g = HB_SET_VALUE_INVALID;
- if (!glyphs->next (&g)) return false;
- if (g < startGlyph) return true;
- g = startGlyph + count - 1;
- if (glyphs->next (&g)) return true;
- /* Fall through. */
- }
- /* TODO Speed up, using set overlap first? */
- /* TODO(iter) Rewrite as dagger. */
- const HBUINT16 *arr = classValue.arrayZ;
- for (unsigned int i = 0; i < count; i++)
- if (arr[i] == klass && glyphs->has (startGlyph + i))
- return true;
- return false;
- }
-
- void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
- {
- unsigned count = classValue.len;
- if (klass == 0)
- {
- unsigned start_glyph = startGlyph;
- for (uint32_t g = HB_SET_VALUE_INVALID;
- glyphs->next (&g) && g < start_glyph;)
- intersect_glyphs->add (g);
-
- for (uint32_t g = startGlyph + count - 1;
- glyphs-> next (&g);)
- intersect_glyphs->add (g);
-
- return;
- }
-
- for (unsigned i = 0; i < count; i++)
- if (classValue[i] == klass && glyphs->has (startGlyph + i))
- intersect_glyphs->add (startGlyph + i);
-
-#if 0
- /* The following implementation is faster asymptotically, but slower
- * in practice. */
- unsigned start_glyph = startGlyph;
- unsigned end_glyph = start_glyph + count;
- for (unsigned g = startGlyph - 1;
- glyphs->next (&g) && g < end_glyph;)
- if (classValue.arrayZ[g - start_glyph] == klass)
- intersect_glyphs->add (g);
-#endif
- }
-
- void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
- {
- if (glyphs->is_empty ()) return;
- hb_codepoint_t end_glyph = startGlyph + classValue.len - 1;
- if (glyphs->get_min () < startGlyph ||
- glyphs->get_max () > end_glyph)
- intersect_classes->add (0);
-
- for (const auto& _ : + hb_enumerate (classValue))
- {
- hb_codepoint_t g = startGlyph + _.first;
- if (glyphs->has (g))
- intersect_classes->add (_.second);
- }
- }
-
- protected:
- HBUINT16 classFormat; /* Format identifier--format = 1 */
- typename Types::HBGlyphID
- startGlyph; /* First GlyphID of the classValueArray */
- typename Types::template ArrayOf<HBUINT16>
- classValue; /* Array of Class Values--one per GlyphID */
- public:
- DEFINE_SIZE_ARRAY (2 + 2 * Types::size, classValue);
-};
-
-template <typename Types>
-struct ClassDefFormat2_4
-{
- friend struct ClassDef;
-
- private:
- unsigned int get_class (hb_codepoint_t glyph_id) const
- {
- return rangeRecord.bsearch (glyph_id).value;
- }
-
- unsigned get_population () const
- {
- typename Types::large_int ret = 0;
- for (const auto &r : rangeRecord)
- ret += r.get_population ();
- return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c,
- Iterator it)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- if (unlikely (!it))
- {
- classFormat = 2;
- rangeRecord.len = 0;
- return_trace (true);
- }
-
- unsigned num_ranges = 1;
- hb_codepoint_t prev_gid = (*it).first;
- unsigned prev_klass = (*it).second;
-
- RangeRecord<Types> range_rec;
- range_rec.first = prev_gid;
- range_rec.last = prev_gid;
- range_rec.value = prev_klass;
-
- auto *record = c->copy (range_rec);
- if (unlikely (!record)) return_trace (false);
-
- for (const auto gid_klass_pair : + (++it))
- {
- hb_codepoint_t cur_gid = gid_klass_pair.first;
- unsigned cur_klass = gid_klass_pair.second;
-
- if (cur_gid != prev_gid + 1 ||
- cur_klass != prev_klass)
- {
- if (unlikely (!record)) break;
- record->last = prev_gid;
- num_ranges++;
-
- range_rec.first = cur_gid;
- range_rec.last = cur_gid;
- range_rec.value = cur_klass;
-
- record = c->copy (range_rec);
- }
-
- prev_klass = cur_klass;
- prev_gid = cur_gid;
- }
-
- if (likely (record)) record->last = prev_gid;
- rangeRecord.len = num_ranges;
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c,
- hb_map_t *klass_map = nullptr /*OUT*/,
- bool keep_empty_table = true,
- bool use_class_zero = true,
- const Coverage* glyph_filter = nullptr) const
- {
- TRACE_SUBSET (this);
- const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
- const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
-
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
- hb_set_t orig_klasses;
-
- if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
- < get_population ())
- {
- for (hb_codepoint_t g : glyph_set)
- {
- unsigned klass = get_class (g);
- if (!klass) continue;
- hb_codepoint_t new_gid = glyph_map[g];
- if (new_gid == HB_MAP_VALUE_INVALID) continue;
- if (glyph_filter && !glyph_filter->has (g)) continue;
- glyph_and_klass.push (hb_pair (new_gid, klass));
- orig_klasses.add (klass);
- }
- }
- else
- {
- unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
- for (auto &range : rangeRecord)
- {
- unsigned klass = range.value;
- if (!klass) continue;
- hb_codepoint_t start = range.first;
- hb_codepoint_t end = hb_min (range.last + 1, num_source_glyphs);
- for (hb_codepoint_t g = start; g < end; g++)
- {
- hb_codepoint_t new_gid = glyph_map[g];
- if (new_gid == HB_MAP_VALUE_INVALID) continue;
- if (glyph_filter && !glyph_filter->has (g)) continue;
-
- glyph_and_klass.push (hb_pair (new_gid, klass));
- orig_klasses.add (klass);
- }
- }
- }
-
- const hb_set_t& glyphset = *c->plan->glyphset_gsub ();
- unsigned glyph_count = glyph_filter
- ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter))
- : glyph_map.get_population ();
- use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
- if (!ClassDef_remap_and_serialize (c->serializer,
- orig_klasses,
- use_class_zero,
- glyph_and_klass,
- klass_map))
- return_trace (false);
- return_trace (keep_empty_table || (bool) glyph_and_klass);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (rangeRecord.sanitize (c));
- }
-
- unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
-
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- {
- for (auto &range : rangeRecord)
- if (range.value)
- if (unlikely (!range.collect_coverage (glyphs)))
- return false;
- return true;
- }
-
- template <typename set_t>
- bool collect_class (set_t *glyphs, unsigned int klass) const
- {
- for (auto &range : rangeRecord)
- {
- if (range.value == klass)
- if (unlikely (!range.collect_coverage (glyphs)))
- return false;
- }
- return true;
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
- {
- for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
- if (get_class (g))
- return true;
- return false;
- }
-
- return hb_any (+ hb_iter (rangeRecord)
- | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs) && range.value; }));
- }
- bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
- {
- if (klass == 0)
- {
- /* Match if there's any glyph that is not listed! */
- hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (auto &range : rangeRecord)
- {
- if (!glyphs->next (&g))
- break;
- if (g < range.first)
- return true;
- g = range.last;
- }
- if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
- return true;
- /* Fall through. */
- }
- for (const auto &range : rangeRecord)
- if (range.value == klass && range.intersects (*glyphs))
- return true;
- return false;
- }
-
- void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
- {
- if (klass == 0)
- {
- hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (auto &range : rangeRecord)
- {
- if (!glyphs->next (&g))
- goto done;
- while (g < range.first)
- {
- intersect_glyphs->add (g);
- if (!glyphs->next (&g))
- goto done;
- }
- g = range.last;
- }
- while (glyphs->next (&g))
- intersect_glyphs->add (g);
- done:
-
- return;
- }
-
- unsigned count = rangeRecord.len;
- if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
- {
- for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
- glyphs->next (&g);)
- {
- unsigned i;
- if (rangeRecord.as_array ().bfind (g, &i) &&
- rangeRecord.arrayZ[i].value == klass)
- intersect_glyphs->add (g);
- }
- return;
- }
-
- for (auto &range : rangeRecord)
- {
- if (range.value != klass) continue;
-
- unsigned end = range.last + 1;
- for (hb_codepoint_t g = range.first - 1;
- glyphs->next (&g) && g < end;)
- intersect_glyphs->add (g);
- }
- }
-
- void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
- {
- if (glyphs->is_empty ()) return;
-
- hb_codepoint_t g = HB_SET_VALUE_INVALID;
- for (auto &range : rangeRecord)
- {
- if (!glyphs->next (&g))
- break;
- if (g < range.first)
- {
- intersect_classes->add (0);
- break;
- }
- g = range.last;
- }
- if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
- intersect_classes->add (0);
-
- for (const auto& range : rangeRecord)
- if (range.intersects (*glyphs))
- intersect_classes->add (range.value);
- }
-
- protected:
- HBUINT16 classFormat; /* Format identifier--format = 2 */
- typename Types::template SortedArrayOf<RangeRecord<Types>>
- rangeRecord; /* Array of glyph ranges--ordered by
- * Start GlyphID */
- public:
- DEFINE_SIZE_ARRAY (2 + Types::size, rangeRecord);
-};
-
-struct ClassDef
-{
- /* Has interface. */
- unsigned operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k]; }
- /* Projection. */
- hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
-
- unsigned int get (hb_codepoint_t k) const { return get_class (k); }
- unsigned int get_class (hb_codepoint_t glyph_id) const
- {
- switch (u.format) {
- case 1: return u.format1.get_class (glyph_id);
- case 2: return u.format2.get_class (glyph_id);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.get_class (glyph_id);
- case 4: return u.format4.get_class (glyph_id);
-#endif
- default:return 0;
- }
- }
-
- unsigned get_population () const
- {
- switch (u.format) {
- case 1: return u.format1.get_population ();
- case 2: return u.format2.get_population ();
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.get_population ();
- case 4: return u.format4.get_population ();
-#endif
- default:return NOT_COVERED;
- }
- }
-
- template<typename Iterator,
- hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
- bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- auto it = + it_with_class_zero | hb_filter (hb_second);
-
- unsigned format = 2;
- hb_codepoint_t glyph_max = 0;
- if (likely (it))
- {
- hb_codepoint_t glyph_min = (*it).first;
- glyph_max = glyph_min;
-
- unsigned num_glyphs = 0;
- unsigned num_ranges = 1;
- hb_codepoint_t prev_gid = glyph_min;
- unsigned prev_klass = (*it).second;
-
- for (const auto gid_klass_pair : it)
- {
- hb_codepoint_t cur_gid = gid_klass_pair.first;
- unsigned cur_klass = gid_klass_pair.second;
- num_glyphs++;
- if (cur_gid == glyph_min) continue;
- if (cur_gid > glyph_max) glyph_max = cur_gid;
- if (cur_gid != prev_gid + 1 ||
- cur_klass != prev_klass)
- num_ranges++;
-
- prev_gid = cur_gid;
- prev_klass = cur_klass;
- }
-
- if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3)
- format = 1;
- }
-
-#ifndef HB_NO_BEYOND_64K
- if (glyph_max > 0xFFFFu)
- format += 2;
-#endif
-
- u.format = format;
-
- switch (u.format)
- {
- case 1: return_trace (u.format1.serialize (c, it));
- case 2: return_trace (u.format2.serialize (c, it));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.serialize (c, it));
- case 4: return_trace (u.format4.serialize (c, it));
-#endif
- default:return_trace (false);
- }
- }
-
- bool subset (hb_subset_context_t *c,
- hb_map_t *klass_map = nullptr /*OUT*/,
- bool keep_empty_table = true,
- bool use_class_zero = true,
- const Coverage* glyph_filter = nullptr) const
- {
- TRACE_SUBSET (this);
- switch (u.format) {
- case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
- case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
- case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
-#endif
- default:return_trace (false);
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
-#ifndef HB_NO_BEYOND_64K
- case 3: return_trace (u.format3.sanitize (c));
- case 4: return_trace (u.format4.sanitize (c));
-#endif
- default:return_trace (true);
- }
- }
-
- unsigned cost () const
- {
- switch (u.format) {
- case 1: return u.format1.cost ();
- case 2: return u.format2.cost ();
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.cost ();
- case 4: return u.format4.cost ();
-#endif
- default:return 0u;
- }
- }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename set_t>
- bool collect_coverage (set_t *glyphs) const
- {
- switch (u.format) {
- case 1: return u.format1.collect_coverage (glyphs);
- case 2: return u.format2.collect_coverage (glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.collect_coverage (glyphs);
- case 4: return u.format4.collect_coverage (glyphs);
-#endif
- default:return false;
- }
- }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename set_t>
- bool collect_class (set_t *glyphs, unsigned int klass) const
- {
- switch (u.format) {
- case 1: return u.format1.collect_class (glyphs, klass);
- case 2: return u.format2.collect_class (glyphs, klass);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.collect_class (glyphs, klass);
- case 4: return u.format4.collect_class (glyphs, klass);
-#endif
- default:return false;
- }
- }
-
- bool intersects (const hb_set_t *glyphs) const
- {
- switch (u.format) {
- case 1: return u.format1.intersects (glyphs);
- case 2: return u.format2.intersects (glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersects (glyphs);
- case 4: return u.format4.intersects (glyphs);
-#endif
- default:return false;
- }
- }
- bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
- {
- switch (u.format) {
- case 1: return u.format1.intersects_class (glyphs, klass);
- case 2: return u.format2.intersects_class (glyphs, klass);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersects_class (glyphs, klass);
- case 4: return u.format4.intersects_class (glyphs, klass);
-#endif
- default:return false;
- }
- }
-
- void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
- {
- switch (u.format) {
- case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
- case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
- case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
-#endif
- default:return;
- }
- }
-
- void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
- {
- switch (u.format) {
- case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
- case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
-#ifndef HB_NO_BEYOND_64K
- case 3: return u.format3.intersected_classes (glyphs, intersect_classes);
- case 4: return u.format4.intersected_classes (glyphs, intersect_classes);
-#endif
- default:return;
- }
- }
-
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ClassDefFormat1_3<SmallTypes> format1;
- ClassDefFormat2_4<SmallTypes> format2;
-#ifndef HB_NO_BEYOND_64K
- ClassDefFormat1_3<MediumTypes>format3;
- ClassDefFormat2_4<MediumTypes>format4;
-#endif
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-template<typename Iterator>
-static inline bool ClassDef_serialize (hb_serialize_context_t *c,
- Iterator it)
-{ return (c->start_embed<ClassDef> ()->serialize (c, it)); }
-
-
-/*
- * Item Variation Store
- */
-
-struct VarRegionAxis
-{
- float evaluate (int coord) const
- {
- int peak = peakCoord.to_int ();
- if (peak == 0 || coord == peak)
- return 1.f;
-
- int start = startCoord.to_int (), end = endCoord.to_int ();
-
- /* TODO Move these to sanitize(). */
- if (unlikely (start > peak || peak > end))
- return 1.f;
- if (unlikely (start < 0 && end > 0 && peak != 0))
- return 1.f;
-
- if (coord <= start || end <= coord)
- return 0.f;
-
- /* Interpolate */
- if (coord < peak)
- return float (coord - start) / (peak - start);
- else
- return float (end - coord) / (end - peak);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- /* TODO Handle invalid start/peak/end configs, so we don't
- * have to do that at runtime. */
- }
-
- public:
- F2DOT14 startCoord;
- F2DOT14 peakCoord;
- F2DOT14 endCoord;
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-#define REGION_CACHE_ITEM_CACHE_INVALID 2.f
-
-struct VarRegionList
-{
- using cache_t = float;
-
- float evaluate (unsigned int region_index,
- const int *coords, unsigned int coord_len,
- cache_t *cache = nullptr) const
- {
- if (unlikely (region_index >= regionCount))
- return 0.;
-
- float *cached_value = nullptr;
- if (cache)
- {
- cached_value = &(cache[region_index]);
- if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID))
- return *cached_value;
- }
-
- const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount);
-
- float v = 1.;
- unsigned int count = axisCount;
- for (unsigned int i = 0; i < count; i++)
- {
- int coord = i < coord_len ? coords[i] : 0;
- float factor = axes[i].evaluate (coord);
- if (factor == 0.f)
- {
- if (cache)
- *cached_value = 0.;
- return 0.;
- }
- v *= factor;
- }
-
- if (cache)
- *cached_value = v;
- return v;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount));
- }
-
- bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t &region_map)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- axisCount = src->axisCount;
- regionCount = region_map.get_population ();
- if (unlikely (hb_unsigned_mul_overflows (axisCount * regionCount,
- VarRegionAxis::static_size))) return_trace (false);
- if (unlikely (!c->extend (this))) return_trace (false);
- unsigned int region_count = src->regionCount;
- for (unsigned int r = 0; r < regionCount; r++)
- {
- unsigned int backward = region_map.backward (r);
- if (backward >= region_count) return_trace (false);
- hb_memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
- }
-
- return_trace (true);
- }
-
- unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
-
- public:
- HBUINT16 axisCount;
- HBUINT15 regionCount;
- protected:
- UnsizedArrayOf<VarRegionAxis>
- axesZ;
- public:
- DEFINE_SIZE_ARRAY (4, axesZ);
-};
-
-struct VarData
-{
- unsigned int get_item_count () const
- { return itemCount; }
-
- unsigned int get_region_index_count () const
- { return regionIndices.len; }
-
- unsigned int get_row_size () const
- { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
-
- unsigned int get_size () const
- { return min_size
- - regionIndices.min_size + regionIndices.get_size ()
- + itemCount * get_row_size ();
- }
-
- float get_delta (unsigned int inner,
- const int *coords, unsigned int coord_count,
- const VarRegionList &regions,
- VarRegionList::cache_t *cache = nullptr) const
- {
- if (unlikely (inner >= itemCount))
- return 0.;
-
- unsigned int count = regionIndices.len;
- bool is_long = longWords ();
- unsigned word_count = wordCount ();
- unsigned int scount = is_long ? count : word_count;
- unsigned int lcount = is_long ? word_count : 0;
-
- const HBUINT8 *bytes = get_delta_bytes ();
- const HBUINT8 *row = bytes + inner * get_row_size ();
-
- float delta = 0.;
- unsigned int i = 0;
-
- const HBINT32 *lcursor = reinterpret_cast<const HBINT32 *> (row);
- for (; i < lcount; i++)
- {
- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
- delta += scalar * *lcursor++;
- }
- const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (lcursor);
- for (; i < scount; i++)
- {
- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
- delta += scalar * *scursor++;
- }
- const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
- for (; i < count; i++)
- {
- float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
- delta += scalar * *bcursor++;
- }
-
- return delta;
- }
-
- void get_region_scalars (const int *coords, unsigned int coord_count,
- const VarRegionList &regions,
- float *scalars /*OUT */,
- unsigned int num_scalars) const
- {
- unsigned count = hb_min (num_scalars, regionIndices.len);
- for (unsigned int i = 0; i < count; i++)
- scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
- for (unsigned int i = count; i < num_scalars; i++)
- scalars[i] = 0.f;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- regionIndices.sanitize (c) &&
- wordCount () <= regionIndices.len &&
- c->check_range (get_delta_bytes (),
- itemCount,
- get_row_size ()));
- }
-
- bool serialize (hb_serialize_context_t *c,
- const VarData *src,
- const hb_inc_bimap_t &inner_map,
- const hb_bimap_t &region_map)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!c->extend_min (this))) return_trace (false);
- itemCount = inner_map.get_next_value ();
-
- /* Optimize word count */
- unsigned ri_count = src->regionIndices.len;
- enum delta_size_t { kZero=0, kNonWord, kWord };
- hb_vector_t<delta_size_t> delta_sz;
- hb_vector_t<unsigned int> ri_map; /* maps new index to old index */
- delta_sz.resize (ri_count);
- ri_map.resize (ri_count);
- unsigned int new_word_count = 0;
- unsigned int r;
-
- const HBUINT8 *src_delta_bytes = src->get_delta_bytes ();
- unsigned src_row_size = src->get_row_size ();
- unsigned src_word_count = src->wordCount ();
- bool src_long_words = src->longWords ();
-
- bool has_long = false;
- if (src_long_words)
- {
- for (r = 0; r < src_word_count; r++)
- {
- for (unsigned old_gid : inner_map.keys())
- {
- int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
- if (delta < -65536 || 65535 < delta)
- {
- has_long = true;
- break;
- }
- }
- }
- }
-
- signed min_threshold = has_long ? -65536 : -128;
- signed max_threshold = has_long ? +65535 : +127;
- for (r = 0; r < ri_count; r++)
- {
- bool short_circuit = src_long_words == has_long && src_word_count <= r;
-
- delta_sz[r] = kZero;
- for (unsigned old_gid : inner_map.keys())
- {
- int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
- if (delta < min_threshold || max_threshold < delta)
- {
- delta_sz[r] = kWord;
- new_word_count++;
- break;
- }
- else if (delta != 0)
- {
- delta_sz[r] = kNonWord;
- if (short_circuit)
- break;
- }
- }
- }
-
- unsigned int word_index = 0;
- unsigned int non_word_index = new_word_count;
- unsigned int new_ri_count = 0;
- for (r = 0; r < ri_count; r++)
- if (delta_sz[r])
- {
- unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
- ri_map[new_r] = r;
- new_ri_count++;
- }
-
- wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
-
- regionIndices.len = new_ri_count;
-
- if (unlikely (!c->extend (this))) return_trace (false);
-
- for (r = 0; r < new_ri_count; r++)
- regionIndices[r] = region_map[src->regionIndices[ri_map[r]]];
-
- HBUINT8 *delta_bytes = get_delta_bytes ();
- unsigned row_size = get_row_size ();
- unsigned count = itemCount;
- for (unsigned int i = 0; i < count; i++)
- {
- unsigned int old = inner_map.backward (i);
- for (unsigned int r = 0; r < new_ri_count; r++)
- set_item_delta_fast (i, r,
- src->get_item_delta_fast (old, ri_map[r],
- src_delta_bytes, src_row_size),
- delta_bytes, row_size);
- }
-
- return_trace (true);
- }
-
- void collect_region_refs (hb_set_t &region_indices, const hb_inc_bimap_t &inner_map) const
- {
- const HBUINT8 *delta_bytes = get_delta_bytes ();
- unsigned row_size = get_row_size ();
-
- for (unsigned int r = 0; r < regionIndices.len; r++)
- {
- unsigned int region = regionIndices.arrayZ[r];
- if (region_indices.has (region)) continue;
- for (hb_codepoint_t old_gid : inner_map.keys())
- if (get_item_delta_fast (old_gid, r, delta_bytes, row_size) != 0)
- {
- region_indices.add (region);
- break;
- }
- }
- }
-
- protected:
- const HBUINT8 *get_delta_bytes () const
- { return &StructAfter<HBUINT8> (regionIndices); }
-
- HBUINT8 *get_delta_bytes ()
- { return &StructAfter<HBUINT8> (regionIndices); }
-
- int32_t get_item_delta_fast (unsigned int item, unsigned int region,
- const HBUINT8 *delta_bytes, unsigned row_size) const
- {
- if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
-
- const HBINT8 *p = (const HBINT8 *) delta_bytes + item * row_size;
- unsigned word_count = wordCount ();
- bool is_long = longWords ();
- if (is_long)
- {
- if (region < word_count)
- return ((const HBINT32 *) p)[region];
- else
- return ((const HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count];
- }
- else
- {
- if (region < word_count)
- return ((const HBINT16 *) p)[region];
- else
- return (p + HBINT16::static_size * word_count)[region - word_count];
- }
- }
- int32_t get_item_delta (unsigned int item, unsigned int region) const
- {
- return get_item_delta_fast (item, region,
- get_delta_bytes (),
- get_row_size ());
- }
-
- void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
- HBUINT8 *delta_bytes, unsigned row_size)
- {
- HBINT8 *p = (HBINT8 *) delta_bytes + item * row_size;
- unsigned word_count = wordCount ();
- bool is_long = longWords ();
- if (is_long)
- {
- if (region < word_count)
- ((HBINT32 *) p)[region] = delta;
- else
- ((HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count] = delta;
- }
- else
- {
- if (region < word_count)
- ((HBINT16 *) p)[region] = delta;
- else
- (p + HBINT16::static_size * word_count)[region - word_count] = delta;
- }
- }
- void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
- {
- set_item_delta_fast (item, region, delta,
- get_delta_bytes (),
- get_row_size ());
- }
-
- bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
- unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
-
- protected:
- HBUINT16 itemCount;
- HBUINT16 wordSizeCount;
- Array16Of<HBUINT16> regionIndices;
-/*UnsizedArrayOf<HBUINT8>bytesX;*/
- public:
- DEFINE_SIZE_ARRAY (6, regionIndices);
-};
-
-struct VariationStore
-{
- using cache_t = VarRegionList::cache_t;
-
- cache_t *create_cache () const
- {
-#ifdef HB_NO_VAR
- return nullptr;
-#endif
- auto &r = this+regions;
- unsigned count = r.regionCount;
-
- float *cache = (float *) hb_malloc (sizeof (float) * count);
- if (unlikely (!cache)) return nullptr;
-
- for (unsigned i = 0; i < count; i++)
- cache[i] = REGION_CACHE_ITEM_CACHE_INVALID;
-
- return cache;
- }
-
- static void destroy_cache (cache_t *cache) { hb_free (cache); }
-
- private:
- float get_delta (unsigned int outer, unsigned int inner,
- const int *coords, unsigned int coord_count,
- VarRegionList::cache_t *cache = nullptr) const
- {
-#ifdef HB_NO_VAR
- return 0.f;
-#endif
-
- if (unlikely (outer >= dataSets.len))
- return 0.f;
-
- return (this+dataSets[outer]).get_delta (inner,
- coords, coord_count,
- this+regions,
- cache);
- }
-
- public:
- float get_delta (unsigned int index,
- const int *coords, unsigned int coord_count,
- VarRegionList::cache_t *cache = nullptr) const
- {
- unsigned int outer = index >> 16;
- unsigned int inner = index & 0xFFFF;
- return get_delta (outer, inner, coords, coord_count, cache);
- }
- float get_delta (unsigned int index,
- hb_array_t<int> coords,
- VarRegionList::cache_t *cache = nullptr) const
- {
- return get_delta (index,
- coords.arrayZ, coords.length,
- cache);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
-#ifdef HB_NO_VAR
- return true;
-#endif
-
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- format == 1 &&
- regions.sanitize (c, this) &&
- dataSets.sanitize (c, this));
- }
-
- bool serialize (hb_serialize_context_t *c,
- const VariationStore *src,
- const hb_array_t <const hb_inc_bimap_t> &inner_maps)
- {
- TRACE_SERIALIZE (this);
-#ifdef HB_NO_VAR
- return_trace (false);
-#endif
-
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- unsigned int set_count = 0;
- for (unsigned int i = 0; i < inner_maps.length; i++)
- if (inner_maps[i].get_population ())
- set_count++;
-
- format = 1;
-
- const auto &src_regions = src+src->regions;
-
- hb_set_t region_indices;
- for (unsigned int i = 0; i < inner_maps.length; i++)
- (src+src->dataSets[i]).collect_region_refs (region_indices, inner_maps[i]);
-
- if (region_indices.in_error ())
- return_trace (false);
-
- region_indices.del_range ((src_regions).regionCount, hb_set_t::INVALID);
-
- /* TODO use constructor when our data-structures support that. */
- hb_inc_bimap_t region_map;
- + hb_iter (region_indices)
- | hb_apply ([&region_map] (unsigned _) { region_map.add(_); })
- ;
- if (region_map.in_error())
- return_trace (false);
-
- if (unlikely (!regions.serialize_serialize (c, &src_regions, region_map)))
- return_trace (false);
-
- dataSets.len = set_count;
- if (unlikely (!c->extend (dataSets))) return_trace (false);
-
- /* TODO: The following code could be simplified when
- * List16OfOffset16To::subset () can take a custom param to be passed to VarData::serialize () */
- unsigned int set_index = 0;
- for (unsigned int i = 0; i < inner_maps.length; i++)
- {
- if (!inner_maps[i].get_population ()) continue;
- if (unlikely (!dataSets[set_index++]
- .serialize_serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
- return_trace (false);
- }
-
- return_trace (true);
- }
-
- VariationStore *copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- hb_vector_t <hb_inc_bimap_t> inner_maps;
- unsigned count = dataSets.len;
- for (unsigned i = 0; i < count; i++)
- {
- hb_inc_bimap_t *map = inner_maps.push ();
- auto &data = this+dataSets[i];
-
- unsigned itemCount = data.get_item_count ();
- for (unsigned j = 0; j < itemCount; j++)
- map->add (j);
- }
-
- if (unlikely (!out->serialize (c, this, inner_maps))) return_trace (nullptr);
-
- return_trace (out);
- }
-
- bool subset (hb_subset_context_t *c, const hb_array_t<const hb_inc_bimap_t> &inner_maps) const
- {
- TRACE_SUBSET (this);
-#ifdef HB_NO_VAR
- return_trace (false);
-#endif
-
- VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> ();
- if (unlikely (!varstore_prime)) return_trace (false);
-
- varstore_prime->serialize (c->serializer, this, inner_maps);
-
- return_trace (
- !c->serializer->in_error()
- && varstore_prime->dataSets);
- }
-
- unsigned int get_region_index_count (unsigned int major) const
- {
-#ifdef HB_NO_VAR
- return 0;
-#endif
- return (this+dataSets[major]).get_region_index_count ();
- }
-
- void get_region_scalars (unsigned int major,
- const int *coords, unsigned int coord_count,
- float *scalars /*OUT*/,
- unsigned int num_scalars) const
- {
-#ifdef HB_NO_VAR
- for (unsigned i = 0; i < num_scalars; i++)
- scalars[i] = 0.f;
- return;
-#endif
-
- (this+dataSets[major]).get_region_scalars (coords, coord_count,
- this+regions,
- &scalars[0], num_scalars);
- }
-
- unsigned int get_sub_table_count () const
- {
-#ifdef HB_NO_VAR
- return 0;
-#endif
- return dataSets.len;
- }
-
- protected:
- HBUINT16 format;
- Offset32To<VarRegionList> regions;
- Array16OfOffset32To<VarData> dataSets;
- public:
- DEFINE_SIZE_ARRAY_SIZED (8, dataSets);
-};
-
-#undef REGION_CACHE_ITEM_CACHE_INVALID
-
-/*
- * Feature Variations
- */
-enum Cond_with_Var_flag_t
-{
- KEEP_COND_WITH_VAR = 0,
- DROP_COND_WITH_VAR = 1,
- DROP_RECORD_WITH_VAR = 2,
- MEM_ERR_WITH_VAR = 3,
-};
-
-struct ConditionFormat1
-{
- friend struct Condition;
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- const hb_map_t *index_map = &c->plan->axes_index_map;
- if (index_map->is_empty ()) return_trace (true);
-
- if (!index_map->has (axisIndex))
- return_trace (false);
-
- return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- private:
- Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
- hb_map_t *condition_map /* OUT */) const
- {
- //invalid axis index, drop the entire record
- if (!c->axes_index_tag_map->has (axisIndex))
- return DROP_RECORD_WITH_VAR;
-
- hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
-
- //axis not pinned, keep the condition
- if (!c->axes_location->has (axis_tag))
- {
- // add axisIndex->value into the hashmap so we can check if the record is
- // unique with variations
- int16_t min_val = filterRangeMinValue.to_int ();
- int16_t max_val = filterRangeMaxValue.to_int ();
- hb_codepoint_t val = (max_val << 16) + min_val;
-
- condition_map->set (axisIndex, val);
- return KEEP_COND_WITH_VAR;
- }
-
- //axis pinned, check if condition is met
- //TODO: add check for axis Ranges
- int v = c->axes_location->get (axis_tag);
-
- //condition not met, drop the entire record
- if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
- return DROP_RECORD_WITH_VAR;
-
- //axis pinned and condition met, drop the condition
- return DROP_COND_WITH_VAR;
- }
-
- bool evaluate (const int *coords, unsigned int coord_len) const
- {
- int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
- return filterRangeMinValue.to_int () <= coord && coord <= filterRangeMaxValue.to_int ();
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- HBUINT16 axisIndex;
- F2DOT14 filterRangeMinValue;
- F2DOT14 filterRangeMaxValue;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct Condition
-{
- bool evaluate (const int *coords, unsigned int coord_len) const
- {
- switch (u.format) {
- case 1: return u.format1.evaluate (coords, coord_len);
- default:return false;
- }
- }
-
- Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
- hb_map_t *condition_map /* OUT */) const
- {
- switch (u.format) {
- case 1: return u.format1.keep_with_variations (c, condition_map);
- default:return KEEP_COND_WITH_VAR;
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 1: return_trace (u.format1.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ConditionFormat1 format1;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-struct ConditionSet
-{
- bool evaluate (const int *coords, unsigned int coord_len) const
- {
- unsigned int count = conditions.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
- return false;
- return true;
- }
-
- Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
- {
- hb_map_t *condition_map = hb_map_create ();
- if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
- hb::shared_ptr<hb_map_t> p {condition_map};
-
- hb_set_t *cond_set = hb_set_create ();
- if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
- hb::shared_ptr<hb_set_t> s {cond_set};
-
- unsigned num_kept_cond = 0, cond_idx = 0;
- for (const auto& offset : conditions)
- {
- Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
- // one condition is not met, drop the entire record
- if (ret == DROP_RECORD_WITH_VAR)
- return DROP_RECORD_WITH_VAR;
-
- // axis not pinned, keep this condition
- if (ret == KEEP_COND_WITH_VAR)
- {
- cond_set->add (cond_idx);
- num_kept_cond++;
- }
- cond_idx++;
- }
-
- // all conditions met
- if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
-
- //check if condition_set is unique with variations
- if (c->conditionset_map->has (p))
- //duplicate found, drop the entire record
- return DROP_RECORD_WITH_VAR;
-
- c->conditionset_map->set (p, 1);
- c->record_cond_idx_map->set (c->cur_record_idx, s);
-
- return KEEP_COND_WITH_VAR;
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- hb_set_t *retained_cond_set = nullptr;
- if (l->feature_record_cond_idx_map != nullptr)
- retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx);
-
- unsigned int count = conditions.len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (retained_cond_set != nullptr && !retained_cond_set->has (i))
- continue;
- subset_offset_array (c, out->conditions, this) (conditions[i]);
- }
-
- return_trace (bool (out->conditions));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (conditions.sanitize (c, this));
- }
-
- protected:
- Array16OfOffset32To<Condition> conditions;
- public:
- DEFINE_SIZE_ARRAY (2, conditions);
-};
-
-struct FeatureTableSubstitutionRecord
-{
- friend struct FeatureTableSubstitution;
-
- void collect_lookups (const void *base, hb_set_t *lookup_indexes /* OUT */) const
- {
- return (base+feature).add_lookup_indexes_to (lookup_indexes);
- }
-
- void closure_features (const void *base,
- const hb_map_t *lookup_indexes,
- hb_set_t *feature_indexes /* OUT */) const
- {
- if ((base+feature).intersects_lookup_indexes (lookup_indexes))
- feature_indexes->add (featureIndex);
- }
-
- void collect_feature_substitutes_with_variations (hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
- const hb_set_t *feature_indices,
- const void *base) const
- {
- if (feature_indices->has (featureIndex))
- feature_substitutes_map->set (featureIndex, &(base+feature));
- }
-
- bool subset (hb_subset_layout_context_t *c, const void *base) const
- {
- TRACE_SUBSET (this);
- if (!c->feature_index_map->has (featureIndex) ||
- c->feature_substitutes_map->has (featureIndex)) {
- // Feature that is being substituted is not being retained, so we don't
- // need this.
- return_trace (false);
- }
-
- auto *out = c->subset_context->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- out->featureIndex = c->feature_index_map->get (featureIndex);
- bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c);
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && feature.sanitize (c, base));
- }
-
- protected:
- HBUINT16 featureIndex;
- Offset32To<Feature> feature;
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct FeatureTableSubstitution
-{
- const Feature *find_substitute (unsigned int feature_index) const
- {
- unsigned int count = substitutions.len;
- for (unsigned int i = 0; i < count; i++)
- {
- const FeatureTableSubstitutionRecord &record = substitutions.arrayZ[i];
- if (record.featureIndex == feature_index)
- return &(this+record.feature);
- }
- return nullptr;
- }
-
- void collect_lookups (const hb_set_t *feature_indexes,
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
- hb_set_t *lookup_indexes /* OUT */) const
- {
- + hb_iter (substitutions)
- | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex)
- | hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record)
- {
- if (feature_substitutes_map == nullptr) return true;
- return !feature_substitutes_map->has (record.featureIndex);
- })
- | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r)
- { r.collect_lookups (this, lookup_indexes); })
- ;
- }
-
- void closure_features (const hb_map_t *lookup_indexes,
- hb_set_t *feature_indexes /* OUT */) const
- {
- for (const FeatureTableSubstitutionRecord& record : substitutions)
- record.closure_features (this, lookup_indexes, feature_indexes);
- }
-
- bool intersects_features (const hb_map_t *feature_index_map) const
- {
- for (const FeatureTableSubstitutionRecord& record : substitutions)
- {
- if (feature_index_map->has (record.featureIndex)) return true;
- }
- return false;
- }
-
- void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
- {
- for (const FeatureTableSubstitutionRecord& record : substitutions)
- record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this);
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- out->version.major = version.major;
- out->version.minor = version.minor;
-
- + substitutions.iter ()
- | hb_apply (subset_record_array (l, &(out->substitutions), this))
- ;
-
- return_trace (bool (out->substitutions));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (version.sanitize (c) &&
- likely (version.major == 1) &&
- substitutions.sanitize (c, this));
- }
-
- protected:
- FixedVersion<> version; /* Version--0x00010000u */
- Array16Of<FeatureTableSubstitutionRecord>
- substitutions;
- public:
- DEFINE_SIZE_ARRAY (6, substitutions);
-};
-
-struct FeatureVariationRecord
-{
- friend struct FeatureVariations;
-
- void collect_lookups (const void *base,
- const hb_set_t *feature_indexes,
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
- hb_set_t *lookup_indexes /* OUT */) const
- {
- return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes);
- }
-
- void closure_features (const void *base,
- const hb_map_t *lookup_indexes,
- hb_set_t *feature_indexes /* OUT */) const
- {
- (base+substitutions).closure_features (lookup_indexes, feature_indexes);
- }
-
- bool intersects_features (const void *base, const hb_map_t *feature_index_map) const
- {
- return (base+substitutions).intersects_features (feature_index_map);
- }
-
- void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
- const void *base) const
- {
- // ret == 1, all conditions met
- if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
- c->apply)
- {
- (base+substitutions).collect_feature_substitutes_with_variations (c);
- c->apply = false; // set variations only once
- }
- }
-
- bool subset (hb_subset_layout_context_t *c, const void *base) const
- {
- TRACE_SUBSET (this);
- auto *out = c->subset_context->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- out->conditions.serialize_subset (c->subset_context, conditions, base, c);
- out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (conditions.sanitize (c, base) &&
- substitutions.sanitize (c, base));
- }
-
- protected:
- Offset32To<ConditionSet>
- conditions;
- Offset32To<FeatureTableSubstitution>
- substitutions;
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct FeatureVariations
-{
- static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFFFFFu;
-
- bool find_index (const int *coords, unsigned int coord_len,
- unsigned int *index) const
- {
- unsigned int count = varRecords.len;
- for (unsigned int i = 0; i < count; i++)
- {
- const FeatureVariationRecord &record = varRecords.arrayZ[i];
- if ((this+record.conditions).evaluate (coords, coord_len))
- {
- *index = i;
- return true;
- }
- }
- *index = NOT_FOUND_INDEX;
- return false;
- }
-
- const Feature *find_substitute (unsigned int variations_index,
- unsigned int feature_index) const
- {
- const FeatureVariationRecord &record = varRecords[variations_index];
- return (this+record.substitutions).find_substitute (feature_index);
- }
-
- void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
- {
- unsigned int count = varRecords.len;
- for (unsigned int i = 0; i < count; i++)
- {
- c->cur_record_idx = i;
- varRecords[i].collect_feature_substitutes_with_variations (c, this);
- }
- }
-
- FeatureVariations* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed (*this));
- }
-
- void collect_lookups (const hb_set_t *feature_indexes,
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
- hb_set_t *lookup_indexes /* OUT */) const
- {
- for (const FeatureVariationRecord& r : varRecords)
- r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes);
- }
-
- void closure_features (const hb_map_t *lookup_indexes,
- const hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
- hb_set_t *feature_indexes /* OUT */) const
- {
- unsigned int count = varRecords.len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (feature_record_cond_idx_map != nullptr &&
- !feature_record_cond_idx_map->has (i))
- continue;
- varRecords[i].closure_features (this, lookup_indexes, feature_indexes);
- }
- }
-
- bool subset (hb_subset_context_t *c,
- hb_subset_layout_context_t *l) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- out->version.major = version.major;
- out->version.minor = version.minor;
-
- int keep_up_to = -1;
- for (int i = varRecords.len - 1; i >= 0; i--) {
- if (varRecords[i].intersects_features (this, l->feature_index_map)) {
- keep_up_to = i;
- break;
- }
- }
-
- unsigned count = (unsigned) (keep_up_to + 1);
- for (unsigned i = 0; i < count; i++)
- {
- if (l->feature_record_cond_idx_map != nullptr &&
- !l->feature_record_cond_idx_map->has (i))
- continue;
-
- l->cur_feature_var_record_idx = i;
- subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
- }
- return_trace (bool (out->varRecords));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (version.sanitize (c) &&
- likely (version.major == 1) &&
- varRecords.sanitize (c, this));
- }
-
- protected:
- FixedVersion<> version; /* Version--0x00010000u */
- Array32Of<FeatureVariationRecord>
- varRecords;
- public:
- DEFINE_SIZE_ARRAY_SIZED (8, varRecords);
-};
-
-
-/*
- * Device Tables
- */
-
-struct HintingDevice
-{
- friend struct Device;
-
- private:
-
- hb_position_t get_x_delta (hb_font_t *font) const
- { return get_delta (font->x_ppem, font->x_scale); }
-
- hb_position_t get_y_delta (hb_font_t *font) const
- { return get_delta (font->y_ppem, font->y_scale); }
-
- public:
-
- unsigned int get_size () const
- {
- unsigned int f = deltaFormat;
- if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size;
- return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
- }
-
- HintingDevice* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- return_trace (c->embed<HintingDevice> (this));
- }
-
- private:
-
- int get_delta (unsigned int ppem, int scale) const
- {
- if (!ppem) return 0;
-
- int pixels = get_delta_pixels (ppem);
-
- if (!pixels) return 0;
-
- return (int) (pixels * (int64_t) scale / ppem);
- }
- int get_delta_pixels (unsigned int ppem_size) const
- {
- unsigned int f = deltaFormat;
- if (unlikely (f < 1 || f > 3))
- return 0;
-
- if (ppem_size < startSize || ppem_size > endSize)
- return 0;
-
- unsigned int s = ppem_size - startSize;
-
- unsigned int byte = deltaValueZ[s >> (4 - f)];
- unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
- unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
-
- int delta = bits & mask;
-
- if ((unsigned int) delta >= ((mask + 1) >> 1))
- delta -= mask + 1;
-
- return delta;
- }
-
- protected:
- HBUINT16 startSize; /* Smallest size to correct--in ppem */
- HBUINT16 endSize; /* Largest size to correct--in ppem */
- HBUINT16 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
- */
- UnsizedArrayOf<HBUINT16>
- deltaValueZ; /* Array of compressed data */
- public:
- DEFINE_SIZE_ARRAY (6, deltaValueZ);
-};
-
-struct VariationDevice
-{
- friend struct Device;
-
- private:
-
- hb_position_t get_x_delta (hb_font_t *font,
- const VariationStore &store,
- VariationStore::cache_t *store_cache = nullptr) const
- { return font->em_scalef_x (get_delta (font, store, store_cache)); }
-
- hb_position_t get_y_delta (hb_font_t *font,
- const VariationStore &store,
- VariationStore::cache_t *store_cache = nullptr) const
- { return font->em_scalef_y (get_delta (font, store, store_cache)); }
-
- VariationDevice* copy (hb_serialize_context_t *c,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
- {
- TRACE_SERIALIZE (this);
- if (!layout_variation_idx_delta_map) return_trace (nullptr);
-
- hb_pair_t<unsigned, int> *v;
- if (!layout_variation_idx_delta_map->has (varIdx, &v))
- return_trace (nullptr);
-
- c->start_zerocopy (this->static_size);
- auto *out = c->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- unsigned new_idx = hb_first (*v);
- out->varIdx = new_idx;
- return_trace (out);
- }
-
- void collect_variation_index (hb_collect_variation_indices_context_t *c) const
- {
- c->layout_variation_indices->add (varIdx);
- int delta = 0;
- if (c->font && c->var_store)
- delta = roundf (get_delta (c->font, *c->var_store, c->store_cache));
-
- /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
- * varidx later*/
- c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- private:
-
- float get_delta (hb_font_t *font,
- const VariationStore &store,
- VariationStore::cache_t *store_cache = nullptr) const
- {
- return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache);
- }
-
- protected:
- VarIdx varIdx;
- HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct DeviceHeader
-{
- protected:
- HBUINT16 reserved1;
- HBUINT16 reserved2;
- public:
- HBUINT16 format; /* Format identifier */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct Device
-{
- hb_position_t get_x_delta (hb_font_t *font,
- const VariationStore &store=Null (VariationStore),
- VariationStore::cache_t *store_cache = nullptr) const
- {
- switch (u.b.format)
- {
-#ifndef HB_NO_HINTING
- case 1: case 2: case 3:
- return u.hinting.get_x_delta (font);
-#endif
-#ifndef HB_NO_VAR
- case 0x8000:
- return u.variation.get_x_delta (font, store, store_cache);
-#endif
- default:
- return 0;
- }
- }
- hb_position_t get_y_delta (hb_font_t *font,
- const VariationStore &store=Null (VariationStore),
- VariationStore::cache_t *store_cache = nullptr) const
- {
- switch (u.b.format)
- {
- case 1: case 2: case 3:
-#ifndef HB_NO_HINTING
- return u.hinting.get_y_delta (font);
-#endif
-#ifndef HB_NO_VAR
- case 0x8000:
- return u.variation.get_y_delta (font, store, store_cache);
-#endif
- default:
- return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.b.format.sanitize (c)) return_trace (false);
- switch (u.b.format) {
-#ifndef HB_NO_HINTING
- case 1: case 2: case 3:
- return_trace (u.hinting.sanitize (c));
-#endif
-#ifndef HB_NO_VAR
- case 0x8000:
- return_trace (u.variation.sanitize (c));
-#endif
- default:
- return_trace (true);
- }
- }
-
- Device* copy (hb_serialize_context_t *c,
- const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map=nullptr) const
- {
- TRACE_SERIALIZE (this);
- switch (u.b.format) {
-#ifndef HB_NO_HINTING
- case 1:
- case 2:
- case 3:
- return_trace (reinterpret_cast<Device *> (u.hinting.copy (c)));
-#endif
-#ifndef HB_NO_VAR
- case 0x8000:
- return_trace (reinterpret_cast<Device *> (u.variation.copy (c, layout_variation_idx_delta_map)));
-#endif
- default:
- return_trace (nullptr);
- }
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- {
- switch (u.b.format) {
-#ifndef HB_NO_HINTING
- case 1:
- case 2:
- case 3:
- return;
-#endif
-#ifndef HB_NO_VAR
- case 0x8000:
- u.variation.collect_variation_index (c);
- return;
-#endif
- default:
- return;
- }
- }
-
- unsigned get_variation_index () const
- {
- switch (u.b.format) {
-#ifndef HB_NO_VAR
- case 0x8000:
- return u.variation.varIdx;
-#endif
- default:
- return HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
- }
- }
-
- protected:
- union {
- DeviceHeader b;
- HintingDevice hinting;
-#ifndef HB_NO_VAR
- VariationDevice variation;
-#endif
- } u;
- public:
- DEFINE_SIZE_UNION (6, b);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_LAYOUT_COMMON_HH */
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 c8a2cf817a2..eed46dd6728 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
@@ -29,6 +29,431 @@
#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
#define HB_OT_LAYOUT_GDEF_TABLE_HH
-#include "OT/Layout/GDEF/GDEF.hh"
+#include "hb-ot-layout-common-private.hh"
+
+#include "hb-font-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * Attachment List Table
+ */
+
+typedef ArrayOf<UINT16> AttachPoint; /* Array of contour point indices--in
+ * increasing numerical order */
+
+struct AttachList
+{
+ inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (index == NOT_COVERED)
+ {
+ if (point_count)
+ *point_count = 0;
+ return 0;
+ }
+
+ const AttachPoint &points = this+attachPoint[index];
+
+ if (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];
+ }
+
+ return points.len;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table -- from
+ * beginning of AttachList table */
+ OffsetArrayOf<AttachPoint>
+ attachPoint; /* Array of AttachPoint tables
+ * in Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (4, attachPoint);
+};
+
+/*
+ * Ligature Caret Table
+ */
+
+struct CaretValueFormat1
+{
+ friend struct CaretValue;
+
+ private:
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
+ {
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ UINT16 caretValueFormat; /* Format identifier--format = 1 */
+ INT16 coordinate; /* X or Y value, in design units */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat2
+{
+ friend struct CaretValue;
+
+ private:
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+ {
+ hb_position_t x, y;
+ if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+ else
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ UINT16 caretValueFormat; /* Format identifier--format = 2 */
+ UINT16 caretValuePoint; /* Contour point index on glyph */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat3
+{
+ friend struct CaretValue;
+
+ inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, const VariationStore &var_store) const
+ {
+ return HB_DIRECTION_IS_HORIZONTAL (direction) ?
+ font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
+ font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+ }
+
+ protected:
+ 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
+ * table */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct CaretValue
+{
+ inline hb_position_t get_caret_value (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ const VariationStore &var_store) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_caret_value (font, direction);
+ case 2: return u.format2.get_caret_value (font, direction, glyph_id);
+ case 3: return u.format3.get_caret_value (font, direction, var_store);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ case 3: return_trace (u.format3.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ CaretValueFormat1 format1;
+ CaretValueFormat2 format2;
+ CaretValueFormat3 format3;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+struct LigGlyph
+{
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ const VariationStore &var_store,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ {
+ if (caret_count) {
+ const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
+ unsigned int count = *caret_count;
+ for (unsigned int i = 0; i < count; i++)
+ caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
+ }
+
+ return carets.len;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (carets.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<CaretValue>
+ carets; /* Offset array of CaretValue tables
+ * --from beginning of LigGlyph table
+ * --in increasing coordinate order */
+ public:
+ DEFINE_SIZE_ARRAY (2, carets);
+};
+
+struct LigCaretList
+{
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ const VariationStore &var_store,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (index == NOT_COVERED)
+ {
+ if (caret_count)
+ *caret_count = 0;
+ return 0;
+ }
+ const LigGlyph &lig_glyph = this+ligGlyph[index];
+ return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of LigCaretList table */
+ OffsetArrayOf<LigGlyph>
+ ligGlyph; /* Array of LigGlyph tables
+ * in Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (4, ligGlyph);
+};
+
+
+struct MarkGlyphSetsFormat1
+{
+ inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ ArrayOf<LOffsetTo<Coverage> >
+ coverage; /* Array of long offsets to mark set
+ * coverage tables */
+ public:
+ DEFINE_SIZE_ARRAY (4, coverage);
+};
+
+struct MarkGlyphSets
+{
+ inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.covers (set_index, glyph_id);
+ default:return false;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ MarkGlyphSetsFormat1 format1;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * GDEF -- The Glyph Definition Table
+ */
+
+struct GDEF
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_GDEF;
+
+ enum GlyphClasses {
+ UnclassifiedGlyph = 0,
+ BaseGlyph = 1,
+ LigatureGlyph = 2,
+ MarkGlyph = 3,
+ ComponentGlyph = 4
+ };
+
+ inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
+ inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
+ { return (this+glyphClassDef).get_class (glyph); }
+ inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+ { (this+glyphClassDef).add_class (glyphs, klass); }
+
+ inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
+ inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
+ { return (this+markAttachClassDef).get_class (glyph); }
+
+ inline bool has_attach_points (void) const { return attachList != 0; }
+ inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *point_count /* IN/OUT */,
+ unsigned int *point_array /* OUT */) const
+ { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
+
+ inline bool has_lig_carets (void) const { return ligCaretList != 0; }
+ inline unsigned int get_lig_carets (hb_font_t *font,
+ hb_direction_t direction,
+ hb_codepoint_t glyph_id,
+ unsigned int start_offset,
+ unsigned int *caret_count /* IN/OUT */,
+ hb_position_t *caret_array /* OUT */) const
+ { return (this+ligCaretList).get_lig_carets (font,
+ direction, glyph_id, get_var_store(),
+ start_offset, caret_count, caret_array); }
+
+ inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; }
+ inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+ { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); }
+
+ inline bool has_var_store (void) const { return version.to_int () >= 0x00010003u && varStore != 0; }
+ inline const VariationStore &get_var_store (void) const
+ { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ glyphClassDef.sanitize (c, this) &&
+ attachList.sanitize (c, this) &&
+ ligCaretList.sanitize (c, this) &&
+ markAttachClassDef.sanitize (c, this) &&
+ (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
+ (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
+ }
+
+ /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+ * glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
+ * Not to be confused with lookup_props which is very similar. */
+ inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
+ {
+ unsigned int klass = get_glyph_class (glyph);
+
+ 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;
+ case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+ case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+ case MarkGlyph:
+ klass = get_mark_attachment_type (glyph);
+ return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
+ }
+ }
+
+
+ protected:
+ FixedVersion<>version; /* Version of the GDEF table--currently
+ * 0x00010003u */
+ OffsetTo<ClassDef>
+ glyphClassDef; /* Offset to class definition table
+ * for glyph type--from beginning of
+ * GDEF header (may be Null) */
+ OffsetTo<AttachList>
+ attachList; /* Offset to list of glyphs with
+ * attachment points--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<LigCaretList>
+ ligCaretList; /* Offset to list of positioning points
+ * for ligature carets--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<ClassDef>
+ markAttachClassDef; /* Offset to class definition table for
+ * mark attachment type--from beginning
+ * of GDEF header (may be Null) */
+ OffsetTo<MarkGlyphSets>
+ markGlyphSetsDef; /* Offset to the table of mark set
+ * definitions--from beginning of GDEF
+ * header (may be NULL). Introduced
+ * in version 0x00010002. */
+ LOffsetTo<VariationStore>
+ varStore; /* Offset to the table of Item Variation
+ * Store--from beginning of GDEF
+ * header (may be NULL). Introduced
+ * in version 0x00010003. */
+ public:
+ DEFINE_SIZE_MIN (12);
+};
+
+
+} /* namespace OT */
+
#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
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 0cfa139a260..b344d793c7c 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
@@ -29,52 +29,1617 @@
#ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
#define HB_OT_LAYOUT_GPOS_TABLE_HH
-#include "OT/Layout/GPOS/GPOS.hh"
+#include "hb-ot-layout-gsubgpos-private.hh"
+
namespace OT {
-namespace Layout {
-namespace GPOS_impl {
-// TODO(garretrieger): Move into new layout directory.
-/* Out-of-class implementation for methods recursing */
-#ifndef HB_NO_OT_LAYOUT
-template <typename context_t>
-/*static*/ typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+
+/* buffer **position** var allocations */
+#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
+#define attach_type() var.u8[2] /* attachment type */
+/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
+
+enum attach_type_t {
+ ATTACH_TYPE_NONE = 0X00,
+
+ /* Each attachment should be either a mark or a cursive; can't be both. */
+ ATTACH_TYPE_MARK = 0X01,
+ ATTACH_TYPE_CURSIVE = 0X02,
+};
+
+
+/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
+
+typedef UINT16 Value;
+
+typedef Value ValueRecord[VAR];
+
+struct ValueFormat : UINT16
{
- const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
- return l.dispatch (c);
+ enum Flags {
+ xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
+ yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
+ xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
+ yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
+ xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
+ yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
+ xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
+ yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
+ ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
+ reserved = 0xF000u, /* For future use */
+
+ devices = 0x00F0u /* Mask for having any Device table */
+ };
+
+/* All fields are options. Only those available advance the value pointer. */
+#if 0
+ INT16 xPlacement; /* Horizontal adjustment for
+ * placement--in design units */
+ INT16 yPlacement; /* Vertical adjustment for
+ * placement--in design units */
+ INT16 xAdvance; /* Horizontal adjustment for
+ * advance--in design units (only used
+ * for horizontal writing) */
+ INT16 yAdvance; /* Vertical adjustment for advance--in
+ * design units (only used for vertical
+ * writing) */
+ Offset xPlaDevice; /* Offset to Device table for
+ * horizontal placement--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset yPlaDevice; /* Offset to Device table for vertical
+ * placement--measured from beginning
+ * of PosTable (may be NULL) */
+ Offset xAdvDevice; /* Offset to Device table for
+ * horizontal advance--measured from
+ * beginning of PosTable (may be NULL) */
+ Offset yAdvDevice; /* Offset to Device table for vertical
+ * advance--measured from beginning of
+ * PosTable (may be NULL) */
+#endif
+
+ inline unsigned int get_len (void) const
+ { return _hb_popcount32 ((unsigned int) *this); }
+ inline unsigned int get_size (void) const
+ { return get_len () * Value::static_size; }
+
+ void apply_value (hb_apply_context_t *c,
+ const void *base,
+ const Value *values,
+ hb_glyph_position_t &glyph_pos) const
+ {
+ unsigned int format = *this;
+ if (!format) return;
+
+ hb_font_t *font = c->font;
+ hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
+
+ if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
+ if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
+ if (format & xAdvance) {
+ if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
+ values++;
+ }
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (format & yAdvance) {
+ if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
+ values++;
+ }
+
+ if (!has_device ()) return;
+
+ bool use_x_device = font->x_ppem || font->num_coords;
+ bool use_y_device = font->y_ppem || font->num_coords;
+
+ if (!use_x_device && !use_y_device) return;
+
+ const VariationStore &store = c->var_store;
+
+ /* pixel -> fractional pixel */
+ if (format & xPlaDevice) {
+ if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font, store);
+ values++;
+ }
+ if (format & yPlaDevice) {
+ if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font, store);
+ values++;
+ }
+ if (format & xAdvDevice) {
+ if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store);
+ values++;
+ }
+ if (format & yAdvDevice) {
+ /* y_advance values grow downward but font-space grows upward, hence negation */
+ if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store);
+ values++;
+ }
+ }
+
+ private:
+ inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
+ {
+ unsigned int format = *this;
+
+ if (format & xPlacement) values++;
+ if (format & yPlacement) values++;
+ if (format & xAdvance) values++;
+ if (format & yAdvance) values++;
+
+ if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+ if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+
+ return true;
+ }
+
+ static inline OffsetTo<Device>& get_device (Value* value)
+ { return *CastP<OffsetTo<Device> > (value); }
+ static inline const OffsetTo<Device>& get_device (const Value* value)
+ { return *CastP<OffsetTo<Device> > (value); }
+
+ static inline const INT16& get_short (const Value* value)
+ { return *CastP<INT16> (value); }
+
+ public:
+
+ inline bool has_device (void) const {
+ unsigned int format = *this;
+ return (format & devices) != 0;
+ }
+
+ inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+ }
+
+ inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ unsigned int len = get_len ();
+
+ if (!c->check_array (values, get_size (), count)) return_trace (false);
+
+ if (!has_device ()) return_trace (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return_trace (false);
+ values += len;
+ }
+
+ return_trace (true);
+ }
+
+ /* Just sanitize referenced Device tables. Doesn't check the values themselves. */
+ inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (!has_device ()) return_trace (true);
+
+ for (unsigned int i = 0; i < count; i++) {
+ if (!sanitize_value_devices (c, base, values))
+ return_trace (false);
+ values += stride;
+ }
+
+ return_trace (true);
+ }
+};
+
+
+struct AnchorFormat1
+{
+ inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ hb_font_t *font = c->font;
+ *x = font->em_scale_x (xCoordinate);
+ *y = font->em_scale_y (yCoordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ 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);
+};
+
+struct AnchorFormat2
+{
+ inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ hb_font_t *font = c->font;
+ unsigned int x_ppem = font->x_ppem;
+ unsigned int y_ppem = font->y_ppem;
+ hb_position_t cx, cy;
+ hb_bool_t ret;
+
+ ret = (x_ppem || y_ppem) &&
+ font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+ *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
+ *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ 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);
+};
+
+struct AnchorFormat3
+{
+ inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ hb_font_t *font = c->font;
+ *x = font->em_scale_x (xCoordinate);
+ *y = font->em_scale_y (yCoordinate);
+
+ if (font->x_ppem || font->num_coords)
+ *x += (this+xDeviceTable).get_x_delta (font, c->var_store);
+ if (font->y_ppem || font->num_coords)
+ *y += (this+yDeviceTable).get_y_delta (font, c->var_store);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+ }
+
+ protected:
+ 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
+ * Anchor table (may be NULL) */
+ OffsetTo<Device>
+ yDeviceTable; /* Offset to Device table for Y
+ * coordinate-- from beginning of
+ * Anchor table (may be NULL) */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+struct Anchor
+{
+ inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
+ hb_position_t *x, hb_position_t *y) const
+ {
+ *x = *y = 0;
+ switch (u.format) {
+ case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
+ case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
+ case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
+ default: return;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ case 3: return_trace (u.format3.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ AnchorFormat1 format1;
+ AnchorFormat2 format2;
+ AnchorFormat3 format3;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+};
+
+
+struct AnchorMatrix
+{
+ inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const {
+ *found = false;
+ if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
+ *found = !matrixZ[row * cols + col].is_null ();
+ return this+matrixZ[row * cols + col];
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
+ {
+ TRACE_SANITIZE (this);
+ if (!c->check_struct (this)) return_trace (false);
+ if (unlikely (_hb_unsigned_int_mul_overflows (rows, cols))) return_trace (false);
+ unsigned int count = rows * cols;
+ if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (!matrixZ[i].sanitize (c, this)) return_trace (false);
+ return_trace (true);
+ }
+
+ UINT16 rows; /* Number of rows */
+ protected:
+ OffsetTo<Anchor>
+ matrixZ[VAR]; /* Matrix of offsets to Anchor tables--
+ * from beginning of AnchorMatrix table */
+ public:
+ DEFINE_SIZE_ARRAY (2, matrixZ);
+};
+
+
+struct MarkRecord
+{
+ friend struct MarkArray;
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
+ }
+
+ protected:
+ UINT16 klass; /* Class defined for this mark */
+ OffsetTo<Anchor>
+ markAnchor; /* Offset to Anchor table--from
+ * beginning of MarkArray table */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */
+{
+ inline bool apply (hb_apply_context_t *c,
+ unsigned int mark_index, unsigned int glyph_index,
+ const AnchorMatrix &anchors, unsigned int class_count,
+ unsigned int glyph_pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
+ unsigned int mark_class = record.klass;
+
+ const Anchor& mark_anchor = this + record.markAnchor;
+ bool found;
+ const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+ /* If this subtable doesn't have an anchor for this base and this class,
+ * return false such that the subsequent subtables have a chance at it. */
+ if (unlikely (!found)) return_trace (false);
+
+ 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);
+
+ hb_glyph_position_t &o = buffer->cur_pos();
+ o.x_offset = base_x - mark_x;
+ o.y_offset = base_y - mark_y;
+ o.attach_type() = ATTACH_TYPE_MARK;
+ o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (ArrayOf<MarkRecord>::sanitize (c, this));
+ }
+};
+
+
+/* Lookups */
+
+struct SinglePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ valueFormat.apply_value (c, this, values, buffer->cur_pos());
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ valueFormat.sanitize_value (c, this, values));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat; /* Defines the types of data in the
+ * ValueRecord */
+ ValueRecord values; /* Defines positioning
+ * value(s)--applied to all glyphs in
+ * the Coverage table */
+ public:
+ DEFINE_SIZE_ARRAY (6, values);
+};
+
+struct SinglePosFormat2
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ if (likely (index >= valueCount)) return_trace (false);
+
+ valueFormat.apply_value (c, this,
+ &values[index * valueFormat.get_len ()],
+ buffer->cur_pos());
+
+ buffer->idx++;
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ valueFormat.sanitize_values (c, this, values, valueCount));
+ }
+
+ protected:
+ 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 */
+ UINT16 valueCount; /* Number of ValueRecords */
+ ValueRecord values; /* Array of ValueRecords--positioning
+ * values applied to glyphs */
+ public:
+ DEFINE_SIZE_ARRAY (8, values);
+};
+
+struct SinglePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ case 2: return_trace (c->dispatch (u.format2));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ SinglePosFormat1 format1;
+ SinglePosFormat2 format2;
+ } u;
+};
+
+
+struct PairValueRecord
+{
+ friend struct PairSet;
+
+ protected:
+ GlyphID secondGlyph; /* GlyphID of second glyph in the
+ * pair--first glyph is listed in the
+ * Coverage table */
+ ValueRecord values; /* Positioning data for the first glyph
+ * followed by for second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (2, values);
+};
+
+struct PairSet
+{
+ friend struct PairPosFormat1;
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+ c->input->add_array (&record->secondGlyph, len, record_size);
+ }
+
+ inline bool apply (hb_apply_context_t *c,
+ const ValueFormat *valueFormats,
+ unsigned int pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
+ unsigned int count = len;
+
+ /* Hand-coded bsearch. */
+ if (unlikely (!count))
+ return_trace (false);
+ hb_codepoint_t x = buffer->info[pos].codepoint;
+ int min = 0, max = (int) count - 1;
+ while (min <= max)
+ {
+ int mid = (min + max) / 2;
+ const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid);
+ hb_codepoint_t mid_x = record->secondGlyph;
+ if (x < mid_x)
+ max = mid - 1;
+ else if (x > mid_x)
+ 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)
+ pos++;
+ buffer->idx = pos;
+ return_trace (true);
+ }
+ }
+
+ return_trace (false);
+ }
+
+ struct sanitize_closure_t {
+ const void *base;
+ const ValueFormat *valueFormats;
+ unsigned int len1; /* valueFormats[0].get_len() */
+ unsigned int stride; /* 1 + len1 + len2 */
+ };
+
+ inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && c->check_array (arrayZ, UINT16::static_size * closure->stride, len))) return_trace (false);
+
+ unsigned int count = len;
+ const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+ return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) &&
+ closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
+ }
+
+ protected:
+ UINT16 len; /* Number of PairValueRecords */
+ UINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered
+ * by GlyphID of the second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (2, arrayZ);
+};
+
+struct PairPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ if (!skippy_iter.next ()) return_trace (false);
+
+ return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (!c->check_struct (this)) return_trace (false);
+
+ unsigned int len1 = valueFormat[0].get_len ();
+ unsigned int len2 = valueFormat[1].get_len ();
+ PairSet::sanitize_closure_t closure = {
+ this,
+ valueFormat,
+ len1,
+ 1 + len1 + len2
+ };
+
+ return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat[2]; /* [0] Defines the types of data in
+ * ValueRecord1--for the first glyph
+ * in the pair--may be zero (0) */
+ /* [1] Defines the types of data in
+ * ValueRecord2--for the second glyph
+ * in the pair--may be zero (0) */
+ OffsetArrayOf<PairSet>
+ pairSet; /* Array of PairSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (10, pairSet);
+};
+
+struct PairPosFormat2
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ if (!skippy_iter.next ()) return_trace (false);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int record_len = len1 + len2;
+
+ unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+ 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]);
+
+ buffer->idx = skippy_iter.idx;
+ if (len2)
+ buffer->idx++;
+
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && coverage.sanitize (c, this)
+ && classDef1.sanitize (c, this)
+ && classDef2.sanitize (c, this))) return_trace (false);
+
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int stride = len1 + len2;
+ unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
+ unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
+ return_trace (c->check_array (values, record_size, count) &&
+ valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+ valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ValueFormat valueFormat1; /* ValueRecord definition--for the
+ * first glyph of the pair--may be zero
+ * (0) */
+ ValueFormat valueFormat2; /* ValueRecord definition--for the
+ * second glyph of the pair--may be
+ * zero (0) */
+ OffsetTo<ClassDef>
+ classDef1; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the first glyph of the pair */
+ OffsetTo<ClassDef>
+ classDef2; /* Offset to ClassDef table--from
+ * beginning of PairPos subtable--for
+ * the second glyph of the pair */
+ UINT16 class1Count; /* Number of classes in ClassDef1
+ * table--includes Class0 */
+ UINT16 class2Count; /* Number of classes in ClassDef2
+ * table--includes Class0 */
+ ValueRecord values; /* Matrix of value pairs:
+ * class1-major, class2-minor,
+ * Each entry has value1 and value2 */
+ public:
+ DEFINE_SIZE_ARRAY (16, values);
+};
+
+struct PairPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ case 2: return_trace (c->dispatch (u.format2));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ PairPosFormat1 format1;
+ PairPosFormat2 format2;
+ } u;
+};
+
+
+struct EntryExitRecord
+{
+ friend struct CursivePosFormat1;
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
+ }
+
+ protected:
+ OffsetTo<Anchor>
+ entryAnchor; /* Offset to EntryAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ OffsetTo<Anchor>
+ exitAnchor; /* Offset to ExitAnchor table--from
+ * beginning of CursivePos
+ * subtable--may be NULL */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent);
+
+struct CursivePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
+ if (!this_record.exitAnchor) return_trace (false);
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ if (!skippy_iter.next ()) return_trace (false);
+
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
+ if (!next_record.entryAnchor) return_trace (false);
+
+ 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);
+
+ hb_glyph_position_t *pos = buffer->pos;
+
+ hb_position_t d;
+ /* Main-direction adjustment */
+ switch (c->direction) {
+ case HB_DIRECTION_LTR:
+ pos[i].x_advance = exit_x + pos[i].x_offset;
+
+ d = entry_x + pos[j].x_offset;
+ pos[j].x_advance -= d;
+ pos[j].x_offset -= d;
+ break;
+ case HB_DIRECTION_RTL:
+ d = exit_x + pos[i].x_offset;
+ pos[i].x_advance -= d;
+ pos[i].x_offset -= d;
+
+ pos[j].x_advance = entry_x + pos[j].x_offset;
+ break;
+ case HB_DIRECTION_TTB:
+ pos[i].y_advance = exit_y + pos[i].y_offset;
+
+ d = entry_y + pos[j].y_offset;
+ pos[j].y_advance -= d;
+ pos[j].y_offset -= d;
+ break;
+ case HB_DIRECTION_BTT:
+ d = exit_y + pos[i].y_offset;
+ pos[i].y_advance -= d;
+ pos[i].y_offset -= d;
+
+ pos[j].y_advance = entry_y;
+ break;
+ case HB_DIRECTION_INVALID:
+ default:
+ break;
+ }
+
+ /* Cross-direction adjustment */
+
+ /* We attach child to parent (think graph theory and rooted trees whereas
+ * the root stays on baseline and each node aligns itself against its
+ * parent.
+ *
+ * Optimize things for the case of RightToLeft, as that's most common in
+ * Arabinc. */
+ unsigned int child = i;
+ unsigned int parent = j;
+ hb_position_t x_offset = entry_x - exit_x;
+ hb_position_t y_offset = entry_y - exit_y;
+ if (!(c->lookup_props & LookupFlag::RightToLeft))
+ {
+ unsigned int k = child;
+ child = parent;
+ parent = k;
+ x_offset = -x_offset;
+ y_offset = -y_offset;
+ }
+
+ /* If child was already connected to someone else, walk through its old
+ * chain and reverse the link direction, such that the whole tree of its
+ * previous connection now attaches to new parent. Watch out for case
+ * where new parent is on the path from old chain...
+ */
+ reverse_cursive_minor_offset (pos, child, c->direction, parent);
+
+ pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
+ pos[child].attach_chain() = (int) parent - (int) child;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[child].y_offset = y_offset;
+ else
+ pos[child].x_offset = x_offset;
+
+ buffer->idx = j;
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of subtable */
+ ArrayOf<EntryExitRecord>
+ entryExitRecord; /* Array of EntryExit records--in
+ * Coverage Index order */
+ public:
+ DEFINE_SIZE_ARRAY (6, entryExitRecord);
+};
+
+struct CursivePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ CursivePosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix BaseArray; /* base-major--
+ * in order of BaseCoverage Index--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+struct MarkBasePosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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
+ {
+ return this+markCoverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+ /* Now we search backwards for a non-mark glyph */
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+ do {
+ if (!skippy_iter.prev ()) return_trace (false);
+ /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
+ 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);
+
+ /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+ //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+
+ unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint);
+ if (base_index == NOT_COVERED) return_trace (false);
+
+ return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ markCoverage.sanitize (c, this) &&
+ baseCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) &&
+ baseArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ 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 */
+ UINT16 classCount; /* Number of classes defined for marks */
+ OffsetTo<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkBasePos subtable */
+ OffsetTo<BaseArray>
+ baseArray; /* Offset to BaseArray table--from
+ * beginning of MarkBasePos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkBasePos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ MarkBasePosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix LigatureAttach; /* component-major--
+ * in order of writing direction--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+typedef OffsetListOf<LigatureAttach> LigatureArray;
+ /* Array of LigatureAttach
+ * tables ordered by
+ * LigatureCoverage Index */
+
+struct MarkLigPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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
+ {
+ return this+markCoverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+ /* Now we search backwards for a non-mark glyph */
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+ if (!skippy_iter.prev ()) return_trace (false);
+
+ /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+ //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+
+ unsigned int j = skippy_iter.idx;
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
+ if (lig_index == NOT_COVERED) return_trace (false);
+
+ const LigatureArray& lig_array = this+ligatureArray;
+ const LigatureAttach& lig_attach = lig_array[lig_index];
+
+ /* Find component to attach to */
+ unsigned int comp_count = lig_attach.rows;
+ if (unlikely (!comp_count)) return_trace (false);
+
+ /* We must now check whether the ligature ID of the current mark glyph
+ * is identical to the ligature ID of the found ligature. If yes, we
+ * can directly use the component index. If not, we attach the mark
+ * glyph to the last component of the ligature. */
+ unsigned int comp_index;
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ if (lig_id && lig_id == mark_id && mark_comp > 0)
+ comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+ else
+ comp_index = comp_count - 1;
+
+ return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ markCoverage.sanitize (c, this) &&
+ ligatureCoverage.sanitize (c, this) &&
+ markArray.sanitize (c, this) &&
+ ligatureArray.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ markCoverage; /* Offset to Mark Coverage table--from
+ * beginning of MarkLigPos subtable */
+ OffsetTo<Coverage>
+ ligatureCoverage; /* Offset to Ligature Coverage
+ * table--from beginning of MarkLigPos
+ * subtable */
+ UINT16 classCount; /* Number of defined mark classes */
+ OffsetTo<MarkArray>
+ markArray; /* Offset to MarkArray table--from
+ * beginning of MarkLigPos subtable */
+ OffsetTo<LigatureArray>
+ ligatureArray; /* Offset to LigatureArray table--from
+ * beginning of MarkLigPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkLigPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ MarkLigPosFormat1 format1;
+ } u;
+};
+
+
+typedef AnchorMatrix Mark2Array; /* mark2-major--
+ * in order of Mark2Coverage Index--,
+ * mark1-minor--
+ * ordered by class--zero-based. */
+
+struct MarkMarkPosFormat1
+{
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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
+ {
+ return this+mark1Coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
+ if (likely (mark1_index == NOT_COVERED)) return_trace (false);
+
+ /* now we search backwards for a suitable mark glyph until a non-mark glyph */
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+ if (!skippy_iter.prev ()) return_trace (false);
+
+ if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+
+ unsigned int j = skippy_iter.idx;
+
+ unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
+
+ if (likely (id1 == id2)) {
+ if (id1 == 0) /* Marks belonging to the same base. */
+ goto good;
+ else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
+ goto good;
+ } else {
+ /* If ligature ids don't match, it may be the case that one of the marks
+ * itself is a ligature. In which case match. */
+ if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+ goto good;
+ }
+
+ /* Didn't match. */
+ return_trace (false);
+
+ good:
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
+ if (mark2_index == NOT_COVERED) return_trace (false);
+
+ return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mark1Coverage.sanitize (c, this) &&
+ mark2Coverage.sanitize (c, this) &&
+ mark1Array.sanitize (c, this) &&
+ mark2Array.sanitize (c, this, (unsigned int) classCount));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ mark1Coverage; /* Offset to Combining Mark1 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ OffsetTo<Coverage>
+ mark2Coverage; /* Offset to Combining Mark2 Coverage
+ * table--from beginning of MarkMarkPos
+ * subtable */
+ UINT16 classCount; /* Number of defined mark classes */
+ OffsetTo<MarkArray>
+ mark1Array; /* Offset to Mark1Array table--from
+ * beginning of MarkMarkPos subtable */
+ OffsetTo<Mark2Array>
+ mark2Array; /* Offset to Mark2Array table--from
+ * beginning of MarkMarkPos subtable */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkMarkPos
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ MarkMarkPosFormat1 format1;
+ } u;
+};
+
+
+struct ContextPos : Context {};
+
+struct ChainContextPos : ChainContext {};
+
+struct ExtensionPos : Extension<ExtensionPos>
+{
+ typedef struct PosLookupSubTable LookupSubTable;
+};
+
+
+
+/*
+ * PosLookup
+ */
+
+
+struct PosLookupSubTable
+{
+ friend struct PosLookup;
+
+ enum Type {
+ Single = 1,
+ Pair = 2,
+ Cursive = 3,
+ MarkBase = 4,
+ MarkLig = 5,
+ MarkMark = 6,
+ Context = 7,
+ ChainContext = 8,
+ Extension = 9
+ };
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+ {
+ TRACE_DISPATCH (this, lookup_type);
+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
+ switch (lookup_type) {
+ case Single: return_trace (u.single.dispatch (c));
+ case Pair: return_trace (u.pair.dispatch (c));
+ case Cursive: return_trace (u.cursive.dispatch (c));
+ case MarkBase: return_trace (u.markBase.dispatch (c));
+ case MarkLig: return_trace (u.markLig.dispatch (c));
+ case MarkMark: return_trace (u.markMark.dispatch (c));
+ case Context: return_trace (u.context.dispatch (c));
+ case ChainContext: return_trace (u.chainContext.dispatch (c));
+ case Extension: return_trace (u.extension.dispatch (c));
+ default: return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 sub_format;
+ SinglePos single;
+ PairPos pair;
+ CursivePos cursive;
+ MarkBasePos markBase;
+ MarkLigPos markLig;
+ MarkMarkPos markMark;
+ ContextPos context;
+ ChainContextPos chainContext;
+ ExtensionPos extension;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, sub_format);
+};
+
+
+struct PosLookup : Lookup
+{
+ inline const PosLookupSubTable& get_subtable (unsigned int i) const
+ { return Lookup::get_subtable<PosLookupSubTable> (i); }
+
+ inline bool is_reverse (void) const
+ {
+ return false;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ return_trace (dispatch (c));
+ }
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ return_trace (dispatch (c));
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const
+ {
+ hb_add_coverage_context_t<set_t> c (glyphs);
+ dispatch (&c);
+ }
+
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ { return Lookup::dispatch<PosLookupSubTable> (c); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!Lookup::sanitize (c))) return_trace (false);
+ return_trace (dispatch (c));
+ }
+};
+
+typedef OffsetListOf<PosLookup> PosLookupList;
+
+/*
+ * GPOS -- The Glyph Positioning Table
+ */
+
+struct GPOS : GSUBGPOS
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_GPOS;
+
+ inline const PosLookup& get_lookup (unsigned int i) const
+ { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
+ static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
+ const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
+ return_trace (list.sanitize (c, this));
+ }
+};
+
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent)
+{
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+ if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
+ return;
+
+ pos[i].attach_chain() = 0;
+
+ unsigned int j = (int) i + chain;
+
+ /* Stop if we see new parent in the chain. */
+ if (j == new_parent)
+ return;
+
+ reverse_cursive_minor_offset (pos, j, direction, new_parent);
+
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[j].y_offset = -pos[i].y_offset;
+ else
+ pos[j].x_offset = -pos[i].x_offset;
+
+ pos[j].attach_chain() = -chain;
+ pos[j].attach_type() = type;
}
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+{
+ /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
+ * offset of glyph they are attached to. */
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+ if (likely (!chain))
+ return;
+
+ unsigned int j = (int) i + chain;
+
+ pos[i].attach_chain() = 0;
-template <>
-inline hb_closure_lookups_context_t::return_t
-PosLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index)
+ propagate_attachment_offsets (pos, j, direction);
+
+ assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE));
+
+ if (type & ATTACH_TYPE_CURSIVE)
+ {
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[i].y_offset += pos[j].y_offset;
+ else
+ pos[i].x_offset += pos[j].x_offset;
+ }
+ else /*if (type & ATTACH_TYPE_MARK)*/
+ {
+ pos[i].x_offset += pos[j].x_offset;
+ pos[i].y_offset += pos[j].y_offset;
+
+ assert (j < i);
+ if (HB_DIRECTION_IS_FORWARD (direction))
+ for (unsigned int k = j; k < i; k++) {
+ pos[i].x_offset -= pos[k].x_advance;
+ pos[i].y_offset -= pos[k].y_advance;
+ }
+ else
+ for (unsigned int k = j + 1; k < i + 1; k++) {
+ pos[i].x_offset += pos[k].x_advance;
+ pos[i].y_offset += pos[k].y_advance;
+ }
+ }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
{
- const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (this_index);
- return l.closure_lookups (c, this_index);
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
}
-template <>
-inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
+void
+GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
{
- auto *gpos = c->face->table.GPOS.get_relaxed ();
- const PosLookup &l = gpos->table->get_lookup (lookup_index);
+ //_hb_buffer_assert_gsubgpos_vars (buffer);
+}
+
+void
+GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+ _hb_buffer_assert_gsubgpos_vars (buffer);
+
+ unsigned int len;
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+ hb_direction_t direction = buffer->props.direction;
+
+ /* Handle attachments */
+ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
+ for (unsigned int i = 0; i < len; i++)
+ propagate_attachment_offsets (pos, i, direction);
+}
+
+
+/* Out-of-class implementation for methods recursing */
+
+template <typename context_t>
+/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+{
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
+ return l.dispatch (c);
+}
+
+/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
+{
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
unsigned int saved_lookup_index = c->lookup_index;
c->set_lookup_index (lookup_index);
c->set_lookup_props (l.get_props ());
-
- bool ret = false;
- auto *accel = gpos->get_accel (lookup_index);
- ret = accel && accel->apply (c, l.get_subtable_count (), false);
-
+ bool ret = l.dispatch (c);
c->set_lookup_index (saved_lookup_index);
c->set_lookup_props (saved_lookup_props);
return ret;
}
-#endif
-} /* namespace GPOS_impl */
-} /* namespace Layout */
+
+#undef attach_chain
+#undef attach_type
+
+
} /* namespace OT */
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 fd8a68be02d..0b09c4e4a1a 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
@@ -29,65 +29,1336 @@
#ifndef HB_OT_LAYOUT_GSUB_TABLE_HH
#define HB_OT_LAYOUT_GSUB_TABLE_HH
-#include "OT/Layout/GSUB/GSUB.hh"
+#include "hb-ot-layout-gsubgpos-private.hh"
+
namespace OT {
-namespace Layout {
-namespace GSUB_impl {
-// TODO(garretrieger): Move into the new layout directory.
-/* Out-of-class implementation for methods recursing */
-#ifndef HB_NO_OT_LAYOUT
-/*static*/ inline bool ExtensionSubst::is_reverse () const
+struct SingleSubstFormat1
{
- return SubstLookup::lookup_type_is_reverse (get_type ());
-}
-template <typename context_t>
-/*static*/ typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ 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/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);
+ }
+ }
+
+ 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/harfbuzz/harfbuzz/issues/363 */
+ hb_codepoint_t glyph_id = iter.get_glyph ();
+ c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ /* According to the Adobe Annotated OpenType Suite, result is always
+ * limited to 16bit. */
+ glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
+ c->replace_glyph (glyph_id);
+
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs,
+ int delta)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+ deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ INT16 deltaGlyphID; /* Add to original GlyphID to get
+ * substitute GlyphID */
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct SingleSubstFormat2
{
- const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
- return l.dispatch (c);
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ 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/harfbuzz/harfbuzz/issues/363 */
+ if (c->glyphs->has (iter.get_glyph ()))
+ c->glyphs->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ 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/harfbuzz/harfbuzz/issues/363 */
+ c->output->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ if (unlikely (index >= substitute.len)) return_trace (false);
+
+ glyph_id = substitute[index];
+ c->replace_glyph (glyph_id);
+
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return_trace (false);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ ArrayOf<GlyphID>
+ substitute; /* Array of substitute
+ * GlyphIDs--ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, substitute);
+};
+
+struct SingleSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return_trace (false);
+ unsigned int format = 2;
+ int delta = 0;
+ if (num_glyphs) {
+ format = 1;
+ /* TODO(serialize) check for wrap-around */
+ delta = substitutes[0] - glyphs[0];
+ for (unsigned int i = 1; i < num_glyphs; i++)
+ if (delta != substitutes[i] - glyphs[i]) {
+ format = 2;
+ break;
+ }
+ }
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs, delta));
+ case 2: return_trace (u.format2.serialize (c, glyphs, substitutes, num_glyphs));
+ default:return_trace (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ case 2: return_trace (c->dispatch (u.format2));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ SingleSubstFormat1 format1;
+ SingleSubstFormat2 format2;
+ } u;
+};
+
+
+struct Sequence
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int count = substitute.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->glyphs->add (substitute[i]);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->output->add_array (substitute.array, substitute.len);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int count = substitute.len;
+
+ /* Special-case to make it in-place and not consider this
+ * as a "multiplied" substitution. */
+ if (unlikely (count == 1))
+ {
+ c->replace_glyph (substitute.array[0]);
+ return_trace (true);
+ }
+ /* Spec disallows this, but Uniscribe allows it.
+ * https://github.com/harfbuzz/harfbuzz/issues/253 */
+ else if (unlikely (count == 0))
+ {
+ c->buffer->delete_glyph ();
+ return_trace (true);
+ }
+
+ unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+
+ for (unsigned int i = 0; i < count; i++) {
+ _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
+ c->output_glyph_for_component (substitute.array[i], klass);
+ }
+ c->buffer->skip_glyph ();
+
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (substitute.sanitize (c));
+ }
+
+ protected:
+ ArrayOf<GlyphID>
+ substitute; /* String of GlyphIDs to substitute */
+ public:
+ DEFINE_SIZE_ARRAY (2, substitute);
+};
+
+struct MultipleSubstFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ Coverage::Iter iter;
+ unsigned int count = sequence.len;
+ for (iter.init (this+coverage); iter.more (); iter.next ())
+ {
+ if (unlikely (iter.get_coverage () >= count))
+ 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);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ return_trace ((this+sequence[index]).apply (c));
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!sequence.serialize (c, num_glyphs))) return_trace (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ if (unlikely (!sequence[i].serialize (c, this).serialize (c,
+ substitute_glyphs_list,
+ substitute_len_list[i]))) return_trace (false);
+ substitute_len_list.advance (num_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<Sequence>
+ sequence; /* Array of Sequence tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, sequence);
+};
+
+struct MultipleSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return_trace (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list));
+ default:return_trace (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ MultipleSubstFormat1 format1;
+ } u;
+};
+
+
+typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
+ * arbitrary order */
+
+struct AlternateSubstFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ 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/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;
+ for (unsigned int i = 0; i < count; i++)
+ c->glyphs->add (alt_set[i]);
+ }
+ }
+ }
+
+ 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/harfbuzz/harfbuzz/issues/363 */
+ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
+ c->output->add_array (alt_set.array, alt_set.len);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const AlternateSet &alt_set = this+alternateSet[index];
+
+ if (unlikely (!alt_set.len)) return_trace (false);
+
+ hb_mask_t glyph_mask = c->buffer->cur().mask;
+ hb_mask_t lookup_mask = c->lookup_mask;
+
+ /* Note: This breaks badly if two features enabled this lookup together. */
+ unsigned int shift = _hb_ctz (lookup_mask);
+ unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
+
+ if (unlikely (alt_index > alt_set.len || alt_index == 0)) return_trace (false);
+
+ glyph_id = alt_set[alt_index - 1];
+
+ c->replace_glyph (glyph_id);
+
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!alternateSet.serialize (c, num_glyphs))) return_trace (false);
+ for (unsigned int i = 0; i < num_glyphs; i++)
+ if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
+ alternate_glyphs_list,
+ alternate_len_list[i]))) return_trace (false);
+ alternate_len_list.advance (num_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<AlternateSet>
+ alternateSet; /* Array of AlternateSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, alternateSet);
+};
+
+struct AlternateSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return_trace (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list));
+ default:return_trace (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ AlternateSubstFormat1 format1;
+ } u;
+};
+
+
+struct Ligature
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int count = component.len;
+ for (unsigned int i = 1; i < count; i++)
+ if (!c->glyphs->has (component[i]))
+ return;
+ c->glyphs->add (ligGlyph);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->input->add_array (component.array, component.len ? component.len - 1 : 0);
+ c->output->add (ligGlyph);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ if (c->len != component.len)
+ return_trace (false);
+
+ for (unsigned int i = 1; i < c->len; i++)
+ if (likely (c->glyphs[i] != component[i]))
+ return_trace (false);
+
+ return_trace (true);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int count = component.len;
+
+ if (unlikely (!count)) return_trace (false);
+
+ /* Special-case to make it in-place and not consider this
+ * as a "ligated" substitution. */
+ if (unlikely (count == 1))
+ {
+ c->replace_glyph (ligGlyph);
+ return_trace (true);
+ }
+
+ bool is_mark_ligature = false;
+ unsigned int total_component_count = 0;
+
+ unsigned int match_length = 0;
+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+
+ if (likely (!match_input (c, count,
+ &component[1],
+ match_glyph,
+ nullptr,
+ &match_length,
+ match_positions,
+ &is_mark_ligature,
+ &total_component_count)))
+ return_trace (false);
+
+ ligate_input (c,
+ count,
+ match_positions,
+ match_length,
+ ligGlyph,
+ is_mark_ligature,
+ total_component_count);
+
+ return_trace (true);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ GlyphID ligature,
+ Supplier<GlyphID> &components, /* Starting from second */
+ unsigned int num_components /* Including first component */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ ligGlyph = ligature;
+ if (unlikely (!component.serialize (c, components, num_components))) return_trace (false);
+ return_trace (true);
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
+ }
+
+ protected:
+ GlyphID ligGlyph; /* GlyphID of ligature to substitute */
+ HeadlessArrayOf<GlyphID>
+ component; /* Array of component GlyphIDs--start
+ * with the second component--ordered
+ * in writing direction */
+ public:
+ DEFINE_SIZE_ARRAY (4, component);
+};
+
+struct LigatureSet
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ (this+ligature[i]).closure (c);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ (this+ligature[i]).collect_glyphs (c);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const Ligature &lig = this+ligature[i];
+ if (lig.would_apply (c))
+ return_trace (true);
+ }
+ return_trace (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const Ligature &lig = this+ligature[i];
+ if (lig.apply (c)) return_trace (true);
+ }
+
+ return_trace (false);
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &ligatures,
+ Supplier<unsigned int> &component_count_list,
+ unsigned int num_ligatures,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!ligature.serialize (c, num_ligatures))) return_trace (false);
+ for (unsigned int i = 0; i < num_ligatures; i++)
+ if (unlikely (!ligature[i].serialize (c, this).serialize (c,
+ ligatures[i],
+ component_list,
+ component_count_list[i]))) return_trace (false);
+ ligatures.advance (num_ligatures);
+ component_count_list.advance (num_ligatures);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (ligature.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<Ligature>
+ ligature; /* Array LigatureSet tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, ligature);
+};
+
+struct LigatureSubstFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ 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/harfbuzz/harfbuzz/issues/363 */
+ if (c->glyphs->has (iter.get_glyph ()))
+ (this+ligatureSet[iter.get_coverage ()]).closure (c);
+ }
+ }
+
+ 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/harfbuzz/harfbuzz/issues/363 */
+ (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
+ }
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const LigatureSet &lig_set = this+ligatureSet[index];
+ return_trace (lig_set.would_apply (c));
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const LigatureSet &lig_set = this+ligatureSet[index];
+ return_trace (lig_set.apply (c));
+ }
+
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return_trace (false);
+ for (unsigned int i = 0; i < num_first_glyphs; i++)
+ if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
+ ligatures_list,
+ component_count_list,
+ ligature_per_first_glyph_count_list[i],
+ component_list))) return_trace (false);
+ ligature_per_first_glyph_count_list.advance (num_first_glyphs);
+ if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ OffsetArrayOf<LigatureSet>
+ ligatureSet; /* Array LigatureSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ligatureSet);
+};
+
+struct LigatureSubst
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (u.format))) return_trace (false);
+ unsigned int format = 1;
+ u.format.set (format);
+ switch (u.format) {
+ case 1: return_trace (u.format1.serialize (c,
+ first_glyphs,
+ ligature_per_first_glyph_count_list,
+ num_first_glyphs,
+ ligatures_list,
+ component_count_list,
+ component_list));
+ default:return_trace (false);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ LigatureSubstFormat1 format1;
+ } u;
+};
+
+
+struct ContextSubst : Context {};
+
+struct ChainContextSubst : ChainContext {};
+
+struct ExtensionSubst : Extension<ExtensionSubst>
+{
+ typedef struct SubstLookupSubTable LookupSubTable;
+
+ inline bool is_reverse (void) const;
+};
+
+
+struct ReverseChainSingleSubstFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int count;
+
+ count = backtrack.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+backtrack[i]).intersects (c->glyphs))
+ return;
+
+ count = lookahead.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+lookahead[i]).intersects (c->glyphs))
+ return;
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ Coverage::Iter iter;
+ 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/harfbuzz/harfbuzz/issues/363 */
+ if (c->glyphs->has (iter.get_glyph ()))
+ c->glyphs->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+
+ unsigned int count;
+
+ count = backtrack.len;
+ for (unsigned int i = 0; i < count; i++)
+ 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++)
+ if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ count = substitute.len;
+ c->output->add_array (substitute.array, substitute.len);
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
+ return_trace (false); /* No chaining to this type */
+
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ 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, (UINT16 *) backtrack.array,
+ match_coverage, this,
+ &start_index) &&
+ match_lookahead (c,
+ lookahead.len, (UINT16 *) lookahead.array,
+ match_coverage, this,
+ 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
+ * calls us through a Context lookup. */
+ return_trace (true);
+ }
+
+ return_trace (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
+ return_trace (false);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (!lookahead.sanitize (c, this))
+ return_trace (false);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ return_trace (substitute.sanitize (c));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<Coverage>
+ backtrack; /* Array of coverage tables
+ * in backtracking sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ lookaheadX; /* Array of coverage tables
+ * in lookahead sequence, in glyph
+ * sequence order */
+ ArrayOf<GlyphID>
+ substituteX; /* Array of substitute
+ * GlyphIDs--ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_MIN (10);
+};
+
+struct ReverseChainSingleSubst
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ReverseChainSingleSubstFormat1 format1;
+ } u;
+};
+
+
+
+/*
+ * SubstLookup
+ */
+
+struct SubstLookupSubTable
+{
+ friend struct SubstLookup;
+
+ enum Type {
+ Single = 1,
+ Multiple = 2,
+ Alternate = 3,
+ Ligature = 4,
+ Context = 5,
+ ChainContext = 6,
+ Extension = 7,
+ ReverseChainSingle = 8
+ };
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+ {
+ TRACE_DISPATCH (this, lookup_type);
+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
+ switch (lookup_type) {
+ case Single: return_trace (u.single.dispatch (c));
+ case Multiple: return_trace (u.multiple.dispatch (c));
+ case Alternate: return_trace (u.alternate.dispatch (c));
+ case Ligature: return_trace (u.ligature.dispatch (c));
+ case Context: return_trace (u.context.dispatch (c));
+ case ChainContext: return_trace (u.chainContext.dispatch (c));
+ case Extension: return_trace (u.extension.dispatch (c));
+ case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c));
+ default: return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 sub_format;
+ SingleSubst single;
+ MultipleSubst multiple;
+ AlternateSubst alternate;
+ LigatureSubst ligature;
+ ContextSubst context;
+ ChainContextSubst chainContext;
+ ExtensionSubst extension;
+ ReverseChainSingleSubst reverseChainContextSingle;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, sub_format);
+};
+
+
+struct SubstLookup : Lookup
+{
+ inline const SubstLookupSubTable& get_subtable (unsigned int i) const
+ { return Lookup::get_subtable<SubstLookupSubTable> (i); }
+
+ inline static bool lookup_type_is_reverse (unsigned int lookup_type)
+ { return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
+
+ inline bool is_reverse (void) const
+ {
+ unsigned int type = get_type ();
+ if (unlikely (type == SubstLookupSubTable::Extension))
+ return CastR<ExtensionSubst> (get_subtable(0)).is_reverse ();
+ return lookup_type_is_reverse (type);
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ return_trace (dispatch (c));
+ }
+
+ inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>);
+ return_trace (dispatch (c));
+ }
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
+ return_trace (dispatch (c));
+ }
+
+ template <typename set_t>
+ inline void add_coverage (set_t *glyphs) const
+ {
+ hb_add_coverage_context_t<set_t> c (glyphs);
+ dispatch (&c);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c,
+ const hb_ot_layout_lookup_accelerator_t *accel) const
+ {
+ TRACE_WOULD_APPLY (this);
+ if (unlikely (!c->len)) return_trace (false);
+ if (!accel->may_have (c->glyphs[0])) return_trace (false);
+ return_trace (dispatch (c));
+ }
+
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+ inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
+ unsigned int i)
+ { return get_subtables<SubstLookupSubTable> ()[i].serialize (c, this); }
+
+ inline bool serialize_single (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<GlyphID> &substitutes,
+ unsigned int num_glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return_trace (false);
+ return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
+ }
+
+ inline bool serialize_multiple (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &substitute_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &substitute_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return_trace (false);
+ return_trace (serialize_subtable (c, 0).u.multiple.serialize (c,
+ glyphs,
+ substitute_len_list,
+ num_glyphs,
+ substitute_glyphs_list));
+ }
+
+ inline bool serialize_alternate (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &glyphs,
+ Supplier<unsigned int> &alternate_len_list,
+ unsigned int num_glyphs,
+ Supplier<GlyphID> &alternate_glyphs_list)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return_trace (false);
+ return_trace (serialize_subtable (c, 0).u.alternate.serialize (c,
+ glyphs,
+ alternate_len_list,
+ num_glyphs,
+ alternate_glyphs_list));
+ }
+
+ inline bool serialize_ligature (hb_serialize_context_t *c,
+ uint32_t lookup_props,
+ Supplier<GlyphID> &first_glyphs,
+ Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+ unsigned int num_first_glyphs,
+ Supplier<GlyphID> &ligatures_list,
+ Supplier<unsigned int> &component_count_list,
+ Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return_trace (false);
+ return_trace (serialize_subtable (c, 0).u.ligature.serialize (c,
+ first_glyphs,
+ ligature_per_first_glyph_count_list,
+ num_first_glyphs,
+ ligatures_list,
+ component_count_list,
+ component_list));
+ }
+
+ template <typename context_t>
+ static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ { return Lookup::dispatch<SubstLookupSubTable> (c); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!Lookup::sanitize (c))) return_trace (false);
+ if (unlikely (!dispatch (c))) return_trace (false);
+
+ if (unlikely (get_type () == SubstLookupSubTable::Extension))
+ {
+ /* The spec says all subtables of an Extension lookup should
+ * 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)
+ return_trace (false);
+ }
+ return_trace (true);
+ }
+};
+
+typedef OffsetListOf<SubstLookup> SubstLookupList;
+
+/*
+ * GSUB -- The Glyph Substitution Table
+ */
+
+struct GSUB : GSUBGPOS
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_GSUB;
+
+ inline const SubstLookup& get_lookup (unsigned int i) const
+ { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
+
+ static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
+ const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
+ return_trace (list.sanitize (c, this));
+ }
+};
+
+
+void
+GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+ _hb_buffer_assert_gsubgpos_vars (buffer);
+
+ const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+ _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+ buffer->info[i].syllable() = 0;
+ }
}
-/*static*/ typename hb_closure_context_t::return_t SubstLookup::closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
+
+/* Out-of-class implementation for methods recursing */
+
+/*static*/ inline bool ExtensionSubst::is_reverse (void) const
{
- const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
- if (l.may_have_non_1to1 ())
- hb_set_add_range (covered_seq_indices, seq_index, end_index);
- return l.dispatch (c);
+ unsigned int type = get_type ();
+ if (unlikely (type == SubstLookupSubTable::Extension))
+ return CastR<ExtensionSubst> (get_subtable<LookupSubTable>()).is_reverse ();
+ return SubstLookup::lookup_type_is_reverse (type);
}
-template <>
-inline hb_closure_lookups_context_t::return_t
-SubstLookup::dispatch_recurse_func<hb_closure_lookups_context_t> (hb_closure_lookups_context_t *c, unsigned this_index)
+template <typename context_t>
+/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
{
- const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index);
- return l.closure_lookups (c, this_index);
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
+ return l.dispatch (c);
}
-template <>
-inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
+/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
{
- auto *gsub = c->face->table.GSUB.get_relaxed ();
- const SubstLookup &l = gsub->table->get_lookup (lookup_index);
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
unsigned int saved_lookup_index = c->lookup_index;
c->set_lookup_index (lookup_index);
c->set_lookup_props (l.get_props ());
-
- bool ret = false;
- auto *accel = gsub->get_accel (lookup_index);
- ret = accel && accel->apply (c, l.get_subtable_count (), false);
-
+ bool ret = l.dispatch (c);
c->set_lookup_index (saved_lookup_index);
c->set_lookup_props (saved_lookup_props);
return ret;
}
-#endif
-} /* namespace GSUB_impl */
-} /* namespace Layout */
+
} /* namespace OT */
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
new file mode 100644
index 00000000000..b08a59138e3
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -0,0 +1,2373 @@
+/*
+ * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
+ * Copyright © 2010,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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#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"
+
+
+namespace OT {
+
+
+struct hb_closure_context_t :
+ hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
+{
+ inline const char *get_name (void) { return "CLOSURE"; }
+ typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return HB_VOID;
+ }
+
+ hb_face_t *face;
+ hb_set_t *glyphs;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+ hb_closure_context_t (hb_face_t *face_,
+ hb_set_t *glyphs_,
+ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+ face (face_),
+ glyphs (glyphs_),
+ recurse_func (nullptr),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+struct hb_would_apply_context_t :
+ hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
+{
+ inline const char *get_name (void) { return "WOULD_APPLY"; }
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return r; }
+
+ hb_face_t *face;
+ const hb_codepoint_t *glyphs;
+ unsigned int len;
+ bool zero_context;
+ unsigned int debug_depth;
+
+ hb_would_apply_context_t (hb_face_t *face_,
+ const hb_codepoint_t *glyphs_,
+ unsigned int len_,
+ bool zero_context_) :
+ face (face_),
+ glyphs (glyphs_),
+ len (len_),
+ zero_context (zero_context_),
+ debug_depth (0) {}
+};
+
+
+struct hb_collect_glyphs_context_t :
+ hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
+{
+ inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
+ typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ /* 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.
+ *
+ * Note further, that the above is not exactly correct. A recursed lookup
+ * is allowed to match input that is not matched in the context, but that's
+ * not how most fonts are built. It's possible to relax that and recurse
+ * with all sets here if it proves to be an issue.
+ */
+
+ if (output == hb_set_get_empty ())
+ return HB_VOID;
+
+ /* Return if new lookup was recursed to before. */
+ if (recursed_lookups->has (lookup_index))
+ return HB_VOID;
+
+ hb_set_t *old_before = before;
+ hb_set_t *old_input = input;
+ hb_set_t *old_after = after;
+ before = input = after = hb_set_get_empty ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+
+ before = old_before;
+ input = old_input;
+ after = old_after;
+
+ recursed_lookups->add (lookup_index);
+
+ return HB_VOID;
+ }
+
+ hb_face_t *face;
+ hb_set_t *before;
+ hb_set_t *input;
+ hb_set_t *after;
+ hb_set_t *output;
+ recurse_func_t recurse_func;
+ 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 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 (nullptr),
+ recursed_lookups (nullptr),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0)
+ {
+ recursed_lookups = hb_set_create ();
+ }
+ ~hb_collect_glyphs_context_t (void)
+ {
+ hb_set_destroy (recursed_lookups);
+ }
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+/* XXX Can we remove this? */
+
+template <typename set_t>
+struct hb_add_coverage_context_t :
+ hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
+{
+ inline const char *get_name (void) { return "GET_COVERAGE"; }
+ typedef const Coverage &return_t;
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
+ static return_t default_return_value (void) { return Null(Coverage); }
+ bool stop_sublookup_iteration (return_t r) const
+ {
+ r.add_coverage (set);
+ return false;
+ }
+
+ hb_add_coverage_context_t (set_t *set_) :
+ set (set_),
+ debug_depth (0) {}
+
+ set_t *set;
+ unsigned int debug_depth;
+};
+
+
+struct hb_apply_context_t :
+ hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
+{
+ struct matcher_t
+ {
+ inline matcher_t (void) :
+ lookup_props (0),
+ ignore_zwnj (false),
+ ignore_zwj (false),
+ mask (-1),
+#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
+ syllable arg1(0),
+#undef arg1
+ match_func (nullptr),
+ match_data (nullptr) {};
+
+ 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_; }
+ inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ inline void set_mask (hb_mask_t mask_) { mask = mask_; }
+ inline void set_syllable (uint8_t syllable_) { syllable = syllable_; }
+ inline void set_match_func (match_func_t match_func_,
+ const void *match_data_)
+ { match_func = match_func_; match_data = match_data_; }
+
+ enum may_match_t {
+ MATCH_NO,
+ MATCH_YES,
+ MATCH_MAYBE
+ };
+
+ inline may_match_t may_match (const hb_glyph_info_t &info,
+ const UINT16 *glyph_data) const
+ {
+ if (!(info.mask & mask) ||
+ (syllable && syllable != info.syllable ()))
+ return MATCH_NO;
+
+ if (match_func)
+ return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
+
+ return MATCH_MAYBE;
+ }
+
+ enum may_skip_t {
+ SKIP_NO,
+ SKIP_YES,
+ SKIP_MAYBE
+ };
+
+ inline may_skip_t
+ may_skip (const hb_apply_context_t *c,
+ const hb_glyph_info_t &info) const
+ {
+ if (!c->check_glyph_property (&info, lookup_props))
+ return SKIP_YES;
+
+ 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;
+
+ return SKIP_NO;
+ }
+
+ protected:
+ unsigned int lookup_props;
+ bool ignore_zwnj;
+ bool ignore_zwj;
+ hb_mask_t mask;
+ uint8_t syllable;
+ match_func_t match_func;
+ const void *match_data;
+ };
+
+ struct skipping_iterator_t
+ {
+ inline void init (hb_apply_context_t *c_, bool context_match = false)
+ {
+ c = c_;
+ 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 (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 (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)
+ {
+ matcher.set_lookup_props (lookup_props);
+ }
+ inline void set_match_func (matcher_t::match_func_t match_func_,
+ const void *match_data_,
+ const UINT16 glyph_data[])
+ {
+ matcher.set_match_func (match_func_, match_data_);
+ match_glyph_data = glyph_data;
+ }
+
+ inline void reset (unsigned int start_index_,
+ unsigned int num_items_)
+ {
+ idx = start_index_;
+ num_items = num_items_;
+ end = c->buffer->len;
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
+
+ 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);
+ while (idx + num_items < end)
+ {
+ idx++;
+ const hb_glyph_info_t &info = c->buffer->info[idx];
+
+ matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+ if (match == matcher_t::MATCH_YES ||
+ (match == matcher_t::MATCH_MAYBE &&
+ skip == matcher_t::SKIP_NO))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
+ }
+ inline bool prev (void)
+ {
+ assert (num_items > 0);
+ while (idx >= num_items)
+ {
+ idx--;
+ const hb_glyph_info_t &info = c->buffer->out_info[idx];
+
+ matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+ if (match == matcher_t::MATCH_YES ||
+ (match == matcher_t::MATCH_MAYBE &&
+ skip == matcher_t::SKIP_NO))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
+ }
+
+ unsigned int idx;
+ protected:
+ hb_apply_context_t *c;
+ matcher_t matcher;
+ const UINT16 *match_glyph_data;
+
+ unsigned int num_items;
+ unsigned int end;
+ };
+
+
+ inline const char *get_name (void) { return "APPLY"; }
+ typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.apply (this); }
+ static return_t default_return_value (void) { return false; }
+ 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 || buffer->max_ops-- <= 0))
+ return default_return_value ();
+
+ nesting_level_left--;
+ bool ret = recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return ret;
+ }
+
+ skipping_iterator_t iter_input, iter_context;
+
+ hb_font_t *font;
+ hb_face_t *face;
+ hb_buffer_t *buffer;
+ recurse_func_t recurse_func;
+ const GDEF &gdef;
+ const VariationStore &var_store;
+
+ 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_) :
+ iter_input (), iter_context (),
+ font (font_), face (font->face), buffer (buffer_),
+ recurse_func (nullptr),
+ gdef (*hb_ot_layout_from_face (face)->gdef),
+ var_store (gdef.get_var_store ()),
+ direction (buffer_->props.direction),
+ lookup_mask (1),
+ table_index (table_index_),
+ lookup_index ((unsigned int) -1),
+ 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_)
+ {
+ lookup_props = lookup_props_;
+ iter_input.init (this, false);
+ iter_context.init (this, true);
+ }
+
+ inline bool
+ match_properties_mark (hb_codepoint_t glyph,
+ unsigned int glyph_props,
+ unsigned int match_props) const
+ {
+ /* If using mark filtering sets, the high short of
+ * match_props has the set index.
+ */
+ if (match_props & LookupFlag::UseMarkFilteringSet)
+ return gdef.mark_set_covers (match_props >> 16, glyph);
+
+ /* The second byte of match_props has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ if (match_props & LookupFlag::MarkAttachmentType)
+ return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+ return true;
+ }
+
+ inline bool
+ check_glyph_property (const hb_glyph_info_t *info,
+ unsigned int match_props) const
+ {
+ hb_codepoint_t glyph = info->codepoint;
+ unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
+
+ /* Not covered, if, for example, glyph class is ligature and
+ * match_props includes LookupFlags::IgnoreLigatures
+ */
+ if (glyph_props & match_props & LookupFlag::IgnoreFlags)
+ return false;
+
+ if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+ return match_properties_mark (glyph, glyph_props, match_props);
+
+ return true;
+ }
+
+ inline void _set_glyph_props (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0,
+ bool ligature = false,
+ bool component = false) const
+ {
+ unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+ if (ligature)
+ {
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
+ /* In the only place that the MULTIPLIED bit is used, Uniscribe
+ * seems to only care about the "last" transformation between
+ * Ligature and Multiple substitions. Ie. if you ligate, expand,
+ * and ligate again, it forgives the multiplication and acts as
+ * if only ligation happened. As such, clear MULTIPLIED bit.
+ */
+ add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+ }
+ if (component)
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+ if (likely (has_glyph_classes))
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
+ else if (class_guess)
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
+ }
+
+ inline void replace_glyph (hb_codepoint_t glyph_index) const
+ {
+ _set_glyph_props (glyph_index);
+ buffer->replace_glyph (glyph_index);
+ }
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
+ {
+ _set_glyph_props (glyph_index);
+ buffer->cur().codepoint = glyph_index;
+ }
+ inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
+ {
+ _set_glyph_props (glyph_index, class_guess, true);
+ buffer->replace_glyph (glyph_index);
+ }
+ inline void output_glyph_for_component (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
+ {
+ _set_glyph_props (glyph_index, class_guess, false, true);
+ buffer->output_glyph (glyph_index);
+ }
+};
+
+
+
+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
+{
+ intersects_func_t intersects;
+};
+struct ContextCollectGlyphsFuncs
+{
+ collect_glyphs_func_t collect;
+};
+struct ContextApplyFuncs
+{
+ match_func_t match;
+};
+
+
+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 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 UINT16 &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ return (data+coverage).intersects (glyphs);
+}
+
+static inline bool intersects_array (hb_closure_context_t *c,
+ unsigned int count,
+ const UINT16 values[],
+ intersects_func_t intersects_func,
+ const void *intersects_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ if (likely (!intersects_func (c->glyphs, values[i], intersects_data)))
+ return false;
+ return true;
+}
+
+
+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 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 UINT16 &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ (data+coverage).add_coverage (glyphs);
+}
+static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
+ hb_set_t *glyphs,
+ unsigned int count,
+ const UINT16 values[],
+ collect_glyphs_func_t collect_func,
+ const void *collect_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ collect_func (glyphs, values[i], collect_data);
+}
+
+
+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 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 UINT16 &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
+}
+
+static inline bool would_match_input (hb_would_apply_context_t *c,
+ unsigned int count, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data)
+{
+ if (count != c->len)
+ return false;
+
+ for (unsigned int i = 1; i < count; i++)
+ if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
+ return false;
+
+ return true;
+}
+static inline bool match_input (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph (not matched) */
+ 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 = nullptr,
+ unsigned int *p_total_component_count = nullptr)
+{
+ TRACE_APPLY (nullptr);
+
+ if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+
+ /*
+ * This is perhaps the trickiest part of OpenType... Remarks:
+ *
+ * - If all components of the ligature were marks, we call this a mark ligature.
+ *
+ * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize
+ * it as a ligature glyph.
+ *
+ * - 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.
+ * 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());
+
+ unsigned int total_component_count = 0;
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+
+ 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++)
+ {
+ if (!skippy_iter.next ()) return_trace (false);
+
+ match_positions[i] = skippy_iter.idx;
+
+ 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 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... */
+ if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
+ {
+ /* ...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! */
+ if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
+ return_trace (false);
+ }
+
+ is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
+ }
+
+ *end_offset = skippy_iter.idx - buffer->idx + 1;
+
+ if (p_is_mark_ligature)
+ *p_is_mark_ligature = is_mark_ligature;
+
+ if (p_total_component_count)
+ *p_total_component_count = total_component_count;
+
+ return_trace (true);
+}
+static inline bool ligate_input (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int match_length,
+ hb_codepoint_t lig_glyph,
+ bool is_mark_ligature,
+ unsigned int total_component_count)
+{
+ TRACE_APPLY (nullptr);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
+
+ /*
+ * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
+ * the ligature to keep its old ligature id. This will allow it to attach to
+ * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH,
+ * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
+ * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature
+ * later, we don't want them to lose their ligature id/component, otherwise
+ * GPOS will fail to correctly position the mark ligature on top of the
+ * LAM,LAM,HEH ligature. See:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=676343
+ *
+ * - If a ligature is formed of components that some of which are also ligatures
+ * themselves, and those ligature components had marks attached to *their*
+ * components, we have to attach the marks to the new ligature component
+ * positions! Now *that*'s tricky! And these marks may be following the
+ * last component of the whole sequence, so we should loop forward looking
+ * for them and update them.
+ *
+ * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a
+ * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature
+ * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature
+ * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to
+ * the new ligature with a component value of 2.
+ *
+ * This in fact happened to a font... See:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=437633
+ */
+
+ unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+ unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+ unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+ unsigned int components_so_far = last_num_components;
+
+ if (!is_mark_ligature)
+ {
+ _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ }
+ }
+ c->replace_glyph_with_ligature (lig_glyph, klass);
+
+ for (unsigned int i = 1; i < count; i++)
+ {
+ while (buffer->idx < match_positions[i] && !buffer->in_error)
+ {
+ if (!is_mark_ligature) {
+ unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ if (this_comp == 0)
+ this_comp = last_num_components;
+ unsigned int new_lig_comp = components_so_far - last_num_components +
+ MIN (this_comp, last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
+ }
+ buffer->next_glyph ();
+ }
+
+ last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+ components_so_far += last_num_components;
+
+ /* Skip the base glyph */
+ buffer->idx++;
+ }
+
+ if (!is_mark_ligature && last_lig_id) {
+ /* Re-adjust components for any marks following. */
+ for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+ if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
+ unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
+ if (!this_comp)
+ break;
+ unsigned int new_lig_comp = components_so_far - last_num_components +
+ MIN (this_comp, last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
+ } else
+ break;
+ }
+ }
+ return_trace (true);
+}
+
+static inline bool match_backtrack (hb_apply_context_t *c,
+ unsigned int count,
+ const UINT16 backtrack[],
+ match_func_t match_func,
+ const void *match_data,
+ unsigned int *match_start)
+{
+ TRACE_APPLY (nullptr);
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+ skippy_iter.reset (c->buffer->backtrack_len (), count);
+ skippy_iter.set_match_func (match_func, match_data, backtrack);
+
+ for (unsigned int i = 0; i < count; i++)
+ 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 UINT16 lookahead[],
+ match_func_t match_func,
+ const void *match_data,
+ unsigned int offset,
+ unsigned int *end_index)
+{
+ TRACE_APPLY (nullptr);
+
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+ skippy_iter.reset (c->buffer->idx + offset - 1, count);
+ skippy_iter.set_match_func (match_func, match_data, lookahead);
+
+ for (unsigned int i = 0; i < count; i++)
+ if (!skippy_iter.next ())
+ return_trace (false);
+
+ *end_index = skippy_iter.idx + 1;
+
+ return_trace (true);
+}
+
+
+
+struct LookupRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ UINT16 sequenceIndex; /* Index into current glyph
+ * sequence--first glyph = 0 */
+ UINT16 lookupListIndex; /* Lookup to apply to that
+ * position--zero--based */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+
+template <typename context_t>
+static inline void recurse_lookups (context_t *c,
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+{
+ for (unsigned int i = 0; i < lookupCount; i++)
+ c->recurse (lookupRecord[i].lookupListIndex);
+}
+
+static inline bool apply_lookup (hb_apply_context_t *c,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+ unsigned int match_length)
+{
+ TRACE_APPLY (nullptr);
+
+ hb_buffer_t *buffer = c->buffer;
+ int end;
+
+ /* All positions are distance from beginning of *output* buffer.
+ * Adjust. */
+ {
+ unsigned int bl = buffer->backtrack_len ();
+ end = bl + match_length;
+
+ int delta = bl - buffer->idx;
+ /* Convert positions to new indexing. */
+ for (unsigned int j = 0; j < count; j++)
+ match_positions[j] += delta;
+ }
+
+ for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++)
+ {
+ unsigned int idx = lookupRecord[i].sequenceIndex;
+ if (idx >= count)
+ continue;
+
+ /* Don't recurse to ourself at same position.
+ * Note that this test is too naive, it doesn't catch longer loops. */
+ if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)
+ continue;
+
+ 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))
+ continue;
+
+ unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ int delta = new_len - orig_len;
+
+ if (!delta)
+ continue;
+
+ /* 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 += 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.
+ * Just never rewind end back and get out of here.
+ * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */
+ end = match_positions[idx];
+ /* There can't be any further changes. */
+ break;
+ }
+
+ unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
+
+ if (delta > 0)
+ {
+ if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH))
+ break;
+ }
+ else
+ {
+ /* NOTE: delta is negative. */
+ delta = MAX (delta, (int) next - (int) count);
+ next -= delta;
+ }
+
+ /* Shift! */
+ memmove (match_positions + next + delta, match_positions + next,
+ (count - next) * sizeof (match_positions[0]));
+ next += delta;
+ count += delta;
+
+ /* Fill in new entries. */
+ for (unsigned int j = idx + 1; j < next; j++)
+ match_positions[j] = match_positions[j - 1] + 1;
+
+ /* And fixup the rest. */
+ for (; next < count; next++)
+ match_positions[next] += delta;
+ }
+
+ buffer->move_to (end);
+
+ return_trace (true);
+}
+
+
+
+/* Contextual lookups */
+
+struct ContextClosureLookupContext
+{
+ ContextClosureFuncs funcs;
+ const void *intersects_data;
+};
+
+struct ContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data;
+};
+
+struct ContextApplyLookupContext
+{
+ ContextApplyFuncs funcs;
+ const void *match_data;
+};
+
+static inline void context_closure_lookup (hb_closure_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextClosureLookupContext &lookup_context)
+{
+ if (intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data))
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
+ ContextApplyLookupContext &lookup_context)
+{
+ return would_match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data);
+}
+static inline bool context_apply_lookup (hb_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextApplyLookupContext &lookup_context)
+{
+ unsigned int match_length = 0;
+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+ return match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data,
+ &match_length, match_positions)
+ && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length),
+ apply_lookup (c,
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length));
+}
+
+struct Rule
+{
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+ context_closure_lookup (c,
+ inputCount, inputZ,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+ context_collect_glyphs_lookup (c,
+ inputCount, inputZ,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+ return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+ return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (inputCount.sanitize (c) &&
+ lookupCount.sanitize (c) &&
+ c->check_range (inputZ,
+ inputZ[0].static_size * inputCount +
+ lookupRecordX[0].static_size * lookupCount));
+ }
+
+ protected:
+ UINT16 inputCount; /* Total number of glyphs in input
+ * glyph sequence--includes the first
+ * glyph */
+ 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 */
+ public:
+ DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX);
+};
+
+struct RuleSet
+{
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).closure (c, lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ if ((this+rule[i]).would_apply (c, lookup_context))
+ return_trace (true);
+ }
+ return_trace (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ {
+ if ((this+rule[i]).apply (c, lookup_context))
+ return_trace (true);
+ }
+ return_trace (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rule.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<Rule>
+ rule; /* Array of Rule tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, rule);
+};
+
+
+struct ContextFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+
+ const Coverage &cov = (this+coverage);
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_glyph},
+ nullptr
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ nullptr
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ nullptr
+ };
+ return_trace (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED))
+ return_trace (false);
+
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ nullptr
+ };
+ return_trace (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+
+struct ContextFormat2
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverage).intersects (c->glyphs))
+ return;
+
+ const ClassDef &class_def = this+classDef;
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_class},
+ &class_def
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (class_def.intersects_class (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &class_def = this+classDef;
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ &class_def
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ClassDef &class_def = this+classDef;
+ unsigned int index = class_def.get_class (c->glyphs[0]);
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_class},
+ &class_def
+ };
+ return_trace (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const ClassDef &class_def = this+classDef;
+ index = class_def.get_class (c->buffer->cur().codepoint);
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextApplyLookupContext lookup_context = {
+ {match_class},
+ &class_def
+ };
+ return_trace (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetTo<ClassDef>
+ classDef; /* Offset to glyph ClassDef table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by class */
+ public:
+ DEFINE_SIZE_ARRAY (8, ruleSet);
+};
+
+
+struct ContextFormat3
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverageZ[0]).intersects (c->glyphs))
+ return;
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_coverage},
+ this
+ };
+ context_closure_lookup (c,
+ glyphCount, (const UINT16 *) (coverageZ + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverageZ[0]).add_coverage (c->input);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ this
+ };
+
+ context_collect_glyphs_lookup (c,
+ glyphCount, (const UINT16 *) (coverageZ + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+ struct ContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ this
+ };
+ return_trace (context_would_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverageZ[0];
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+ struct ContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ this
+ };
+ return_trace (context_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!c->check_struct (this)) return_trace (false);
+ unsigned int count = glyphCount;
+ if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
+ if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (!coverageZ[i].sanitize (c, this)) return_trace (false);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
+ return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 3 */
+ UINT16 glyphCount; /* Number of glyphs in the input glyph
+ * sequence */
+ UINT16 lookupCount; /* Number of LookupRecords */
+ OffsetTo<Coverage>
+ coverageZ[VAR]; /* Array of offsets to Coverage
+ * table in glyph sequence order */
+ LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
+ * design order */
+ public:
+ DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX);
+};
+
+struct Context
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ case 2: return_trace (c->dispatch (u.format2));
+ case 3: return_trace (c->dispatch (u.format3));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ContextFormat1 format1;
+ ContextFormat2 format2;
+ ContextFormat3 format3;
+ } u;
+};
+
+
+/* Chaining Contextual lookups */
+
+struct ChainContextClosureLookupContext
+{
+ ContextClosureFuncs funcs;
+ const void *intersects_data[3];
+};
+
+struct ChainContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data[3];
+};
+
+struct ChainContextApplyLookupContext
+{
+ ContextApplyFuncs funcs;
+ const void *match_data[3];
+};
+
+static inline void chain_context_closure_lookup (hb_closure_context_t *c,
+ unsigned int backtrackCount,
+ const UINT16 backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const UINT16 lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextClosureLookupContext &lookup_context)
+{
+ if (intersects_array (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ && intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ && intersects_array (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+ unsigned int backtrackCount,
+ const UINT16 backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const UINT16 lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->before,
+ backtrackCount, backtrack,
+ lookup_context.funcs.collect, lookup_context.collect_data[0]);
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data[1]);
+ collect_array (c, c->after,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.collect, lookup_context.collect_data[2]);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
+ unsigned int backtrackCount,
+ const UINT16 backtrack[] HB_UNUSED,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const UINT16 lookahead[] HB_UNUSED,
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
+ ChainContextApplyLookupContext &lookup_context)
+{
+ return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
+ && would_match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1]);
+}
+
+static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
+ unsigned int backtrackCount,
+ const UINT16 backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const UINT16 input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const UINT16 lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextApplyLookupContext &lookup_context)
+{
+ 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,
+ lookup_context.funcs.match, lookup_context.match_data[1],
+ &match_length, match_positions)
+ && match_backtrack (c,
+ backtrackCount, backtrack,
+ 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, &end_index)
+ && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
+ apply_lookup (c,
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length));
+}
+
+struct ChainRule
+{
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ 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,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ 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,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ 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,
+ input.len, input.array,
+ lookahead.len, lookahead.array, lookup.len,
+ lookup.array, lookup_context));
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ 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,
+ input.len, input.array,
+ lookahead.len, lookahead.array, lookup.len,
+ lookup.array, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!backtrack.sanitize (c)) return_trace (false);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
+ if (!input.sanitize (c)) return_trace (false);
+ 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<UINT16>
+ backtrack; /* Array of backtracking values
+ * (to be matched before the input
+ * sequence) */
+ HeadlessArrayOf<UINT16>
+ inputX; /* Array of input values (start with
+ * second glyph) */
+ ArrayOf<UINT16>
+ lookaheadX; /* Array of lookahead values's (to be
+ * matched after the input sequence) */
+ ArrayOf<LookupRecord>
+ lookupX; /* Array of LookupRecords--in
+ * design order) */
+ public:
+ DEFINE_SIZE_MIN (8);
+};
+
+struct ChainRuleSet
+{
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).closure (c, lookup_context);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_WOULD_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if ((this+rule[i]).would_apply (c, lookup_context))
+ return_trace (true);
+
+ return_trace (false);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+ {
+ TRACE_APPLY (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ if ((this+rule[i]).apply (c, lookup_context))
+ return_trace (true);
+
+ return_trace (false);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rule.sanitize (c, this));
+ }
+
+ protected:
+ OffsetArrayOf<ChainRule>
+ rule; /* Array of ChainRule tables
+ * ordered by preference */
+ public:
+ DEFINE_SIZE_ARRAY (2, rule);
+};
+
+struct ChainContextFormat1
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const Coverage &cov = (this+coverage);
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_glyph},
+ {nullptr, nullptr, nullptr}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ {nullptr, nullptr, nullptr}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ {nullptr, nullptr, nullptr}
+ };
+ return_trace (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_glyph},
+ {nullptr, nullptr, nullptr}
+ };
+ return_trace (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<ChainRuleSet>
+ ruleSet; /* Array of ChainRuleSet tables
+ * ordered by Coverage Index */
+ public:
+ DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+struct ChainContextFormat2
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ if (!(this+coverage).intersects (c->glyphs))
+ return;
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (input_class_def.intersects_class (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ rule_set.closure (c, lookup_context);
+ }
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ unsigned int index = input_class_def.get_class (c->glyphs[0]);
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+ return_trace (rule_set.would_apply (c, lookup_context));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ index = input_class_def.get_class (c->buffer->cur().codepoint);
+ const ChainRuleSet &rule_set = this+ruleSet[index];
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+ return_trace (rule_set.apply (c, lookup_context));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (coverage.sanitize (c, this) &&
+ backtrackClassDef.sanitize (c, this) &&
+ inputClassDef.sanitize (c, this) &&
+ lookaheadClassDef.sanitize (c, this) &&
+ ruleSet.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetTo<ClassDef>
+ backtrackClassDef; /* Offset to glyph ClassDef table
+ * containing backtrack sequence
+ * data--from beginning of table */
+ OffsetTo<ClassDef>
+ inputClassDef; /* Offset to glyph ClassDef
+ * table containing input sequence
+ * data--from beginning of table */
+ OffsetTo<ClassDef>
+ lookaheadClassDef; /* Offset to glyph ClassDef table
+ * containing lookahead sequence
+ * data--from beginning of table */
+ OffsetArrayOf<ChainRuleSet>
+ ruleSet; /* Array of ChainRuleSet tables
+ * ordered by class */
+ public:
+ DEFINE_SIZE_ARRAY (12, ruleSet);
+};
+
+struct ChainContextFormat3
+{
+ inline void closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ if (!(this+input[0]).intersects (c->glyphs))
+ return;
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_coverage},
+ {this, this, this}
+ };
+ chain_context_closure_lookup (c,
+ 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);
+ }
+
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ (this+input[0]).add_coverage (c->input);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ {this, this, this}
+ };
+ chain_context_collect_glyphs_lookup (c,
+ 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);
+ }
+
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ {this, this, this}
+ };
+ return_trace (chain_context_would_apply_lookup (c,
+ 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));
+ }
+
+ inline const Coverage &get_coverage (void) const
+ {
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ return this+input[0];
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
+ if (likely (index == NOT_COVERED)) return_trace (false);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextApplyLookupContext lookup_context = {
+ {match_coverage},
+ {this, this, this}
+ };
+ return_trace (chain_context_apply_lookup (c,
+ 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));
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!backtrack.sanitize (c, this)) return_trace (false);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (!input.sanitize (c, this)) return_trace (false);
+ if (!input.len) return_trace (false); /* To be consistent with Context. */
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ if (!lookahead.sanitize (c, this)) return_trace (false);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return_trace (lookup.sanitize (c));
+ }
+
+ protected:
+ UINT16 format; /* Format identifier--format = 3 */
+ OffsetArrayOf<Coverage>
+ backtrack; /* Array of coverage tables
+ * in backtracking sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ inputX ; /* Array of coverage
+ * tables in input sequence, in glyph
+ * sequence order */
+ OffsetArrayOf<Coverage>
+ lookaheadX; /* Array of coverage tables
+ * in lookahead sequence, in glyph
+ * sequence order */
+ ArrayOf<LookupRecord>
+ lookupX; /* Array of LookupRecords--in
+ * design order) */
+ public:
+ DEFINE_SIZE_MIN (10);
+};
+
+struct ChainContext
+{
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (c->dispatch (u.format1));
+ case 2: return_trace (c->dispatch (u.format2));
+ case 3: return_trace (c->dispatch (u.format3));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ChainContextFormat1 format1;
+ ChainContextFormat2 format2;
+ ChainContextFormat3 format3;
+ } u;
+};
+
+
+template <typename T>
+struct ExtensionFormat1
+{
+ inline unsigned int get_type (void) const { return extensionLookupType; }
+
+ template <typename X>
+ inline const X& get_subtable (void) const
+ {
+ unsigned int offset = extensionOffset;
+ if (unlikely (!offset)) return Null(typename T::LookupSubTable);
+ return StructAtOffset<typename T::LookupSubTable> (this, offset);
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, format);
+ if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
+ return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()));
+ }
+
+ /* This is called from may_dispatch() above with hb_sanitize_context_t. */
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && extensionOffset != 0);
+ }
+
+ protected:
+ UINT16 format; /* Format identifier. Set to 1. */
+ UINT16 extensionLookupType; /* Lookup type of subtable referenced
+ * by ExtensionOffset (i.e. the
+ * extension subtable). */
+ UINT32 extensionOffset; /* Offset to the extension subtable,
+ * of lookup type subtable. */
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+template <typename T>
+struct Extension
+{
+ inline unsigned int get_type (void) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_type ();
+ default:return 0;
+ }
+ }
+ template <typename X>
+ inline const X& get_subtable (void) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
+ default:return Null(typename T::LookupSubTable);
+ }
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t dispatch (context_t *c) const
+ {
+ TRACE_DISPATCH (this, u.format);
+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+ switch (u.format) {
+ case 1: return_trace (u.format1.dispatch (c));
+ default:return_trace (c->default_return_value ());
+ }
+ }
+
+ protected:
+ union {
+ UINT16 format; /* Format identifier */
+ ExtensionFormat1<T> format1;
+ } u;
+};
+
+
+/*
+ * GSUB/GPOS Common
+ */
+
+struct GSUBGPOS
+{
+ inline unsigned int get_script_count (void) const
+ { return (this+scriptList).len; }
+ inline const Tag& get_script_tag (unsigned int i) const
+ { return (this+scriptList).get_tag (i); }
+ inline unsigned int get_script_tags (unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */) const
+ { return (this+scriptList).get_tags (start_offset, script_count, script_tags); }
+ inline const Script& get_script (unsigned int i) const
+ { return (this+scriptList)[i]; }
+ inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+ { return (this+scriptList).find_index (tag, index); }
+
+ inline unsigned int get_feature_count (void) const
+ { return (this+featureList).len; }
+ inline hb_tag_t get_feature_tag (unsigned int i) const
+ { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); }
+ inline unsigned int get_feature_tags (unsigned int start_offset,
+ unsigned int *feature_count /* IN/OUT */,
+ hb_tag_t *feature_tags /* OUT */) const
+ { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); }
+ inline const Feature& get_feature (unsigned int i) const
+ { return (this+featureList)[i]; }
+ inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const
+ { return (this+featureList).find_index (tag, index); }
+
+ inline unsigned int get_lookup_count (void) const
+ { return (this+lookupList).len; }
+ inline const Lookup& get_lookup (unsigned int i) const
+ { return (this+lookupList)[i]; }
+
+ inline bool find_variations_index (const int *coords, unsigned int num_coords,
+ unsigned int *index) const
+ { return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
+ .find_index (coords, num_coords, index); }
+ inline const Feature& get_feature_variation (unsigned int feature_index,
+ unsigned int variations_index) const
+ {
+ if (FeatureVariations::NOT_FOUND_INDEX != variations_index &&
+ version.to_int () >= 0x00010001u)
+ {
+ const Feature *feature = (this+featureVars).find_substitute (variations_index,
+ feature_index);
+ if (feature)
+ return *feature;
+ }
+ return get_feature (feature_index);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ scriptList.sanitize (c, this) &&
+ featureList.sanitize (c, this) &&
+ lookupList.sanitize (c, this) &&
+ (version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
+ }
+
+ protected:
+ FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set
+ * to 0x00010000u */
+ OffsetTo<ScriptList>
+ scriptList; /* ScriptList table */
+ OffsetTo<FeatureList>
+ featureList; /* FeatureList table */
+ OffsetTo<LookupList>
+ lookupList; /* LookupList table */
+ LOffsetTo<FeatureVariations>
+ featureVars; /* Offset to Feature Variations
+ table--from beginning of table
+ * (may be NULL). Introduced
+ * in version 0x00010001. */
+ public:
+ DEFINE_SIZE_MIN (10);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
deleted file mode 100644
index e1b66a199a3..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
+++ /dev/null
@@ -1,4550 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2010,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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_LAYOUT_GSUBGPOS_HH
-#define HB_OT_LAYOUT_GSUBGPOS_HH
-
-#include "hb.hh"
-#include "hb-buffer.hh"
-#include "hb-map.hh"
-#include "hb-set.hh"
-#include "hb-ot-map.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-layout-gdef-table.hh"
-
-
-namespace OT {
-
-
-struct hb_intersects_context_t :
- hb_dispatch_context_t<hb_intersects_context_t, bool>
-{
- template <typename T>
- return_t dispatch (const T &obj) { return obj.intersects (this->glyphs); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- const hb_set_t *glyphs;
-
- hb_intersects_context_t (const hb_set_t *glyphs_) :
- glyphs (glyphs_) {}
-};
-
-struct hb_have_non_1to1_context_t :
- hb_dispatch_context_t<hb_have_non_1to1_context_t, bool>
-{
- template <typename T>
- return_t dispatch (const T &obj) { return obj.may_have_non_1to1 (); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-};
-
-struct hb_closure_context_t :
- hb_dispatch_context_t<hb_closure_context_t>
-{
- typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indicies, unsigned seq_index, unsigned end_index);
- template <typename T>
- return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
- static return_t default_return_value () { return hb_empty_t (); }
- void recurse (unsigned lookup_index, hb_set_t *covered_seq_indicies, unsigned seq_index, unsigned end_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func))
- return;
-
- nesting_level_left--;
- recurse_func (this, lookup_index, covered_seq_indicies, seq_index, end_index);
- nesting_level_left++;
- }
-
- void reset_lookup_visit_count ()
- { lookup_count = 0; }
-
- bool lookup_limit_exceeded ()
- { return lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; }
-
- bool should_visit_lookup (unsigned int lookup_index)
- {
- if (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT)
- return false;
-
- if (is_lookup_done (lookup_index))
- return false;
-
- return true;
- }
-
- bool is_lookup_done (unsigned int lookup_index)
- {
- if (unlikely (done_lookups_glyph_count->in_error () ||
- done_lookups_glyph_set->in_error ()))
- return true;
-
- /* Have we visited this lookup with the current set of glyphs? */
- if (done_lookups_glyph_count->get (lookup_index) != glyphs->get_population ())
- {
- done_lookups_glyph_count->set (lookup_index, glyphs->get_population ());
-
- if (!done_lookups_glyph_set->has (lookup_index))
- {
- if (unlikely (!done_lookups_glyph_set->set (lookup_index, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
- return true;
- }
-
- done_lookups_glyph_set->get (lookup_index)->clear ();
- }
-
- hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index);
- if (unlikely (covered_glyph_set->in_error ()))
- return true;
- if (parent_active_glyphs ().is_subset (*covered_glyph_set))
- return true;
-
- covered_glyph_set->union_ (parent_active_glyphs ());
- return false;
- }
-
- const hb_set_t& previous_parent_active_glyphs () {
- if (active_glyphs_stack.length <= 1)
- return *glyphs;
-
- return active_glyphs_stack[active_glyphs_stack.length - 2];
- }
-
- const hb_set_t& parent_active_glyphs ()
- {
- if (!active_glyphs_stack)
- return *glyphs;
-
- return active_glyphs_stack.tail ();
- }
-
- hb_set_t& push_cur_active_glyphs ()
- {
- return *active_glyphs_stack.push ();
- }
-
- bool pop_cur_done_glyphs ()
- {
- if (!active_glyphs_stack)
- return false;
-
- active_glyphs_stack.pop ();
- return true;
- }
-
- hb_face_t *face;
- hb_set_t *glyphs;
- hb_set_t output[1];
- hb_vector_t<hb_set_t> active_glyphs_stack;
- recurse_func_t recurse_func = nullptr;
- unsigned int nesting_level_left;
-
- hb_closure_context_t (hb_face_t *face_,
- hb_set_t *glyphs_,
- hb_map_t *done_lookups_glyph_count_,
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set_,
- unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
- face (face_),
- glyphs (glyphs_),
- nesting_level_left (nesting_level_left_),
- done_lookups_glyph_count (done_lookups_glyph_count_),
- done_lookups_glyph_set (done_lookups_glyph_set_)
- {}
-
- ~hb_closure_context_t () { flush (); }
-
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-
- void flush ()
- {
- output->del_range (face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */
- glyphs->union_ (*output);
- output->clear ();
- active_glyphs_stack.pop ();
- active_glyphs_stack.reset ();
- }
-
- private:
- hb_map_t *done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set;
- unsigned int lookup_count = 0;
-};
-
-
-
-struct hb_closure_lookups_context_t :
- hb_dispatch_context_t<hb_closure_lookups_context_t>
-{
- typedef return_t (*recurse_func_t) (hb_closure_lookups_context_t *c, unsigned lookup_index);
- template <typename T>
- return_t dispatch (const T &obj) { obj.closure_lookups (this); return hb_empty_t (); }
- static return_t default_return_value () { return hb_empty_t (); }
- void recurse (unsigned lookup_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func))
- return;
-
- /* Return if new lookup was recursed to before. */
- if (lookup_limit_exceeded ()
- || visited_lookups->in_error ()
- || visited_lookups->has (lookup_index))
- // Don't increment lookup count here, that will be done in the call to closure_lookups()
- // made by recurse_func.
- return;
-
- nesting_level_left--;
- recurse_func (this, lookup_index);
- nesting_level_left++;
- }
-
- void set_lookup_visited (unsigned lookup_index)
- { visited_lookups->add (lookup_index); }
-
- void set_lookup_inactive (unsigned lookup_index)
- { inactive_lookups->add (lookup_index); }
-
- bool lookup_limit_exceeded ()
- {
- bool ret = lookup_count > HB_MAX_LOOKUP_VISIT_COUNT;
- if (ret)
- DEBUG_MSG (SUBSET, nullptr, "lookup visit count limit exceeded in lookup closure!");
- return ret; }
-
- bool is_lookup_visited (unsigned lookup_index)
- {
- if (unlikely (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT))
- {
- DEBUG_MSG (SUBSET, nullptr, "total visited lookup count %u exceeds max limit, lookup %u is dropped.",
- lookup_count, lookup_index);
- return true;
- }
-
- if (unlikely (visited_lookups->in_error ()))
- return true;
-
- return visited_lookups->has (lookup_index);
- }
-
- hb_face_t *face;
- const hb_set_t *glyphs;
- recurse_func_t recurse_func;
- unsigned int nesting_level_left;
-
- hb_closure_lookups_context_t (hb_face_t *face_,
- const hb_set_t *glyphs_,
- hb_set_t *visited_lookups_,
- hb_set_t *inactive_lookups_,
- unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
- face (face_),
- glyphs (glyphs_),
- recurse_func (nullptr),
- nesting_level_left (nesting_level_left_),
- visited_lookups (visited_lookups_),
- inactive_lookups (inactive_lookups_),
- lookup_count (0) {}
-
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-
- private:
- hb_set_t *visited_lookups;
- hb_set_t *inactive_lookups;
- unsigned int lookup_count;
-};
-
-struct hb_would_apply_context_t :
- hb_dispatch_context_t<hb_would_apply_context_t, bool>
-{
- template <typename T>
- return_t dispatch (const T &obj) { return obj.would_apply (this); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- hb_face_t *face;
- const hb_codepoint_t *glyphs;
- unsigned int len;
- bool zero_context;
-
- hb_would_apply_context_t (hb_face_t *face_,
- const hb_codepoint_t *glyphs_,
- unsigned int len_,
- bool zero_context_) :
- face (face_),
- glyphs (glyphs_),
- len (len_),
- zero_context (zero_context_) {}
-};
-
-struct hb_collect_glyphs_context_t :
- hb_dispatch_context_t<hb_collect_glyphs_context_t>
-{
- typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
- template <typename T>
- return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); }
- static return_t default_return_value () { return hb_empty_t (); }
- void recurse (unsigned int lookup_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func))
- return;
-
- /* 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.
- *
- * Note further, that the above is not exactly correct. A recursed lookup
- * is allowed to match input that is not matched in the context, but that's
- * not how most fonts are built. It's possible to relax that and recurse
- * with all sets here if it proves to be an issue.
- */
-
- if (output == hb_set_get_empty ())
- return;
-
- /* Return if new lookup was recursed to before. */
- if (recursed_lookups->has (lookup_index))
- return;
-
- hb_set_t *old_before = before;
- hb_set_t *old_input = input;
- hb_set_t *old_after = after;
- before = input = after = hb_set_get_empty ();
-
- nesting_level_left--;
- recurse_func (this, lookup_index);
- nesting_level_left++;
-
- before = old_before;
- input = old_input;
- after = old_after;
-
- recursed_lookups->add (lookup_index);
- }
-
- hb_face_t *face;
- hb_set_t *before;
- hb_set_t *input;
- hb_set_t *after;
- hb_set_t *output;
- recurse_func_t recurse_func;
- hb_set_t *recursed_lookups;
- unsigned int nesting_level_left;
-
- 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 */
- 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 (nullptr),
- recursed_lookups (hb_set_create ()),
- nesting_level_left (nesting_level_left_) {}
- ~hb_collect_glyphs_context_t () { hb_set_destroy (recursed_lookups); }
-
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-};
-
-
-
-template <typename set_t>
-struct hb_collect_coverage_context_t :
- hb_dispatch_context_t<hb_collect_coverage_context_t<set_t>, const Coverage &>
-{
- typedef const Coverage &return_t; // Stoopid that we have to dupe this here.
- template <typename T>
- return_t dispatch (const T &obj) { return obj.get_coverage (); }
- static return_t default_return_value () { return Null (Coverage); }
- bool stop_sublookup_iteration (return_t r) const
- {
- r.collect_coverage (set);
- return false;
- }
-
- hb_collect_coverage_context_t (set_t *set_) :
- set (set_) {}
-
- set_t *set;
-};
-
-struct hb_ot_apply_context_t :
- hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY>
-{
- struct matcher_t
- {
- matcher_t () :
- lookup_props (0),
- mask (-1),
- ignore_zwnj (false),
- ignore_zwj (false),
- per_syllable (false),
- syllable {0},
- match_func (nullptr),
- match_data (nullptr) {}
-
- typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
-
- void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
- void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
- void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
- void set_mask (hb_mask_t mask_) { mask = mask_; }
- void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; }
- void set_syllable (uint8_t syllable_) { syllable = per_syllable ? syllable_ : 0; }
- void set_match_func (match_func_t match_func_,
- const void *match_data_)
- { match_func = match_func_; match_data = match_data_; }
-
- enum may_match_t {
- MATCH_NO,
- MATCH_YES,
- MATCH_MAYBE
- };
-
- may_match_t may_match (hb_glyph_info_t &info,
- hb_codepoint_t glyph_data) const
- {
- if (!(info.mask & mask) ||
- (syllable && syllable != info.syllable ()))
- return MATCH_NO;
-
- if (match_func)
- return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO;
-
- return MATCH_MAYBE;
- }
-
- enum may_skip_t {
- SKIP_NO,
- SKIP_YES,
- SKIP_MAYBE
- };
-
- may_skip_t may_skip (const hb_ot_apply_context_t *c,
- const hb_glyph_info_t &info) const
- {
- if (!c->check_glyph_property (&info, lookup_props))
- return SKIP_YES;
-
- 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;
-
- return SKIP_NO;
- }
-
- protected:
- unsigned int lookup_props;
- hb_mask_t mask;
- bool ignore_zwnj;
- bool ignore_zwj;
- bool per_syllable;
- uint8_t syllable;
- match_func_t match_func;
- const void *match_data;
- };
-
- struct skipping_iterator_t
- {
- void init (hb_ot_apply_context_t *c_, bool context_match = false)
- {
- c = c_;
- match_glyph_data16 = nullptr;
-#ifndef HB_NO_BEYOND_64K
- match_glyph_data24 = nullptr;
-#endif
- matcher.set_match_func (nullptr, nullptr);
- matcher.set_lookup_props (c->lookup_props);
- /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */
- matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj));
- /* Ignore ZWJ if we are matching context, or asked to. */
- matcher.set_ignore_zwj (context_match || c->auto_zwj);
- matcher.set_mask (context_match ? -1 : c->lookup_mask);
- /* Per syllable matching is only for GSUB. */
- matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
- }
- void set_lookup_props (unsigned int lookup_props)
- {
- matcher.set_lookup_props (lookup_props);
- }
- void set_match_func (matcher_t::match_func_t match_func_,
- const void *match_data_)
- {
- matcher.set_match_func (match_func_, match_data_);
- }
- void set_glyph_data (const HBUINT16 glyph_data[])
- {
- match_glyph_data16 = glyph_data;
-#ifndef HB_NO_BEYOND_64K
- match_glyph_data24 = nullptr;
-#endif
- }
-#ifndef HB_NO_BEYOND_64K
- void set_glyph_data (const HBUINT24 glyph_data[])
- {
- match_glyph_data16 = nullptr;
- match_glyph_data24 = glyph_data;
- }
-#endif
-
- void reset (unsigned int start_index_,
- unsigned int num_items_)
- {
- idx = start_index_;
- num_items = num_items_;
- end = c->buffer->len;
- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
- }
-
- void reject ()
- {
- num_items++;
- backup_glyph_data ();
- }
-
- matcher_t::may_skip_t
- may_skip (const hb_glyph_info_t &info) const
- { return matcher.may_skip (c, info); }
-
- enum match_t {
- MATCH,
- NOT_MATCH,
- SKIP
- };
-
- match_t match (hb_glyph_info_t &info)
- {
- matcher_t::may_skip_t skip = matcher.may_skip (c, info);
- if (unlikely (skip == matcher_t::SKIP_YES))
- return SKIP;
-
- matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ());
- if (match == matcher_t::MATCH_YES ||
- (match == matcher_t::MATCH_MAYBE &&
- skip == matcher_t::SKIP_NO))
- return MATCH;
-
- if (skip == matcher_t::SKIP_NO)
- return NOT_MATCH;
-
- return SKIP;
- }
-
- bool next (unsigned *unsafe_to = nullptr)
- {
- assert (num_items > 0);
- /* The alternate condition below is faster at string boundaries,
- * but produces subpar "unsafe-to-concat" values. */
- signed stop = (signed) end - (signed) num_items;
- if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
- stop = (signed) end - 1;
- while ((signed) idx < stop)
- {
- idx++;
- switch (match (c->buffer->info[idx]))
- {
- case MATCH:
- {
- num_items--;
- advance_glyph_data ();
- return true;
- }
- case NOT_MATCH:
- {
- if (unsafe_to)
- *unsafe_to = idx + 1;
- return false;
- }
- case SKIP:
- continue;
- }
- }
- if (unsafe_to)
- *unsafe_to = end;
- return false;
- }
- bool prev (unsigned *unsafe_from = nullptr)
- {
- assert (num_items > 0);
- /* The alternate condition below is faster at string boundaries,
- * but produces subpar "unsafe-to-concat" values. */
- unsigned stop = num_items - 1;
- if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
- stop = 1 - 1;
- while (idx > stop)
- {
- idx--;
- switch (match (c->buffer->out_info[idx]))
- {
- case MATCH:
- {
- num_items--;
- advance_glyph_data ();
- return true;
- }
- case NOT_MATCH:
- {
- if (unsafe_from)
- *unsafe_from = hb_max (1u, idx) - 1u;
- return false;
- }
- case SKIP:
- continue;
- }
- }
- if (unsafe_from)
- *unsafe_from = 0;
- return false;
- }
-
- hb_codepoint_t
- get_glyph_data ()
- {
- if (match_glyph_data16) return *match_glyph_data16;
-#ifndef HB_NO_BEYOND_64K
- else
- if (match_glyph_data24) return *match_glyph_data24;
-#endif
- return 0;
- }
- void
- advance_glyph_data ()
- {
- if (match_glyph_data16) match_glyph_data16++;
-#ifndef HB_NO_BEYOND_64K
- else
- if (match_glyph_data24) match_glyph_data24++;
-#endif
- }
- void
- backup_glyph_data ()
- {
- if (match_glyph_data16) match_glyph_data16--;
-#ifndef HB_NO_BEYOND_64K
- else
- if (match_glyph_data24) match_glyph_data24--;
-#endif
- }
-
- unsigned int idx;
- protected:
- hb_ot_apply_context_t *c;
- matcher_t matcher;
- const HBUINT16 *match_glyph_data16;
-#ifndef HB_NO_BEYOND_64K
- const HBUINT24 *match_glyph_data24;
-#endif
-
- unsigned int num_items;
- unsigned int end;
- };
-
-
- const char *get_name () { return "APPLY"; }
- typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index);
- template <typename T>
- return_t dispatch (const T &obj) { return obj.apply (this); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
- return_t recurse (unsigned int sub_lookup_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
- {
- buffer->shaping_failed = true;
- return default_return_value ();
- }
-
- nesting_level_left--;
- bool ret = recurse_func (this, sub_lookup_index);
- nesting_level_left++;
- return ret;
- }
-
- skipping_iterator_t iter_input, iter_context;
-
- unsigned int table_index; /* GSUB/GPOS */
- hb_font_t *font;
- hb_face_t *face;
- hb_buffer_t *buffer;
- recurse_func_t recurse_func = nullptr;
- const GDEF &gdef;
- const VariationStore &var_store;
- VariationStore::cache_t *var_store_cache;
- hb_set_digest_t digest;
-
- hb_direction_t direction;
- hb_mask_t lookup_mask = 1;
- unsigned int lookup_index = (unsigned) -1;
- unsigned int lookup_props = 0;
- unsigned int nesting_level_left = HB_MAX_NESTING_LEVEL;
-
- bool has_glyph_classes;
- bool auto_zwnj = true;
- bool auto_zwj = true;
- bool per_syllable = false;
- bool random = false;
- uint32_t random_state = 1;
- unsigned new_syllables = (unsigned) -1;
-
- signed last_base = -1; // GPOS uses
- unsigned last_base_until = 0; // GPOS uses
-
- hb_ot_apply_context_t (unsigned int table_index_,
- hb_font_t *font_,
- hb_buffer_t *buffer_) :
- table_index (table_index_),
- font (font_), face (font->face), buffer (buffer_),
- gdef (
-#ifndef HB_NO_OT_LAYOUT
- *face->table.GDEF->table
-#else
- Null (GDEF)
-#endif
- ),
- var_store (gdef.get_var_store ()),
- var_store_cache (
-#ifndef HB_NO_VAR
- table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr
-#else
- nullptr
-#endif
- ),
- digest (buffer_->digest ()),
- direction (buffer_->props.direction),
- has_glyph_classes (gdef.has_glyph_classes ())
- { init_iters (); }
-
- ~hb_ot_apply_context_t ()
- {
-#ifndef HB_NO_VAR
- VariationStore::destroy_cache (var_store_cache);
-#endif
- }
-
- void init_iters ()
- {
- iter_input.init (this, false);
- iter_context.init (this, true);
- }
-
- void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; last_base = -1; last_base_until = 0; init_iters (); }
- void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
- void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
- void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
- void set_random (bool random_) { random = random_; }
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
- void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
- void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); }
-
- uint32_t random_number ()
- {
- /* http://www.cplusplus.com/reference/random/minstd_rand/ */
- random_state = random_state * 48271 % 2147483647;
- return random_state;
- }
-
- bool match_properties_mark (hb_codepoint_t glyph,
- unsigned int glyph_props,
- unsigned int match_props) const
- {
- /* If using mark filtering sets, the high short of
- * match_props has the set index.
- */
- if (match_props & LookupFlag::UseMarkFilteringSet)
- return gdef.mark_set_covers (match_props >> 16, glyph);
-
- /* The second byte of match_props has the meaning
- * "ignore marks of attachment type different than
- * the attachment type specified."
- */
- if (match_props & LookupFlag::MarkAttachmentType)
- return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
-
- return true;
- }
-
- bool check_glyph_property (const hb_glyph_info_t *info,
- unsigned int match_props) const
- {
- hb_codepoint_t glyph = info->codepoint;
- unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
-
- /* Not covered, if, for example, glyph class is ligature and
- * match_props includes LookupFlags::IgnoreLigatures
- */
- if (glyph_props & match_props & LookupFlag::IgnoreFlags)
- return false;
-
- if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
- return match_properties_mark (glyph, glyph_props, match_props);
-
- return true;
- }
-
- void _set_glyph_class (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0,
- bool ligature = false,
- bool component = false)
- {
- digest.add (glyph_index);
-
- if (new_syllables != (unsigned) -1)
- buffer->cur().syllable() = new_syllables;
-
- unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
- props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
- if (ligature)
- {
- props |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
- /* In the only place that the MULTIPLIED bit is used, Uniscribe
- * seems to only care about the "last" transformation between
- * Ligature and Multiple substitutions. Ie. if you ligate, expand,
- * and ligate again, it forgives the multiplication and acts as
- * if only ligation happened. As such, clear MULTIPLIED bit.
- */
- props &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
- }
- if (component)
- props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
- if (likely (has_glyph_classes))
- {
- props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
- _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
- }
- else if (class_guess)
- {
- props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
- _hb_glyph_info_set_glyph_props (&buffer->cur(), props | class_guess);
- }
- else
- _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
- }
-
- void replace_glyph (hb_codepoint_t glyph_index)
- {
- _set_glyph_class (glyph_index);
- (void) buffer->replace_glyph (glyph_index);
- }
- void replace_glyph_inplace (hb_codepoint_t glyph_index)
- {
- _set_glyph_class (glyph_index);
- buffer->cur().codepoint = glyph_index;
- }
- void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
- unsigned int class_guess)
- {
- _set_glyph_class (glyph_index, class_guess, true);
- (void) buffer->replace_glyph (glyph_index);
- }
- void output_glyph_for_component (hb_codepoint_t glyph_index,
- unsigned int class_guess)
- {
- _set_glyph_class (glyph_index, class_guess, false, true);
- (void) buffer->output_glyph (glyph_index);
- }
-};
-
-
-struct hb_accelerate_subtables_context_t :
- hb_dispatch_context_t<hb_accelerate_subtables_context_t>
-{
- template <typename Type>
- static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c)
- {
- const Type *typed_obj = (const Type *) obj;
- return typed_obj->apply (c);
- }
-
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
- template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
- template <typename Type>
- static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c)
- {
- const Type *typed_obj = (const Type *) obj;
- return apply_cached_ (typed_obj, c, hb_prioritize);
- }
-
- template <typename T>
- static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) )
- template <typename T>
- static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; }
- template <typename Type>
- static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter)
- {
- const Type *typed_obj = (const Type *) obj;
- return cache_func_ (typed_obj, c, enter, hb_prioritize);
- }
-#endif
-
- typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c);
- typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter);
-
- struct hb_applicable_t
- {
- friend struct hb_accelerate_subtables_context_t;
- friend struct hb_ot_layout_lookup_accelerator_t;
-
- template <typename T>
- void init (const T &obj_,
- hb_apply_func_t apply_func_
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- , hb_apply_func_t apply_cached_func_
- , hb_cache_func_t cache_func_
-#endif
- )
- {
- obj = &obj_;
- apply_func = apply_func_;
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- apply_cached_func = apply_cached_func_;
- cache_func = cache_func_;
-#endif
- digest.init ();
- obj_.get_coverage ().collect_coverage (&digest);
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
- }
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- bool apply_cached (hb_ot_apply_context_t *c) const
- {
- return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c);
- }
- bool cache_enter (hb_ot_apply_context_t *c) const
- {
- return cache_func (obj, c, true);
- }
- void cache_leave (hb_ot_apply_context_t *c) const
- {
- cache_func (obj, c, false);
- }
-#endif
-
- private:
- const void *obj;
- hb_apply_func_t apply_func;
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- hb_apply_func_t apply_cached_func;
- hb_cache_func_t cache_func;
-#endif
- hb_set_digest_t digest;
- };
-
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- template <typename T>
- auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () )
- template <typename T>
- auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u )
-#endif
-
- /* Dispatch interface. */
- template <typename T>
- return_t dispatch (const T &obj)
- {
- hb_applicable_t *entry = &array[i++];
-
- entry->init (obj,
- apply_to<T>
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- , apply_cached_to<T>
- , cache_func_to<T>
-#endif
- );
-
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- /* Cache handling
- *
- * We allow one subtable from each lookup to use a cache. The assumption
- * being that multiple subtables of the same lookup cannot use a cache
- * because the resources they would use will collide. As such, we ask
- * each subtable to tell us how much it costs (which a cache would avoid),
- * and we allocate the cache opportunity to the costliest subtable.
- */
- unsigned cost = cache_cost (obj, hb_prioritize);
- if (cost > cache_user_cost)
- {
- cache_user_idx = i - 1;
- cache_user_cost = cost;
- }
-#endif
-
- return hb_empty_t ();
- }
- static return_t default_return_value () { return hb_empty_t (); }
-
- hb_accelerate_subtables_context_t (hb_applicable_t *array_) :
- array (array_) {}
-
- hb_applicable_t *array;
- unsigned i = 0;
-
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- unsigned cache_user_idx = (unsigned) -1;
- unsigned cache_user_cost = 0;
-#endif
-};
-
-
-typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache);
-typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache);
-typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data);
-typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
-
-struct ContextClosureFuncs
-{
- intersects_func_t intersects;
- intersected_glyphs_func_t intersected_glyphs;
-};
-struct ContextCollectGlyphsFuncs
-{
- collect_glyphs_func_t collect;
-};
-struct ContextApplyFuncs
-{
- match_func_t match;
-};
-struct ChainContextApplyFuncs
-{
- match_func_t match[3];
-};
-
-
-static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED, void *cache HB_UNUSED)
-{
- return glyphs->has (value);
-}
-static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data, void *cache)
-{
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- hb_map_t *map = (hb_map_t *) cache;
-
- hb_codepoint_t *cached_v;
- if (map->has (value, &cached_v))
- return *cached_v;
-
- bool v = class_def.intersects_class (glyphs, value);
- map->set (value, v);
-
- return v;
-}
-static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data, void *cache HB_UNUSED)
-{
- Offset16To<Coverage> coverage;
- coverage = value;
- return (data+coverage).intersects (glyphs);
-}
-
-
-static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
-{
- unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value];
- intersected_glyphs->add (g);
-}
-
-using intersected_class_cache_t = hb_hashmap_t<unsigned, hb_set_t>;
-
-static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache)
-{
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
-
- intersected_class_cache_t *map = (intersected_class_cache_t *) cache;
-
- hb_set_t *cached_v;
- if (map->has (value, &cached_v))
- {
- intersected_glyphs->union_ (*cached_v);
- return;
- }
-
- hb_set_t v;
- class_def.intersected_class_glyphs (glyphs, value, &v);
-
- intersected_glyphs->union_ (v);
-
- map->set (value, std::move (v));
-}
-
-static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
-{
- Offset16To<Coverage> coverage;
- coverage = value;
- (data+coverage).intersect_set (*glyphs, *intersected_glyphs);
-}
-
-
-template <typename HBUINT>
-static inline bool array_is_subset_of (const hb_set_t *glyphs,
- unsigned int count,
- const HBUINT values[],
- intersects_func_t intersects_func,
- const void *intersects_data,
- void *cache)
-{
- for (const auto &_ : + hb_iter (values, count))
- if (!intersects_func (glyphs, _, intersects_data, cache)) return false;
- return true;
-}
-
-
-static inline void collect_glyph (hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED)
-{
- glyphs->add (value);
-}
-static inline void collect_class (hb_set_t *glyphs, unsigned value, const void *data)
-{
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- class_def.collect_class (glyphs, value);
-}
-static inline void collect_coverage (hb_set_t *glyphs, unsigned value, const void *data)
-{
- Offset16To<Coverage> coverage;
- coverage = value;
- (data+coverage).collect_coverage (glyphs);
-}
-template <typename HBUINT>
-static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
- hb_set_t *glyphs,
- unsigned int count,
- const HBUINT values[],
- collect_glyphs_func_t collect_func,
- const void *collect_data)
-{
- return
- + hb_iter (values, count)
- | hb_apply ([&] (const HBUINT &_) { collect_func (glyphs, _, collect_data); })
- ;
-}
-
-
-static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED)
-{
- return info.codepoint == value;
-}
-static inline bool match_class (hb_glyph_info_t &info, unsigned value, const void *data)
-{
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- return class_def.get_class (info.codepoint) == value;
-}
-static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data)
-{
- unsigned klass = info.syllable();
- if (klass < 255)
- return klass == value;
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
- klass = class_def.get_class (info.codepoint);
- if (likely (klass < 255))
- info.syllable() = klass;
- return klass == value;
-}
-static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data)
-{
- Offset16To<Coverage> coverage;
- coverage = value;
- return (data+coverage).get_coverage (info.codepoint) != NOT_COVERED;
-}
-
-template <typename HBUINT>
-static inline bool would_match_input (hb_would_apply_context_t *c,
- unsigned int count, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data)
-{
- if (count != c->len)
- return false;
-
- for (unsigned int i = 1; i < count; i++)
- {
- hb_glyph_info_t info;
- info.codepoint = c->glyphs[i];
- if (likely (!match_func (info, input[i - 1], match_data)))
- return false;
- }
-
- return true;
-}
-template <typename HBUINT>
-static inline bool match_input (hb_ot_apply_context_t *c,
- unsigned int count, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
- unsigned int *end_position,
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
- unsigned int *p_total_component_count = nullptr)
-{
- TRACE_APPLY (nullptr);
-
- if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false);
-
- hb_buffer_t *buffer = c->buffer;
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data);
- skippy_iter.set_glyph_data (input);
-
- /*
- * This is perhaps the trickiest part of OpenType... Remarks:
- *
- * - If all components of the ligature were marks, we call this a mark ligature.
- *
- * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize
- * it as a ligature glyph.
- *
- * - 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.
- * 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
- */
-
- unsigned int total_component_count = 0;
- total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
-
- 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++)
- {
- unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
- {
- *end_position = unsafe_to;
- return_trace (false);
- }
-
- match_positions[i] = skippy_iter.idx;
-
- 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 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... */
- if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
- {
- /* ...unless, we are attached to a base ligature and that base
- * ligature is ignorable. */
- if (ligbase == LIGBASE_NOT_CHECKED)
- {
- bool found = false;
- const auto *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 (out[j]) == hb_ot_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! */
- if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
- return_trace (false);
- }
-
- total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
- }
-
- *end_position = skippy_iter.idx + 1;
-
- if (p_total_component_count)
- *p_total_component_count = total_component_count;
-
- return_trace (true);
-}
-static inline bool ligate_input (hb_ot_apply_context_t *c,
- unsigned int count, /* Including the first glyph */
- const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
- unsigned int match_end,
- hb_codepoint_t lig_glyph,
- unsigned int total_component_count)
-{
- TRACE_APPLY (nullptr);
-
- hb_buffer_t *buffer = c->buffer;
-
- buffer->merge_clusters (buffer->idx, match_end);
-
- /* - If a base and one or more marks ligate, consider that as a base, NOT
- * ligature, such that all following marks can still attach to it.
- * https://github.com/harfbuzz/harfbuzz/issues/1109
- *
- * - If all components of the ligature were marks, we call this a mark ligature.
- * If it *is* a mark ligature, we don't allocate a new ligature id, and leave
- * the ligature to keep its old ligature id. This will allow it to attach to
- * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH,
- * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA with a
- * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature
- * later, we don't want them to lose their ligature id/component, otherwise
- * GPOS will fail to correctly position the mark ligature on top of the
- * LAM,LAM,HEH ligature. See:
- * https://bugzilla.gnome.org/show_bug.cgi?id=676343
- *
- * - If a ligature is formed of components that some of which are also ligatures
- * themselves, and those ligature components had marks attached to *their*
- * components, we have to attach the marks to the new ligature component
- * positions! Now *that*'s tricky! And these marks may be following the
- * last component of the whole sequence, so we should loop forward looking
- * for them and update them.
- *
- * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a
- * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature
- * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature
- * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to
- * the new ligature with a component value of 2.
- *
- * This in fact happened to a font... See:
- * https://bugzilla.gnome.org/show_bug.cgi?id=437633
- */
-
- bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]);
- bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]);
- for (unsigned int i = 1; i < count; i++)
- if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]]))
- {
- is_base_ligature = false;
- is_mark_ligature = false;
- break;
- }
- bool is_ligature = !is_base_ligature && !is_mark_ligature;
-
- unsigned int klass = is_ligature ? HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE : 0;
- unsigned int lig_id = is_ligature ? _hb_allocate_lig_id (buffer) : 0;
- unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
- unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
- unsigned int components_so_far = last_num_components;
-
- if (is_ligature)
- {
- _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
- if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
- {
- _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
- }
- }
- c->replace_glyph_with_ligature (lig_glyph, klass);
-
- for (unsigned int i = 1; i < count; i++)
- {
- while (buffer->idx < match_positions[i] && buffer->successful)
- {
- if (is_ligature)
- {
- unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
- if (this_comp == 0)
- this_comp = last_num_components;
- unsigned int new_lig_comp = components_so_far - last_num_components +
- hb_min (this_comp, last_num_components);
- _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
- }
- (void) buffer->next_glyph ();
- }
-
- last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
- last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
- components_so_far += last_num_components;
-
- /* Skip the base glyph */
- buffer->idx++;
- }
-
- if (!is_mark_ligature && last_lig_id)
- {
- /* Re-adjust components for any marks following. */
- for (unsigned i = buffer->idx; i < buffer->len; ++i)
- {
- if (last_lig_id != _hb_glyph_info_get_lig_id (&buffer->info[i])) break;
-
- unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
- if (!this_comp) break;
-
- unsigned new_lig_comp = components_so_far - last_num_components +
- hb_min (this_comp, last_num_components);
- _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
- }
- }
- return_trace (true);
-}
-
-template <typename HBUINT>
-static inline bool match_backtrack (hb_ot_apply_context_t *c,
- unsigned int count,
- const HBUINT backtrack[],
- match_func_t match_func,
- const void *match_data,
- unsigned int *match_start)
-{
- TRACE_APPLY (nullptr);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
- skippy_iter.reset (c->buffer->backtrack_len (), count);
- skippy_iter.set_match_func (match_func, match_data);
- skippy_iter.set_glyph_data (backtrack);
-
- for (unsigned int i = 0; i < count; i++)
- {
- unsigned unsafe_from;
- if (!skippy_iter.prev (&unsafe_from))
- {
- *match_start = unsafe_from;
- return_trace (false);
- }
- }
-
- *match_start = skippy_iter.idx;
- return_trace (true);
-}
-
-template <typename HBUINT>
-static inline bool match_lookahead (hb_ot_apply_context_t *c,
- unsigned int count,
- const HBUINT lookahead[],
- match_func_t match_func,
- const void *match_data,
- unsigned int start_index,
- unsigned int *end_index)
-{
- TRACE_APPLY (nullptr);
-
- hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
- skippy_iter.reset (start_index - 1, count);
- skippy_iter.set_match_func (match_func, match_data);
- skippy_iter.set_glyph_data (lookahead);
-
- for (unsigned int i = 0; i < count; i++)
- {
- unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
- {
- *end_index = unsafe_to;
- return_trace (false);
- }
- }
-
- *end_index = skippy_iter.idx + 1;
- return_trace (true);
-}
-
-
-
-struct LookupRecord
-{
- bool serialize (hb_serialize_context_t *c,
- const hb_map_t *lookup_map) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- return_trace (c->check_assign (out->lookupListIndex, lookup_map->get (lookupListIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 sequenceIndex; /* Index into current glyph
- * sequence--first glyph = 0 */
- HBUINT16 lookupListIndex; /* Lookup to apply to that
- * position--zero--based */
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c,
- const hb_array_t<const LookupRecord> lookupRecords,
- const hb_map_t *lookup_map)
-{
- unsigned count = 0;
- for (const LookupRecord& r : lookupRecords)
- {
- if (!lookup_map->has (r.lookupListIndex))
- continue;
-
- if (!r.serialize (c, lookup_map))
- return 0;
-
- count++;
- }
- return count;
-}
-
-enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 };
-
-template <typename HBUINT>
-static void context_closure_recurse_lookups (hb_closure_context_t *c,
- unsigned inputCount, const HBUINT input[],
- unsigned lookupCount,
- const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */,
- unsigned value,
- ContextFormat context_format,
- const void *data,
- intersected_glyphs_func_t intersected_glyphs_func,
- void *cache)
-{
- hb_set_t covered_seq_indicies;
- hb_set_t pos_glyphs;
- for (unsigned int i = 0; i < lookupCount; i++)
- {
- unsigned seqIndex = lookupRecord[i].sequenceIndex;
- if (seqIndex >= inputCount) continue;
-
- bool has_pos_glyphs = false;
-
- if (!covered_seq_indicies.has (seqIndex))
- {
- has_pos_glyphs = true;
- pos_glyphs.clear ();
- if (seqIndex == 0)
- {
- switch (context_format) {
- case ContextFormat::SimpleContext:
- pos_glyphs.add (value);
- break;
- case ContextFormat::ClassBasedContext:
- intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs, cache);
- break;
- case ContextFormat::CoverageBasedContext:
- pos_glyphs.set (c->parent_active_glyphs ());
- break;
- }
- }
- else
- {
- const void *input_data = input;
- unsigned input_value = seqIndex - 1;
- if (context_format != ContextFormat::SimpleContext)
- {
- input_data = data;
- input_value = input[seqIndex - 1];
- }
-
- intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs, cache);
- }
- }
-
- covered_seq_indicies.add (seqIndex);
- if (has_pos_glyphs) {
- c->push_cur_active_glyphs () = std::move (pos_glyphs);
- } else {
- c->push_cur_active_glyphs ().set (*c->glyphs);
- }
-
- unsigned endIndex = inputCount;
- if (context_format == ContextFormat::CoverageBasedContext)
- endIndex += 1;
-
- c->recurse (lookupRecord[i].lookupListIndex, &covered_seq_indicies, seqIndex, endIndex);
-
- c->pop_cur_done_glyphs ();
- }
-}
-
-template <typename context_t>
-static inline void recurse_lookups (context_t *c,
- unsigned int lookupCount,
- const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
-{
- for (unsigned int i = 0; i < lookupCount; i++)
- c->recurse (lookupRecord[i].lookupListIndex);
-}
-
-static inline void apply_lookup (hb_ot_apply_context_t *c,
- unsigned int count, /* Including the first glyph */
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
- unsigned int match_end)
-{
- hb_buffer_t *buffer = c->buffer;
- int end;
-
- /* All positions are distance from beginning of *output* buffer.
- * Adjust. */
- {
- unsigned int bl = buffer->backtrack_len ();
- end = bl + match_end - buffer->idx;
-
- int delta = bl - buffer->idx;
- /* Convert positions to new indexing. */
- for (unsigned int j = 0; j < count; j++)
- match_positions[j] += delta;
- }
-
- for (unsigned int i = 0; i < lookupCount && buffer->successful; i++)
- {
- unsigned int idx = lookupRecord[i].sequenceIndex;
- if (idx >= count)
- continue;
-
- unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
-
- /* This can happen if earlier recursed lookups deleted many entries. */
- if (unlikely (match_positions[idx] >= orig_len))
- continue;
-
- if (unlikely (!buffer->move_to (match_positions[idx])))
- break;
-
- if (unlikely (buffer->max_ops <= 0))
- break;
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- if (buffer->have_output)
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "recursing to lookup %u at %u",
- (unsigned) lookupRecord[i].lookupListIndex,
- buffer->idx);
- }
-
- if (!c->recurse (lookupRecord[i].lookupListIndex))
- continue;
-
- if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
- {
- if (buffer->have_output)
- c->buffer->sync_so_far ();
- c->buffer->message (c->font,
- "recursed to lookup %u",
- (unsigned) lookupRecord[i].lookupListIndex);
- }
-
- unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
- int delta = new_len - orig_len;
-
- if (!delta)
- continue;
-
- /* 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 recursed-to
- * lookup might had a different LookupFlag. Here's a constructed
- * case of that:
- * https://github.com/harfbuzz/harfbuzz/discussions/3538
- *
- * It should be possible to construct tests for both of these cases.
- */
-
- 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.
- * Just never rewind end beyond start of current position, since that is
- * not possible in the recursed lookup. Also adjust delta as such.
- *
- * https://bugs.chromium.org/p/chromium/issues/detail?id=659496
- * https://github.com/harfbuzz/harfbuzz/issues/1611
- */
- delta += match_positions[idx] - end;
- end = match_positions[idx];
- }
-
- unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
-
- if (delta > 0)
- {
- if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH))
- break;
- }
- else
- {
- /* NOTE: delta is non-positive. */
- delta = hb_max (delta, (int) next - (int) count);
- next -= delta;
- }
-
- /* Shift! */
- memmove (match_positions + next + delta, match_positions + next,
- (count - next) * sizeof (match_positions[0]));
- next += delta;
- count += delta;
-
- /* Fill in new entries. */
- for (unsigned int j = idx + 1; j < next; j++)
- match_positions[j] = match_positions[j - 1] + 1;
-
- /* And fixup the rest. */
- for (; next < count; next++)
- match_positions[next] += delta;
- }
-
- (void) buffer->move_to (end);
-}
-
-
-
-/* Contextual lookups */
-
-struct ContextClosureLookupContext
-{
- ContextClosureFuncs funcs;
- ContextFormat context_format;
- const void *intersects_data;
- void *intersects_cache;
- void *intersected_glyphs_cache;
-};
-
-struct ContextCollectGlyphsLookupContext
-{
- ContextCollectGlyphsFuncs funcs;
- const void *collect_data;
-};
-
-struct ContextApplyLookupContext
-{
- ContextApplyFuncs funcs;
- const void *match_data;
-};
-
-template <typename HBUINT>
-static inline bool context_intersects (const hb_set_t *glyphs,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- ContextClosureLookupContext &lookup_context)
-{
- return array_is_subset_of (glyphs,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects,
- lookup_context.intersects_data,
- lookup_context.intersects_cache);
-}
-
-template <typename HBUINT>
-static inline void context_closure_lookup (hb_closure_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- unsigned value, /* Index of first glyph in Coverage or Class value in ClassDef table */
- ContextClosureLookupContext &lookup_context)
-{
- if (context_intersects (c->glyphs,
- inputCount, input,
- lookup_context))
- context_closure_recurse_lookups (c,
- inputCount, input,
- lookupCount, lookupRecord,
- value,
- lookup_context.context_format,
- lookup_context.intersects_data,
- lookup_context.funcs.intersected_glyphs,
- lookup_context.intersected_glyphs_cache);
-}
-
-template <typename HBUINT>
-static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- ContextCollectGlyphsLookupContext &lookup_context)
-{
- collect_array (c, c->input,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.collect, lookup_context.collect_data);
- recurse_lookups (c,
- lookupCount, lookupRecord);
-}
-
-template <typename HBUINT>
-static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount HB_UNUSED,
- const LookupRecord lookupRecord[] HB_UNUSED,
- const ContextApplyLookupContext &lookup_context)
-{
- return would_match_input (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data);
-}
-
-template <typename HBUINT>
-static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- const ContextApplyLookupContext &lookup_context)
-{
- unsigned match_end = 0;
- unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
- if (match_input (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data,
- &match_end, match_positions))
- {
- c->buffer->unsafe_to_break (c->buffer->idx, match_end);
- apply_lookup (c,
- inputCount, match_positions,
- lookupCount, lookupRecord,
- match_end);
- return true;
- }
- else
- {
- c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
- return false;
- }
-}
-
-template <typename Types>
-struct Rule
-{
- bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
- {
- return context_intersects (glyphs,
- inputCount, inputZ.arrayZ,
- lookup_context);
- }
-
- void closure (hb_closure_context_t *c, unsigned value, ContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
-
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
- context_closure_lookup (c,
- inputCount, inputZ.arrayZ,
- lookupCount, lookupRecord.arrayZ,
- value, lookup_context);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c,
- ContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
- if (!intersects (c->glyphs, lookup_context)) return;
-
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array (inputCount ? inputCount - 1 : 0));
- recurse_lookups (c, lookupCount, lookupRecord.arrayZ);
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- ContextCollectGlyphsLookupContext &lookup_context) const
- {
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array (inputCount ? inputCount - 1 : 0));
- context_collect_glyphs_lookup (c,
- inputCount, inputZ.arrayZ,
- lookupCount, lookupRecord.arrayZ,
- lookup_context);
- }
-
- bool would_apply (hb_would_apply_context_t *c,
- const ContextApplyLookupContext &lookup_context) const
- {
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array (inputCount ? inputCount - 1 : 0));
- return context_would_apply_lookup (c,
- inputCount, inputZ.arrayZ,
- lookupCount, lookupRecord.arrayZ,
- lookup_context);
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ContextApplyLookupContext &lookup_context) const
- {
- TRACE_APPLY (this);
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array (inputCount ? inputCount - 1 : 0));
- return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
- }
-
- bool serialize (hb_serialize_context_t *c,
- const hb_map_t *input_mapping, /* old->new glyphid or class mapping */
- const hb_map_t *lookup_map) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!c->extend_min (out))) return_trace (false);
-
- out->inputCount = inputCount;
- const auto input = inputZ.as_array (inputCount - 1);
- for (const auto org : input)
- {
- HBUINT16 d;
- d = input_mapping->get (org);
- c->copy (d);
- }
-
- const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
- (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
-
- unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map);
- return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_map_t *lookup_map,
- const hb_map_t *klass_map = nullptr) const
- {
- TRACE_SUBSET (this);
- if (unlikely (!inputCount)) return_trace (false);
- const auto input = inputZ.as_array (inputCount - 1);
-
- const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map;
- if (!hb_all (input, mapping)) return_trace (false);
- return_trace (serialize (c->serializer, mapping, lookup_map));
- }
-
- public:
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (inputCount.sanitize (c) &&
- lookupCount.sanitize (c) &&
- c->check_range (inputZ.arrayZ,
- inputZ.item_size * (inputCount ? inputCount - 1 : 0) +
- LookupRecord::static_size * lookupCount));
- }
-
- protected:
- HBUINT16 inputCount; /* Total number of glyphs in input
- * glyph sequence--includes the first
- * glyph */
- HBUINT16 lookupCount; /* Number of LookupRecords */
- UnsizedArrayOf<typename Types::HBUINT>
- inputZ; /* Array of match inputs--start with
- * second glyph */
-/*UnsizedArrayOf<LookupRecord>
- lookupRecordX;*/ /* Array of LookupRecords--in
- * design order */
- public:
- DEFINE_SIZE_ARRAY (4, inputZ);
-};
-
-template <typename Types>
-struct RuleSet
-{
- using Rule = OT::Rule<Types>;
-
- bool intersects (const hb_set_t *glyphs,
- ContextClosureLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const Rule &_) { return _.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
-
- void closure (hb_closure_context_t *c, unsigned value,
- ContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
-
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const Rule &_) { _.closure (c, value, lookup_context); })
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c,
- ContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const Rule &_) { _.closure_lookups (c, lookup_context); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- ContextCollectGlyphsLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const Rule &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c,
- const ContextApplyLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const Rule &_) { return _.would_apply (c, lookup_context); })
- | hb_any
- ;
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ContextApplyLookupContext &lookup_context) const
- {
- TRACE_APPLY (this);
- return_trace (
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
- | hb_any
- )
- ;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_map_t *lookup_map,
- const hb_map_t *klass_map = nullptr) const
- {
- TRACE_SUBSET (this);
-
- auto snap = c->serializer->snapshot ();
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const Offset16To<Rule>& _ : rule)
- {
- if (!_) continue;
- auto o_snap = c->serializer->snapshot ();
- auto *o = out->rule.serialize_append (c->serializer);
- if (unlikely (!o)) continue;
-
- if (!o->serialize_subset (c, _, this, lookup_map, klass_map))
- {
- out->rule.pop ();
- c->serializer->revert (o_snap);
- }
- }
-
- bool ret = bool (out->rule);
- if (!ret) c->serializer->revert (snap);
-
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (rule.sanitize (c, this));
- }
-
- protected:
- Array16OfOffset16To<Rule>
- rule; /* Array of Rule tables
- * ordered by preference */
- public:
- DEFINE_SIZE_ARRAY (2, rule);
-};
-
-
-template <typename Types>
-struct ContextFormat1_4
-{
- using RuleSet = OT::RuleSet<Types>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- struct ContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
- ContextFormat::SimpleContext,
- nullptr
- };
-
- return
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (*glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_map ([&] (const RuleSet &_) { return _.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs);
-
- struct ContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
- ContextFormat::SimpleContext,
- nullptr
- };
-
- + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
- | hb_filter ([&] (hb_codepoint_t _) {
- return c->previous_parent_active_glyphs ().has (_);
- }, hb_first)
- | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); })
- | hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
- ;
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- struct ContextClosureLookupContext lookup_context = {
- {intersects_glyph, nullptr},
- ContextFormat::SimpleContext,
- nullptr
- };
-
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (*c->glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c, lookup_context); })
- ;
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- (this+coverage).collect_coverage (c->input);
-
- struct ContextCollectGlyphsLookupContext lookup_context = {
- {collect_glyph},
- nullptr
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
- struct ContextApplyLookupContext lookup_context = {
- {match_glyph},
- nullptr
- };
- return rule_set.would_apply (c, lookup_context);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED))
- return_trace (false);
-
- const RuleSet &rule_set = this+ruleSet[index];
- struct ContextApplyLookupContext lookup_context = {
- {match_glyph},
- nullptr
- };
- return_trace (rule_set.apply (c, lookup_context));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of table */
- Array16Of<typename Types::template OffsetTo<RuleSet>>
- ruleSet; /* Array of RuleSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet);
-};
-
-
-template <typename Types>
-struct ContextFormat2_5
-{
- using RuleSet = OT::RuleSet<SmallTypes>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (!(this+coverage).intersects (glyphs))
- return false;
-
- const ClassDef &class_def = this+classDef;
-
- hb_map_t cache;
- struct ContextClosureLookupContext lookup_context = {
- {intersects_class, nullptr},
- ContextFormat::ClassBasedContext,
- &class_def,
- &cache
- };
-
- hb_set_t retained_coverage_glyphs;
- (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs);
-
- hb_set_t coverage_glyph_classes;
- class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
-
-
- return
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_enumerate
- | hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
- { return class_def.intersects_class (glyphs, p.first) &&
- coverage_glyph_classes.has (p.first) &&
- p.second.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- if (!(this+coverage).intersects (c->glyphs))
- return;
-
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
- cur_active_glyphs);
-
- const ClassDef &class_def = this+classDef;
-
- hb_map_t cache;
- intersected_class_cache_t intersected_cache;
- struct ContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
- ContextFormat::ClassBasedContext,
- &class_def,
- &cache,
- &intersected_cache
- };
-
- + hb_enumerate (ruleSet)
- | hb_filter ([&] (unsigned _)
- { return class_def.intersects_class (&c->parent_active_glyphs (), _); },
- hb_first)
- | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<RuleSet>&> _)
- {
- const RuleSet& rule_set = this+_.second;
- rule_set.closure (c, _.first, lookup_context);
- })
- ;
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- if (!(this+coverage).intersects (c->glyphs))
- return;
-
- const ClassDef &class_def = this+classDef;
-
- hb_map_t cache;
- struct ContextClosureLookupContext lookup_context = {
- {intersects_class, nullptr},
- ContextFormat::ClassBasedContext,
- &class_def,
- &cache
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_enumerate
- | hb_filter ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
- { return class_def.intersects_class (c->glyphs, p.first); })
- | hb_map (hb_second)
- | hb_apply ([&] (const RuleSet & _)
- { _.closure_lookups (c, lookup_context); });
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- (this+coverage).collect_coverage (c->input);
-
- const ClassDef &class_def = this+classDef;
- struct ContextCollectGlyphsLookupContext lookup_context = {
- {collect_class},
- &class_def
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const ClassDef &class_def = this+classDef;
- unsigned int index = class_def.get_class (c->glyphs[0]);
- const RuleSet &rule_set = this+ruleSet[index];
- struct ContextApplyLookupContext lookup_context = {
- {match_class},
- &class_def
- };
- return rule_set.would_apply (c, lookup_context);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- unsigned cache_cost () const
- {
- unsigned c = (this+classDef).cost () * ruleSet.len;
- return c >= 4 ? c : 0;
- }
- bool cache_func (hb_ot_apply_context_t *c, bool enter) const
- {
- if (enter)
- {
- if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
- return false;
- auto &info = c->buffer->info;
- unsigned count = c->buffer->len;
- for (unsigned i = 0; i < count; i++)
- info[i].syllable() = 255;
- c->new_syllables = 255;
- return true;
- }
- else
- {
- c->new_syllables = (unsigned) -1;
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
- return true;
- }
- }
-
- bool apply (hb_ot_apply_context_t *c, bool cached = false) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const ClassDef &class_def = this+classDef;
-
- struct ContextApplyLookupContext lookup_context = {
- {cached ? match_class_cached : match_class},
- &class_def
- };
-
- if (cached && c->buffer->cur().syllable() < 255)
- index = c->buffer->cur().syllable ();
- else
- {
- index = class_def.get_class (c->buffer->cur().codepoint);
- if (cached && index < 255)
- c->buffer->cur().syllable() = index;
- }
- const RuleSet &rule_set = this+ruleSet[index];
- return_trace (rule_set.apply (c, lookup_context));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
- if (unlikely (!out->coverage.serialize_subset (c, coverage, this)))
- return_trace (false);
-
- hb_map_t klass_map;
- out->classDef.serialize_subset (c, classDef, this, &klass_map);
-
- const hb_set_t* glyphset = c->plan->glyphset_gsub ();
- hb_set_t retained_coverage_glyphs;
- (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs);
-
- hb_set_t coverage_glyph_classes;
- (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
-
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
- bool ret = true;
- int non_zero_index = -1, index = 0;
- auto snapshot = c->serializer->snapshot();
- for (const auto& _ : + hb_enumerate (ruleSet)
- | hb_filter (klass_map, hb_first))
- {
- auto *o = out->ruleSet.serialize_append (c->serializer);
- if (unlikely (!o))
- {
- ret = false;
- break;
- }
-
- if (coverage_glyph_classes.has (_.first) &&
- o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) {
- non_zero_index = index;
- snapshot = c->serializer->snapshot();
- }
-
- index++;
- }
-
- if (!ret || non_zero_index == -1) return_trace (false);
-
- //prune empty trailing ruleSets
- --index;
- while (index > non_zero_index)
- {
- out->ruleSet.pop ();
- index--;
- }
- c->serializer->revert (snapshot);
-
- return_trace (bool (out->ruleSet));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of table */
- typename Types::template OffsetTo<ClassDef>
- classDef; /* Offset to glyph ClassDef table--from
- * beginning of table */
- Array16Of<typename Types::template OffsetTo<RuleSet>>
- ruleSet; /* Array of RuleSet tables
- * ordered by class */
- public:
- DEFINE_SIZE_ARRAY (4 + 2 * Types::size, ruleSet);
-};
-
-
-struct ContextFormat3
-{
- using RuleSet = OT::RuleSet<SmallTypes>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (!(this+coverageZ[0]).intersects (glyphs))
- return false;
-
- struct ContextClosureLookupContext lookup_context = {
- {intersects_coverage, nullptr},
- ContextFormat::CoverageBasedContext,
- this
- };
- return context_intersects (glyphs,
- glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
- lookup_context);
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- if (!(this+coverageZ[0]).intersects (c->glyphs))
- return;
-
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
- cur_active_glyphs);
-
-
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- struct ContextClosureLookupContext lookup_context = {
- {intersects_coverage, intersected_coverage_glyphs},
- ContextFormat::CoverageBasedContext,
- this
- };
- context_closure_lookup (c,
- glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
- lookupCount, lookupRecord,
- 0, lookup_context);
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- if (!intersects (c->glyphs))
- return;
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- recurse_lookups (c, lookupCount, lookupRecord);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- (this+coverageZ[0]).collect_coverage (c->input);
-
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- struct ContextCollectGlyphsLookupContext lookup_context = {
- {collect_coverage},
- this
- };
-
- context_collect_glyphs_lookup (c,
- glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
- lookupCount, lookupRecord,
- lookup_context);
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- struct ContextApplyLookupContext lookup_context = {
- {match_coverage},
- this
- };
- return context_would_apply_lookup (c,
- glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
- lookupCount, lookupRecord,
- lookup_context);
- }
-
- const Coverage &get_coverage () const { return this+coverageZ[0]; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- struct ContextApplyLookupContext lookup_context = {
- {match_coverage},
- this
- };
- return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- out->format = format;
- out->glyphCount = glyphCount;
-
- auto coverages = coverageZ.as_array (glyphCount);
-
- for (const Offset16To<Coverage>& offset : coverages)
- {
- /* TODO(subset) This looks like should not be necessary to write this way. */
- auto *o = c->serializer->allocate_size<Offset16To<Coverage>> (Offset16To<Coverage>::static_size);
- if (unlikely (!o)) return_trace (false);
- if (!o->serialize_subset (c, offset, this)) return_trace (false);
- }
-
- const auto& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount));
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
-
-
- unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (lookupCount), lookup_map);
- return_trace (c->serializer->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!c->check_struct (this)) return_trace (false);
- unsigned int count = glyphCount;
- if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
- if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false);
- for (unsigned int i = 0; i < count; i++)
- if (!coverageZ[i].sanitize (c, this)) return_trace (false);
- const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
- return_trace (c->check_array (lookupRecord, lookupCount));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 3 */
- HBUINT16 glyphCount; /* Number of glyphs in the input glyph
- * sequence */
- HBUINT16 lookupCount; /* Number of LookupRecords */
- UnsizedArrayOf<Offset16To<Coverage>>
- coverageZ; /* Array of offsets to Coverage
- * table in glyph sequence order */
-/*UnsizedArrayOf<LookupRecord>
- lookupRecordX;*/ /* Array of LookupRecords--in
- * design order */
- public:
- DEFINE_SIZE_ARRAY (6, coverageZ);
-};
-
-struct Context
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
- case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ContextFormat1_4<SmallTypes> format1;
- ContextFormat2_5<SmallTypes> format2;
- ContextFormat3 format3;
-#ifndef HB_NO_BEYOND_64K
- ContextFormat1_4<MediumTypes> format4;
- ContextFormat2_5<MediumTypes> format5;
-#endif
- } u;
-};
-
-
-/* Chaining Contextual lookups */
-
-struct ChainContextClosureLookupContext
-{
- ContextClosureFuncs funcs;
- ContextFormat context_format;
- const void *intersects_data[3];
- void *intersects_cache[3];
- void *intersected_glyphs_cache;
-};
-
-struct ChainContextCollectGlyphsLookupContext
-{
- ContextCollectGlyphsFuncs funcs;
- const void *collect_data[3];
-};
-
-struct ChainContextApplyLookupContext
-{
- ChainContextApplyFuncs funcs;
- const void *match_data[3];
-};
-
-template <typename HBUINT>
-static inline bool chain_context_intersects (const hb_set_t *glyphs,
- unsigned int backtrackCount,
- const HBUINT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[],
- ChainContextClosureLookupContext &lookup_context)
-{
- return array_is_subset_of (glyphs,
- backtrackCount, backtrack,
- lookup_context.funcs.intersects,
- lookup_context.intersects_data[0],
- lookup_context.intersects_cache[0])
- && array_is_subset_of (glyphs,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects,
- lookup_context.intersects_data[1],
- lookup_context.intersects_cache[1])
- && array_is_subset_of (glyphs,
- lookaheadCount, lookahead,
- lookup_context.funcs.intersects,
- lookup_context.intersects_data[2],
- lookup_context.intersects_cache[2]);
-}
-
-template <typename HBUINT>
-static inline void chain_context_closure_lookup (hb_closure_context_t *c,
- unsigned int backtrackCount,
- const HBUINT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- unsigned value,
- ChainContextClosureLookupContext &lookup_context)
-{
- if (chain_context_intersects (c->glyphs,
- backtrackCount, backtrack,
- inputCount, input,
- lookaheadCount, lookahead,
- lookup_context))
- context_closure_recurse_lookups (c,
- inputCount, input,
- lookupCount, lookupRecord,
- value,
- lookup_context.context_format,
- lookup_context.intersects_data[1],
- lookup_context.funcs.intersected_glyphs,
- lookup_context.intersected_glyphs_cache);
-}
-
-template <typename HBUINT>
-static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
- unsigned int backtrackCount,
- const HBUINT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- ChainContextCollectGlyphsLookupContext &lookup_context)
-{
- collect_array (c, c->before,
- backtrackCount, backtrack,
- lookup_context.funcs.collect, lookup_context.collect_data[0]);
- collect_array (c, c->input,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.collect, lookup_context.collect_data[1]);
- collect_array (c, c->after,
- lookaheadCount, lookahead,
- lookup_context.funcs.collect, lookup_context.collect_data[2]);
- recurse_lookups (c,
- lookupCount, lookupRecord);
-}
-
-template <typename HBUINT>
-static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
- unsigned int backtrackCount,
- const HBUINT backtrack[] HB_UNUSED,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[] HB_UNUSED,
- unsigned int lookupCount HB_UNUSED,
- const LookupRecord lookupRecord[] HB_UNUSED,
- const ChainContextApplyLookupContext &lookup_context)
-{
- return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
- && would_match_input (c,
- inputCount, input,
- lookup_context.funcs.match[1], lookup_context.match_data[1]);
-}
-
-template <typename HBUINT>
-static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
- unsigned int backtrackCount,
- const HBUINT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const HBUINT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const HBUINT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- const ChainContextApplyLookupContext &lookup_context)
-{
- unsigned end_index = c->buffer->idx;
- unsigned match_end = 0;
- unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
- if (!(match_input (c,
- inputCount, input,
- lookup_context.funcs.match[1], lookup_context.match_data[1],
- &match_end, match_positions) && (end_index = match_end)
- && match_lookahead (c,
- lookaheadCount, lookahead,
- lookup_context.funcs.match[2], lookup_context.match_data[2],
- match_end, &end_index)))
- {
- c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
- return false;
- }
-
- unsigned start_index = c->buffer->out_len;
- if (!match_backtrack (c,
- backtrackCount, backtrack,
- lookup_context.funcs.match[0], lookup_context.match_data[0],
- &start_index))
- {
- c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
- return false;
- }
-
- c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
- apply_lookup (c,
- inputCount, match_positions,
- lookupCount, lookupRecord,
- match_end);
- return true;
-}
-
-template <typename Types>
-struct ChainRule
-{
- bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- return chain_context_intersects (glyphs,
- backtrack.len, backtrack.arrayZ,
- input.lenP1, input.arrayZ,
- lookahead.len, lookahead.arrayZ,
- lookup_context);
- }
-
- void closure (hb_closure_context_t *c, unsigned value,
- ChainContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- chain_context_closure_lookup (c,
- backtrack.len, backtrack.arrayZ,
- input.lenP1, input.arrayZ,
- lookahead.len, lookahead.arrayZ,
- lookup.len, lookup.arrayZ,
- value,
- lookup_context);
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c,
- ChainContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
- if (!intersects (c->glyphs, lookup_context)) return;
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- recurse_lookups (c, lookup.len, lookup.arrayZ);
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- ChainContextCollectGlyphsLookupContext &lookup_context) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- chain_context_collect_glyphs_lookup (c,
- backtrack.len, backtrack.arrayZ,
- input.lenP1, input.arrayZ,
- lookahead.len, lookahead.arrayZ,
- lookup.len, lookup.arrayZ,
- lookup_context);
- }
-
- bool would_apply (hb_would_apply_context_t *c,
- const ChainContextApplyLookupContext &lookup_context) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- return chain_context_would_apply_lookup (c,
- backtrack.len, backtrack.arrayZ,
- input.lenP1, input.arrayZ,
- lookahead.len, lookahead.arrayZ, lookup.len,
- lookup.arrayZ, lookup_context);
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ChainContextApplyLookupContext &lookup_context) const
- {
- TRACE_APPLY (this);
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- return_trace (chain_context_apply_lookup (c,
- backtrack.len, backtrack.arrayZ,
- input.lenP1, input.arrayZ,
- lookahead.len, lookahead.arrayZ, lookup.len,
- lookup.arrayZ, lookup_context));
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize_array (hb_serialize_context_t *c,
- HBUINT16 len,
- Iterator it) const
- {
- c->copy (len);
- for (const auto g : it)
- c->copy ((HBUINT16) g);
- }
-
- bool serialize (hb_serialize_context_t *c,
- const hb_map_t *lookup_map,
- const hb_map_t *backtrack_map,
- const hb_map_t *input_map = nullptr,
- const hb_map_t *lookahead_map = nullptr) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!out)) return_trace (false);
-
- const hb_map_t *mapping = backtrack_map;
- serialize_array (c, backtrack.len, + backtrack.iter ()
- | hb_map (mapping));
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- if (input_map) mapping = input_map;
- serialize_array (c, input.lenP1, + input.iter ()
- | hb_map (mapping));
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- if (lookahead_map) mapping = lookahead_map;
- serialize_array (c, lookahead.len, + lookahead.iter ()
- | hb_map (mapping));
-
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
-
- HBUINT16* lookupCount = c->embed (&(lookup.len));
- if (!lookupCount) return_trace (false);
-
- unsigned count = serialize_lookuprecord_array (c, lookup.as_array (), lookup_map);
- return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_map_t *lookup_map,
- const hb_map_t *backtrack_map = nullptr,
- const hb_map_t *input_map = nullptr,
- const hb_map_t *lookahead_map = nullptr) const
- {
- TRACE_SUBSET (this);
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
-
- if (!backtrack_map)
- {
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- if (!hb_all (backtrack, glyphset) ||
- !hb_all (input, glyphset) ||
- !hb_all (lookahead, glyphset))
- return_trace (false);
-
- serialize (c->serializer, lookup_map, c->plan->glyph_map);
- }
- else
- {
- if (!hb_all (backtrack, backtrack_map) ||
- !hb_all (input, input_map) ||
- !hb_all (lookahead, lookahead_map))
- return_trace (false);
-
- serialize (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
- }
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!backtrack.sanitize (c)) return_trace (false);
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- if (!input.sanitize (c)) return_trace (false);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- if (!lookahead.sanitize (c)) return_trace (false);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- return_trace (lookup.sanitize (c));
- }
-
- protected:
- Array16Of<typename Types::HBUINT>
- backtrack; /* Array of backtracking values
- * (to be matched before the input
- * sequence) */
- HeadlessArrayOf<typename Types::HBUINT>
- inputX; /* Array of input values (start with
- * second glyph) */
- Array16Of<typename Types::HBUINT>
- lookaheadX; /* Array of lookahead values's (to be
- * matched after the input sequence) */
- Array16Of<LookupRecord>
- lookupX; /* Array of LookupRecords--in
- * design order) */
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-template <typename Types>
-struct ChainRuleSet
-{
- using ChainRule = OT::ChainRule<Types>;
-
- bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const ChainRule &_) { return _.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
- void closure (hb_closure_context_t *c, unsigned value, ChainContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
-
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRule &_) { _.closure (c, value, lookup_context); })
- ;
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c,
- ChainContextClosureLookupContext &lookup_context) const
- {
- if (unlikely (c->lookup_limit_exceeded ())) return;
-
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c, lookup_context); })
- ;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRule &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c,
- const ChainContextApplyLookupContext &lookup_context) const
- {
- return
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const ChainRule &_) { return _.would_apply (c, lookup_context); })
- | hb_any
- ;
- }
-
- bool apply (hb_ot_apply_context_t *c,
- const ChainContextApplyLookupContext &lookup_context) const
- {
- TRACE_APPLY (this);
- return_trace (
- + hb_iter (rule)
- | hb_map (hb_add (this))
- | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
- | hb_any
- )
- ;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_map_t *lookup_map,
- const hb_map_t *backtrack_klass_map = nullptr,
- const hb_map_t *input_klass_map = nullptr,
- const hb_map_t *lookahead_klass_map = nullptr) const
- {
- TRACE_SUBSET (this);
-
- auto snap = c->serializer->snapshot ();
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const Offset16To<ChainRule>& _ : rule)
- {
- if (!_) continue;
- auto o_snap = c->serializer->snapshot ();
- auto *o = out->rule.serialize_append (c->serializer);
- if (unlikely (!o)) continue;
-
- if (!o->serialize_subset (c, _, this,
- lookup_map,
- backtrack_klass_map,
- input_klass_map,
- lookahead_klass_map))
- {
- out->rule.pop ();
- c->serializer->revert (o_snap);
- }
- }
-
- bool ret = bool (out->rule);
- if (!ret) c->serializer->revert (snap);
-
- return_trace (ret);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (rule.sanitize (c, this));
- }
-
- protected:
- Array16OfOffset16To<ChainRule>
- rule; /* Array of ChainRule tables
- * ordered by preference */
- public:
- DEFINE_SIZE_ARRAY (2, rule);
-};
-
-template <typename Types>
-struct ChainContextFormat1_4
-{
- using ChainRuleSet = OT::ChainRuleSet<Types>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
- ContextFormat::SimpleContext,
- {nullptr, nullptr, nullptr}
- };
-
- return
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (*glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_map ([&] (const ChainRuleSet &_) { return _.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
- cur_active_glyphs);
-
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_glyph, intersected_glyph},
- ContextFormat::SimpleContext,
- {nullptr, nullptr, nullptr}
- };
-
- + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
- | hb_filter ([&] (hb_codepoint_t _) {
- return c->previous_parent_active_glyphs ().has (_);
- }, hb_first)
- | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); })
- | hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
- ;
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_glyph, nullptr},
- ContextFormat::SimpleContext,
- {nullptr, nullptr, nullptr}
- };
-
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (*c->glyphs, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c, lookup_context); })
- ;
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- (this+coverage).collect_coverage (c->input);
-
- struct ChainContextCollectGlyphsLookupContext lookup_context = {
- {collect_glyph},
- {nullptr, nullptr, nullptr}
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
- struct ChainContextApplyLookupContext lookup_context = {
- {{match_glyph, match_glyph, match_glyph}},
- {nullptr, nullptr, nullptr}
- };
- return rule_set.would_apply (c, lookup_context);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const ChainRuleSet &rule_set = this+ruleSet[index];
- struct ChainContextApplyLookupContext lookup_context = {
- {{match_glyph, match_glyph, match_glyph}},
- {nullptr, nullptr, nullptr}
- };
- return_trace (rule_set.apply (c, lookup_context));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
-
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, ruleSet)
- | hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (bool (new_coverage));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 1 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of table */
- Array16Of<typename Types::template OffsetTo<ChainRuleSet>>
- ruleSet; /* Array of ChainRuleSet tables
- * ordered by Coverage Index */
- public:
- DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet);
-};
-
-template <typename Types>
-struct ChainContextFormat2_5
-{
- using ChainRuleSet = OT::ChainRuleSet<SmallTypes>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- if (!(this+coverage).intersects (glyphs))
- return false;
-
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- hb_map_t caches[3] = {};
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, nullptr},
- ContextFormat::ClassBasedContext,
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def},
- {&caches[0], &caches[1], &caches[2]}
- };
-
- hb_set_t retained_coverage_glyphs;
- (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs);
-
- hb_set_t coverage_glyph_classes;
- input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
-
- return
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_enumerate
- | hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p)
- { return input_class_def.intersects_class (glyphs, p.first) &&
- coverage_glyph_classes.has (p.first) &&
- p.second.intersects (glyphs, lookup_context); })
- | hb_any
- ;
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- if (!(this+coverage).intersects (c->glyphs))
- return;
-
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
- cur_active_glyphs);
-
-
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- hb_map_t caches[3] = {};
- intersected_class_cache_t intersected_cache;
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, intersected_class_glyphs},
- ContextFormat::ClassBasedContext,
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def},
- {&caches[0], &caches[1], &caches[2]},
- &intersected_cache
- };
-
- + hb_enumerate (ruleSet)
- | hb_filter ([&] (unsigned _)
- { return input_class_def.intersects_class (&c->parent_active_glyphs (), _); },
- hb_first)
- | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<ChainRuleSet>&> _)
- {
- const ChainRuleSet& chainrule_set = this+_.second;
- chainrule_set.closure (c, _.first, lookup_context);
- })
- ;
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- if (!(this+coverage).intersects (c->glyphs))
- return;
-
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- hb_map_t caches[3] = {};
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, nullptr},
- ContextFormat::ClassBasedContext,
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def},
- {&caches[0], &caches[1], &caches[2]}
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_enumerate
- | hb_filter([&] (unsigned klass)
- { return input_class_def.intersects_class (c->glyphs, klass); }, hb_first)
- | hb_map (hb_second)
- | hb_apply ([&] (const ChainRuleSet &_)
- { _.closure_lookups (c, lookup_context); })
- ;
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- (this+coverage).collect_coverage (c->input);
-
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- struct ChainContextCollectGlyphsLookupContext lookup_context = {
- {collect_class},
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def}
- };
-
- + hb_iter (ruleSet)
- | hb_map (hb_add (this))
- | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
- ;
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- unsigned int index = input_class_def.get_class (c->glyphs[0]);
- const ChainRuleSet &rule_set = this+ruleSet[index];
- struct ChainContextApplyLookupContext lookup_context = {
- {{match_class, match_class, match_class}},
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def}
- };
- return rule_set.would_apply (c, lookup_context);
- }
-
- const Coverage &get_coverage () const { return this+coverage; }
-
- unsigned cache_cost () const
- {
- unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len;
- return c >= 4 ? c : 0;
- }
- bool cache_func (hb_ot_apply_context_t *c, bool enter) const
- {
- if (enter)
- {
- if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
- return false;
- auto &info = c->buffer->info;
- unsigned count = c->buffer->len;
- for (unsigned i = 0; i < count; i++)
- info[i].syllable() = 255;
- c->new_syllables = 255;
- return true;
- }
- else
- {
- c->new_syllables = (unsigned) -1;
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
- return true;
- }
- }
-
- bool apply (hb_ot_apply_context_t *c, bool cached = false) const
- {
- TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const ClassDef &backtrack_class_def = this+backtrackClassDef;
- const ClassDef &input_class_def = this+inputClassDef;
- const ClassDef &lookahead_class_def = this+lookaheadClassDef;
-
- /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef.
- * The reason is that most heavy fonts want to identify a glyph in context and apply
- * a lookup to it. In this scenario, the length of the input sequence is one, whereas
- * the lookahead / backtrack are typically longer. The one glyph in input sequence is
- * looked-up below and no input glyph is looked up in individual rules, whereas the
- * lookahead and backtrack glyphs are tried. Since we match lookahead before backtrack,
- * we should cache lookahead. This decisions showed a 20% improvement in shaping of
- * the Gulzar font.
- */
-
- struct ChainContextApplyLookupContext lookup_context = {
- {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached : match_class,
- cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
- cached ? match_class_cached : match_class}},
- {&backtrack_class_def,
- &input_class_def,
- &lookahead_class_def}
- };
-
- index = input_class_def.get_class (c->buffer->cur().codepoint);
- const ChainRuleSet &rule_set = this+ruleSet[index];
- return_trace (rule_set.apply (c, lookup_context));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->format = format;
- out->coverage.serialize_subset (c, coverage, this);
-
- hb_map_t backtrack_klass_map;
- hb_map_t input_klass_map;
- hb_map_t lookahead_klass_map;
-
- out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map);
- // TODO: subset inputClassDef based on glyphs survived in Coverage subsetting
- out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map);
- out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map);
-
- if (unlikely (!c->serializer->propagate_error (backtrack_klass_map,
- input_klass_map,
- lookahead_klass_map)))
- return_trace (false);
-
- const hb_set_t* glyphset = c->plan->glyphset_gsub ();
- hb_set_t retained_coverage_glyphs;
- (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs);
-
- hb_set_t coverage_glyph_classes;
- (this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
-
- int non_zero_index = -1, index = 0;
- bool ret = true;
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
- auto last_non_zero = c->serializer->snapshot ();
- for (const auto& _ : + hb_enumerate (ruleSet)
- | hb_filter (input_klass_map, hb_first))
- {
- auto *o = out->ruleSet.serialize_append (c->serializer);
- if (unlikely (!o))
- {
- ret = false;
- break;
- }
- if (coverage_glyph_classes.has (_.first) &&
- o->serialize_subset (c, _.second, this,
- lookup_map,
- &backtrack_klass_map,
- &input_klass_map,
- &lookahead_klass_map))
- {
- last_non_zero = c->serializer->snapshot ();
- non_zero_index = index;
- }
-
- index++;
- }
-
- if (!ret || non_zero_index == -1) return_trace (false);
-
- // prune empty trailing ruleSets
- if (index > non_zero_index) {
- c->serializer->revert (last_non_zero);
- out->ruleSet.len = non_zero_index + 1;
- }
-
- return_trace (bool (out->ruleSet));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (coverage.sanitize (c, this) &&
- backtrackClassDef.sanitize (c, this) &&
- inputClassDef.sanitize (c, this) &&
- lookaheadClassDef.sanitize (c, this) &&
- ruleSet.sanitize (c, this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 2 */
- typename Types::template OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of table */
- typename Types::template OffsetTo<ClassDef>
- backtrackClassDef; /* Offset to glyph ClassDef table
- * containing backtrack sequence
- * data--from beginning of table */
- typename Types::template OffsetTo<ClassDef>
- inputClassDef; /* Offset to glyph ClassDef
- * table containing input sequence
- * data--from beginning of table */
- typename Types::template OffsetTo<ClassDef>
- lookaheadClassDef; /* Offset to glyph ClassDef table
- * containing lookahead sequence
- * data--from beginning of table */
- Array16Of<typename Types::template OffsetTo<ChainRuleSet>>
- ruleSet; /* Array of ChainRuleSet tables
- * ordered by class */
- public:
- DEFINE_SIZE_ARRAY (4 + 4 * Types::size, ruleSet);
-};
-
-struct ChainContextFormat3
-{
- using RuleSet = OT::RuleSet<SmallTypes>;
-
- bool intersects (const hb_set_t *glyphs) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
-
- if (!(this+input[0]).intersects (glyphs))
- return false;
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_coverage, nullptr},
- ContextFormat::CoverageBasedContext,
- {this, this, this}
- };
- return chain_context_intersects (glyphs,
- backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
- input.len, (const HBUINT16 *) input.arrayZ + 1,
- lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
- lookup_context);
- }
-
- bool may_have_non_1to1 () const
- { return true; }
-
- void closure (hb_closure_context_t *c) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
-
- if (!(this+input[0]).intersects (c->glyphs))
- return;
-
- hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
- get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
- cur_active_glyphs);
-
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- struct ChainContextClosureLookupContext lookup_context = {
- {intersects_coverage, intersected_coverage_glyphs},
- ContextFormat::CoverageBasedContext,
- {this, this, this}
- };
- chain_context_closure_lookup (c,
- backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
- input.len, (const HBUINT16 *) input.arrayZ + 1,
- lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
- lookup.len, lookup.arrayZ,
- 0, lookup_context);
-
- c->pop_cur_done_glyphs ();
- }
-
- void closure_lookups (hb_closure_lookups_context_t *c) const
- {
- if (!intersects (c->glyphs))
- return;
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- recurse_lookups (c, lookup.len, lookup.arrayZ);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
-
- void collect_glyphs (hb_collect_glyphs_context_t *c) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
-
- (this+input[0]).collect_coverage (c->input);
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
-
- struct ChainContextCollectGlyphsLookupContext lookup_context = {
- {collect_coverage},
- {this, this, this}
- };
- chain_context_collect_glyphs_lookup (c,
- backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
- input.len, (const HBUINT16 *) input.arrayZ + 1,
- lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
- lookup.len, lookup.arrayZ,
- lookup_context);
- }
-
- bool would_apply (hb_would_apply_context_t *c) const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- struct ChainContextApplyLookupContext lookup_context = {
- {{match_coverage, match_coverage, match_coverage}},
- {this, this, this}
- };
- return chain_context_would_apply_lookup (c,
- backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
- input.len, (const HBUINT16 *) input.arrayZ + 1,
- lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
- lookup.len, lookup.arrayZ, lookup_context);
- }
-
- const Coverage &get_coverage () const
- {
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- return this+input[0];
- }
-
- bool apply (hb_ot_apply_context_t *c) const
- {
- TRACE_APPLY (this);
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
-
- unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
- if (likely (index == NOT_COVERED)) return_trace (false);
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- struct ChainContextApplyLookupContext lookup_context = {
- {{match_coverage, match_coverage, match_coverage}},
- {this, this, this}
- };
- return_trace (chain_context_apply_lookup (c,
- backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
- input.len, (const HBUINT16 *) input.arrayZ + 1,
- lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
- lookup.len, lookup.arrayZ, lookup_context));
- }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool serialize_coverage_offsets (hb_subset_context_t *c, Iterator it, const void* base) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> ();
-
- if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size)))
- return_trace (false);
-
- for (auto& offset : it) {
- auto *o = out->serialize_append (c->serializer);
- if (unlikely (!o) || !o->serialize_subset (c, offset, base))
- return_trace (false);
- }
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out)) return_trace (false);
- if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
-
- if (!serialize_coverage_offsets (c, backtrack.iter (), this))
- return_trace (false);
-
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- if (!serialize_coverage_offsets (c, input.iter (), this))
- return_trace (false);
-
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- if (!serialize_coverage_offsets (c, lookahead.iter (), this))
- return_trace (false);
-
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
-
- HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookup.len);
- if (!lookupCount) return_trace (false);
-
- unsigned count = serialize_lookuprecord_array (c->serializer, lookup.as_array (), lookup_map);
- return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!backtrack.sanitize (c, this)) return_trace (false);
- const auto &input = StructAfter<decltype (inputX)> (backtrack);
- if (!input.sanitize (c, this)) return_trace (false);
- if (!input.len) return_trace (false); /* To be consistent with Context. */
- const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
- if (!lookahead.sanitize (c, this)) return_trace (false);
- const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
- return_trace (lookup.sanitize (c));
- }
-
- protected:
- HBUINT16 format; /* Format identifier--format = 3 */
- Array16OfOffset16To<Coverage>
- backtrack; /* Array of coverage tables
- * in backtracking sequence, in glyph
- * sequence order */
- Array16OfOffset16To<Coverage>
- inputX ; /* Array of coverage
- * tables in input sequence, in glyph
- * sequence order */
- Array16OfOffset16To<Coverage>
- lookaheadX; /* Array of coverage tables
- * in lookahead sequence, in glyph
- * sequence order */
- Array16Of<LookupRecord>
- lookupX; /* Array of LookupRecords--in
- * design order) */
- public:
- DEFINE_SIZE_MIN (10);
-};
-
-struct ChainContext
-{
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
-#ifndef HB_NO_BEYOND_64K
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
- case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...));
-#endif
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ChainContextFormat1_4<SmallTypes> format1;
- ChainContextFormat2_5<SmallTypes> format2;
- ChainContextFormat3 format3;
-#ifndef HB_NO_BEYOND_64K
- ChainContextFormat1_4<MediumTypes> format4;
- ChainContextFormat2_5<MediumTypes> format5;
-#endif
- } u;
-};
-
-
-template <typename T>
-struct ExtensionFormat1
-{
- unsigned int get_type () const { return extensionLookupType; }
-
- template <typename X>
- const X& get_subtable () const
- { return this + reinterpret_cast<const Offset32To<typename T::SubTable> &> (extensionOffset); }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, this))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, format);
- return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), std::forward<Ts> (ds)...));
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
- { dispatch (c); }
-
- /* This is called from may_dispatch() above with hb_sanitize_context_t. */
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- extensionLookupType != T::SubTable::Extension);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-
- out->format = format;
- out->extensionLookupType = extensionLookupType;
-
- const auto& src_offset =
- reinterpret_cast<const Offset32To<typename T::SubTable> &> (extensionOffset);
- auto& dest_offset =
- reinterpret_cast<Offset32To<typename T::SubTable> &> (out->extensionOffset);
-
- return_trace (dest_offset.serialize_subset (c, src_offset, this, get_type ()));
- }
-
- protected:
- HBUINT16 format; /* Format identifier. Set to 1. */
- HBUINT16 extensionLookupType; /* Lookup type of subtable referenced
- * by ExtensionOffset (i.e. the
- * extension subtable). */
- Offset32 extensionOffset; /* Offset to the extension subtable,
- * of lookup type subtable. */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-template <typename T>
-struct Extension
-{
- unsigned int get_type () const
- {
- switch (u.format) {
- case 1: return u.format1.get_type ();
- default:return 0;
- }
- }
- template <typename X>
- const X& get_subtable () const
- {
- switch (u.format) {
- case 1: return u.format1.template get_subtable<typename T::SubTable> ();
- default:return Null (typename T::SubTable);
- }
- }
-
- // Specialization of dispatch for subset. dispatch() normally just
- // dispatches to the sub table this points too, but for subset
- // we need to run subset on this subtable too.
- template <typename ...Ts>
- typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const
- {
- switch (u.format) {
- case 1: return u.format1.subset (c);
- default: return c->default_return_value ();
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (u.format1.dispatch (c, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- protected:
- union {
- HBUINT16 format; /* Format identifier */
- ExtensionFormat1<T> format1;
- } u;
-};
-
-
-/*
- * GSUB/GPOS Common
- */
-
-struct hb_ot_layout_lookup_accelerator_t
-{
- template <typename TLookup>
- static hb_ot_layout_lookup_accelerator_t *create (const TLookup &lookup)
- {
- unsigned count = lookup.get_subtable_count ();
-
- unsigned size = sizeof (hb_ot_layout_lookup_accelerator_t) -
- HB_VAR_ARRAY * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t) +
- count * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t);
-
- /* The following is a calloc because when we are collecting subtables,
- * some of them might be invalid and hence not collect; as a result,
- * we might not fill in all the count entries of the subtables array.
- * Zeroing it allows the set digest to gatekeep it without having to
- * initialize it further. */
- auto *thiz = (hb_ot_layout_lookup_accelerator_t *) hb_calloc (1, size);
- if (unlikely (!thiz))
- return nullptr;
-
- hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables);
- lookup.dispatch (&c_accelerate_subtables);
-
- thiz->digest.init ();
- for (auto& subtable : hb_iter (thiz->subtables, count))
- thiz->digest.add (subtable.digest);
-
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx;
- for (unsigned i = 0; i < count; i++)
- if (i != thiz->cache_user_idx)
- thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func;
-#endif
-
- return thiz;
- }
-
- bool may_have (hb_codepoint_t g) const
- { return digest.may_have (g); }
-
- bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
- {
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- if (use_cache)
- {
- return
- + hb_iter (hb_iter (subtables, subtables_count))
- | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
- | hb_any
- ;
- }
- else
-#endif
- {
- return
- + hb_iter (hb_iter (subtables, subtables_count))
- | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
- | hb_any
- ;
- }
- return false;
- }
-
- bool cache_enter (hb_ot_apply_context_t *c) const
- {
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- return cache_user_idx != (unsigned) -1 &&
- subtables[cache_user_idx].cache_enter (c);
-#else
- return false;
-#endif
- }
- void cache_leave (hb_ot_apply_context_t *c) const
- {
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- subtables[cache_user_idx].cache_leave (c);
-#endif
- }
-
-
- hb_set_digest_t digest;
- private:
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- unsigned cache_user_idx = (unsigned) -1;
-#endif
- hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY];
-};
-
-template <typename Types>
-struct GSUBGPOSVersion1_2
-{
- friend struct GSUBGPOS;
-
- protected:
- FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set
- * to 0x00010000u */
- typename Types:: template OffsetTo<ScriptList>
- scriptList; /* ScriptList table */
- typename Types::template OffsetTo<FeatureList>
- featureList; /* FeatureList table */
- typename Types::template OffsetTo<LookupList<Types>>
- lookupList; /* LookupList table */
- Offset32To<FeatureVariations>
- featureVars; /* Offset to Feature Variations
- table--from beginning of table
- * (may be NULL). Introduced
- * in version 0x00010001. */
- public:
- DEFINE_SIZE_MIN (4 + 3 * Types::size);
-
- unsigned int get_size () const
- {
- return min_size +
- (version.to_int () >= 0x00010001u ? featureVars.static_size : 0);
- }
-
- const typename Types::template OffsetTo<LookupList<Types>>* get_lookup_list_offset () const
- {
- return &lookupList;
- }
-
- template <typename TLookup>
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- typedef List16OfOffsetTo<TLookup, typename Types::HBUINT> TLookupList;
- if (unlikely (!(scriptList.sanitize (c, this) &&
- featureList.sanitize (c, this) &&
- reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList).sanitize (c, this))))
- return_trace (false);
-
-#ifndef HB_NO_VAR
- if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this))))
- return_trace (false);
-#endif
-
- return_trace (true);
- }
-
- template <typename TLookup>
- bool subset (hb_subset_layout_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- auto *out = c->subset_context->serializer->start_embed (this);
- if (unlikely (!c->subset_context->serializer->extend_min (out))) return_trace (false);
-
- out->version = version;
-
- typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList;
- reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList)
- .serialize_subset (c->subset_context,
- reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList),
- this,
- c);
-
- reinterpret_cast<typename Types::template OffsetTo<RecordListOfFeature> &> (out->featureList)
- .serialize_subset (c->subset_context,
- reinterpret_cast<const typename Types::template OffsetTo<RecordListOfFeature> &> (featureList),
- this,
- c);
-
- out->scriptList.serialize_subset (c->subset_context,
- scriptList,
- this,
- c);
-
-#ifndef HB_NO_VAR
- if (version.to_int () >= 0x00010001u)
- {
- auto snapshot = c->subset_context->serializer->snapshot ();
- if (!c->subset_context->serializer->extend_min (&out->featureVars))
- return_trace (false);
-
- // TODO(qxliu76): the current implementation doesn't correctly handle feature variations
- // that are dropped by instancing when the associated conditions don't trigger.
- // Since partial instancing isn't yet supported this isn't an issue yet but will
- // need to be fixed for partial instancing.
-
-
-
- // if all axes are pinned all feature vars are dropped.
- bool ret = !c->subset_context->plan->all_axes_pinned
- && out->featureVars.serialize_subset (c->subset_context, featureVars, this, c);
- if (!ret && version.major == 1)
- {
- c->subset_context->serializer->revert (snapshot);
- out->version.major = 1;
- out->version.minor = 0;
- }
- }
-#endif
-
- return_trace (true);
- }
-};
-
-struct GSUBGPOS
-{
- unsigned int get_size () const
- {
- switch (u.version.major) {
- case 1: return u.version1.get_size ();
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.get_size ();
-#endif
- default: return u.version.static_size;
- }
- }
-
- template <typename TLookup>
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!u.version.sanitize (c))) return_trace (false);
- switch (u.version.major) {
- case 1: return_trace (u.version1.sanitize<TLookup> (c));
-#ifndef HB_NO_BEYOND_64K
- case 2: return_trace (u.version2.sanitize<TLookup> (c));
-#endif
- default: return_trace (true);
- }
- }
-
- template <typename TLookup>
- bool subset (hb_subset_layout_context_t *c) const
- {
- switch (u.version.major) {
- case 1: return u.version1.subset<TLookup> (c);
-#ifndef HB_NO_BEYOND_64K
- case 2: return u.version2.subset<TLookup> (c);
-#endif
- default: return false;
- }
- }
-
- const ScriptList &get_script_list () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.scriptList;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.scriptList;
-#endif
- default: return Null (ScriptList);
- }
- }
- const FeatureList &get_feature_list () const
- {
- switch (u.version.major) {
- case 1: return this+u.version1.featureList;
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.featureList;
-#endif
- default: return Null (FeatureList);
- }
- }
- unsigned int get_lookup_count () const
- {
- switch (u.version.major) {
- case 1: return (this+u.version1.lookupList).len;
-#ifndef HB_NO_BEYOND_64K
- case 2: return (this+u.version2.lookupList).len;
-#endif
- default: return 0;
- }
- }
- const Lookup& get_lookup (unsigned int i) const
- {
- switch (u.version.major) {
- case 1: return (this+u.version1.lookupList)[i];
-#ifndef HB_NO_BEYOND_64K
- case 2: return (this+u.version2.lookupList)[i];
-#endif
- default: return Null (Lookup);
- }
- }
- const FeatureVariations &get_feature_variations () const
- {
- switch (u.version.major) {
- case 1: return (u.version.to_int () >= 0x00010001u ? this+u.version1.featureVars : Null (FeatureVariations));
-#ifndef HB_NO_BEYOND_64K
- case 2: return this+u.version2.featureVars;
-#endif
- default: return Null (FeatureVariations);
- }
- }
-
- bool has_data () const { return u.version.to_int (); }
- unsigned int get_script_count () const
- { return get_script_list ().len; }
- const Tag& get_script_tag (unsigned int i) const
- { return get_script_list ().get_tag (i); }
- unsigned int get_script_tags (unsigned int start_offset,
- unsigned int *script_count /* IN/OUT */,
- hb_tag_t *script_tags /* OUT */) const
- { return get_script_list ().get_tags (start_offset, script_count, script_tags); }
- const Script& get_script (unsigned int i) const
- { return get_script_list ()[i]; }
- bool find_script_index (hb_tag_t tag, unsigned int *index) const
- { return get_script_list ().find_index (tag, index); }
-
- unsigned int get_feature_count () const
- { return get_feature_list ().len; }
- hb_tag_t get_feature_tag (unsigned int i) const
- { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : get_feature_list ().get_tag (i); }
- unsigned int get_feature_tags (unsigned int start_offset,
- unsigned int *feature_count /* IN/OUT */,
- hb_tag_t *feature_tags /* OUT */) const
- { return get_feature_list ().get_tags (start_offset, feature_count, feature_tags); }
- const Feature& get_feature (unsigned int i) const
- { return get_feature_list ()[i]; }
- bool find_feature_index (hb_tag_t tag, unsigned int *index) const
- { return get_feature_list ().find_index (tag, index); }
-
- bool find_variations_index (const int *coords, unsigned int num_coords,
- unsigned int *index) const
- {
-#ifdef HB_NO_VAR
- *index = FeatureVariations::NOT_FOUND_INDEX;
- return false;
-#endif
- return get_feature_variations ().find_index (coords, num_coords, index);
- }
- const Feature& get_feature_variation (unsigned int feature_index,
- unsigned int variations_index) const
- {
-#ifndef HB_NO_VAR
- if (FeatureVariations::NOT_FOUND_INDEX != variations_index &&
- u.version.to_int () >= 0x00010001u)
- {
- const Feature *feature = get_feature_variations ().find_substitute (variations_index,
- feature_index);
- if (feature)
- return *feature;
- }
-#endif
- return get_feature (feature_index);
- }
-
- void feature_variation_collect_lookups (const hb_set_t *feature_indexes,
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
- hb_set_t *lookup_indexes /* OUT */) const
- {
-#ifndef HB_NO_VAR
- get_feature_variations ().collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes);
-#endif
- }
-
-#ifndef HB_NO_VAR
- void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
- { get_feature_variations ().collect_feature_substitutes_with_variations (c); }
-#endif
-
- template <typename TLookup>
- void closure_lookups (hb_face_t *face,
- const hb_set_t *glyphs,
- hb_set_t *lookup_indexes /* IN/OUT */) const
- {
- hb_set_t visited_lookups, inactive_lookups;
- hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
-
- c.set_recurse_func (TLookup::template dispatch_recurse_func<hb_closure_lookups_context_t>);
-
- for (unsigned lookup_index : *lookup_indexes)
- reinterpret_cast<const TLookup &> (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
-
- hb_set_union (lookup_indexes, &visited_lookups);
- hb_set_subtract (lookup_indexes, &inactive_lookups);
- }
-
- void prune_langsys (const hb_map_t *duplicate_feature_map,
- const hb_set_t *layout_scripts,
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map,
- hb_set_t *new_feature_indexes /* OUT */) const
- {
- hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
-
- unsigned count = get_script_count ();
- for (unsigned script_index = 0; script_index < count; script_index++)
- {
- const Tag& tag = get_script_tag (script_index);
- if (!layout_scripts->has (tag)) continue;
- const Script& s = get_script (script_index);
- s.prune_langsys (&c, script_index);
- }
- }
-
- void prune_features (const hb_map_t *lookup_indices, /* IN */
- const hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* IN */
- const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map, /* IN */
- hb_set_t *feature_indices /* IN/OUT */) const
- {
-#ifndef HB_NO_VAR
- // This is the set of feature indices which have alternate versions defined
- // if the FeatureVariation's table and the alternate version(s) intersect the
- // set of lookup indices.
- hb_set_t alternate_feature_indices;
- get_feature_variations ().closure_features (lookup_indices, feature_record_cond_idx_map, &alternate_feature_indices);
- if (unlikely (alternate_feature_indices.in_error()))
- {
- feature_indices->err ();
- return;
- }
-#endif
-
- for (unsigned i : hb_iter (feature_indices))
- {
- hb_tag_t tag = get_feature_tag (i);
- if (tag == HB_TAG ('p', 'r', 'e', 'f'))
- // Note: Never ever drop feature 'pref', even if it's empty.
- // HarfBuzz chooses shaper for Khmer based on presence of this
- // feature. See thread at:
- // http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html
- continue;
-
-
- const Feature *f = &(get_feature (i));
- const Feature** p = nullptr;
- if (feature_substitutes_map->has (i, &p))
- f = *p;
-
- if (!f->featureParams.is_null () &&
- tag == HB_TAG ('s', 'i', 'z', 'e'))
- continue;
-
- if (!f->intersects_lookup_indexes (lookup_indices)
-#ifndef HB_NO_VAR
- && !alternate_feature_indices.has (i)
-#endif
- )
- feature_indices->del (i);
- }
- }
-
- void collect_name_ids (const hb_map_t *feature_index_map,
- hb_set_t *nameids_to_retain /* OUT */) const
- {
- unsigned count = get_feature_count ();
- for (unsigned i = 0 ; i < count; i++)
- {
- if (!feature_index_map->has (i)) continue;
- hb_tag_t tag = get_feature_tag (i);
- get_feature (i).collect_name_ids (tag, nameids_to_retain);
- }
- }
-
- template <typename T>
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- this->table = hb_sanitize_context_t ().reference_table<T> (face);
- if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
- {
- hb_blob_destroy (this->table.get_blob ());
- this->table = hb_blob_get_empty ();
- }
-
- this->lookup_count = table->get_lookup_count ();
-
- this->accels = (hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *) hb_calloc (this->lookup_count, sizeof (*accels));
- if (unlikely (!this->accels))
- {
- this->lookup_count = 0;
- this->table.destroy ();
- this->table = hb_blob_get_empty ();
- }
- }
- ~accelerator_t ()
- {
- for (unsigned int i = 0; i < this->lookup_count; i++)
- hb_free (this->accels[i]);
- hb_free (this->accels);
- this->table.destroy ();
- }
-
- hb_ot_layout_lookup_accelerator_t *get_accel (unsigned lookup_index) const
- {
- if (unlikely (lookup_index >= lookup_count)) return nullptr;
-
- retry:
- auto *accel = accels[lookup_index].get_acquire ();
- if (unlikely (!accel))
- {
- accel = hb_ot_layout_lookup_accelerator_t::create (table->get_lookup (lookup_index));
- if (unlikely (!accel))
- return nullptr;
-
- if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel)))
- {
- hb_free (accel);
- goto retry;
- }
- }
-
- return accel;
- }
-
- hb_blob_ptr_t<T> table;
- unsigned int lookup_count;
- hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *accels;
- };
-
- protected:
- union {
- FixedVersion<> version; /* Version identifier */
- GSUBGPOSVersion1_2<SmallTypes> version1;
-#ifndef HB_NO_BEYOND_64K
- GSUBGPOSVersion1_2<MediumTypes> version2;
-#endif
- } u;
- public:
- DEFINE_SIZE_MIN (4);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_LAYOUT_GSUBGPOS_HH */
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 a1c125b11b6..adbaad64f39 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
@@ -27,7 +27,7 @@
#ifndef HB_OT_LAYOUT_JSTF_TABLE_HH
#define HB_OT_LAYOUT_JSTF_TABLE_HH
-#include "hb-open-type.hh"
+#include "hb-open-type-private.hh"
#include "hb-ot-layout-gpos-table.hh"
@@ -45,7 +45,7 @@ typedef IndexArray JstfModList;
* JstfMax -- Justification Maximum Table
*/
-typedef List16OfOffset16To<PosLookup> JstfMax;
+typedef OffsetListOf<PosLookup> JstfMax;
/*
@@ -54,7 +54,7 @@ typedef List16OfOffset16To<PosLookup> JstfMax;
struct JstfPriority
{
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -71,43 +71,43 @@ struct JstfPriority
}
protected:
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
shrinkageEnableGSUB; /* Offset to Shrinkage Enable GSUB
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
shrinkageDisableGSUB; /* Offset to Shrinkage Disable GSUB
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
shrinkageEnableGPOS; /* Offset to Shrinkage Enable GPOS
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
shrinkageDisableGPOS; /* Offset to Shrinkage Disable GPOS
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfMax>
+ OffsetTo<JstfMax>
shrinkageJstfMax; /* Offset to Shrinkage JstfMax table--
* from beginning of JstfPriority table
* --may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
extensionEnableGSUB; /* Offset to Extension Enable GSUB
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
extensionDisableGSUB; /* Offset to Extension Disable GSUB
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
extensionEnableGPOS; /* Offset to Extension Enable GPOS
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfModList>
+ OffsetTo<JstfModList>
extensionDisableGPOS; /* Offset to Extension Disable GPOS
* JstfModList table--from beginning of
* JstfPriority table--may be NULL */
- Offset16To<JstfMax>
+ OffsetTo<JstfMax>
extensionJstfMax; /* Offset to Extension JstfMax table--
* from beginning of JstfPriority table
* --may be NULL */
@@ -121,13 +121,13 @@ struct JstfPriority
* JstfLangSys -- Justification Language System Table
*/
-struct JstfLangSys : List16OfOffset16To<JstfPriority>
+struct JstfLangSys : OffsetListOf<JstfPriority>
{
- bool sanitize (hb_sanitize_context_t *c,
- const Record_sanitize_closure_t * = nullptr) const
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
- return_trace (List16OfOffset16To<JstfPriority>::sanitize (c));
+ return_trace (OffsetListOf<JstfPriority>::sanitize (c));
}
};
@@ -136,7 +136,7 @@ struct JstfLangSys : List16OfOffset16To<JstfPriority>
* ExtenderGlyphs -- Extender Glyph Table
*/
-typedef SortedArray16Of<HBGlyphID16> ExtenderGlyphs;
+typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
/*
@@ -145,27 +145,27 @@ typedef SortedArray16Of<HBGlyphID16> ExtenderGlyphs;
struct JstfScript
{
- unsigned int get_lang_sys_count () const
+ inline unsigned int get_lang_sys_count (void) const
{ return langSys.len; }
- const Tag& get_lang_sys_tag (unsigned int i) const
+ inline const Tag& get_lang_sys_tag (unsigned int i) const
{ return langSys.get_tag (i); }
- unsigned int get_lang_sys_tags (unsigned int start_offset,
- unsigned int *lang_sys_count /* IN/OUT */,
- hb_tag_t *lang_sys_tags /* OUT */) const
+ inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+ unsigned int *lang_sys_count /* IN/OUT */,
+ hb_tag_t *lang_sys_tags /* OUT */) const
{ return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
- const JstfLangSys& get_lang_sys (unsigned int i) const
+ inline const JstfLangSys& get_lang_sys (unsigned int i) const
{
if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
return this+langSys[i].offset;
}
- bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+ inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
{ return langSys.find_index (tag, index); }
- bool has_default_lang_sys () const { return defaultLangSys != 0; }
- const JstfLangSys& get_default_lang_sys () const { return this+defaultLangSys; }
+ inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+ inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
- bool sanitize (hb_sanitize_context_t *c,
- const Record_sanitize_closure_t * = nullptr) const
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfScript>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (extenderGlyphs.sanitize (c, this) &&
@@ -174,10 +174,10 @@ struct JstfScript
}
protected:
- Offset16To<ExtenderGlyphs>
+ OffsetTo<ExtenderGlyphs>
extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning
* of JstfScript table-may be NULL */
- Offset16To<JstfLangSys>
+ OffsetTo<JstfLangSys>
defaultLangSys; /* Offset to DefaultJstfLangSys table--from
* beginning of JstfScript table--may be Null */
RecordArrayOf<JstfLangSys>
@@ -189,28 +189,27 @@ struct JstfScript
/*
- * JSTF -- Justification
- * https://docs.microsoft.com/en-us/typography/opentype/spec/jstf
+ * JSTF -- The Justification Table
*/
struct JSTF
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_JSTF;
+ static const hb_tag_t tableTag = HB_OT_TAG_JSTF;
- unsigned int get_script_count () const
+ inline unsigned int get_script_count (void) const
{ return scriptList.len; }
- const Tag& get_script_tag (unsigned int i) const
+ inline const Tag& get_script_tag (unsigned int i) const
{ return scriptList.get_tag (i); }
- unsigned int get_script_tags (unsigned int start_offset,
- unsigned int *script_count /* IN/OUT */,
- hb_tag_t *script_tags /* OUT */) const
+ inline unsigned int get_script_tags (unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */) const
{ return scriptList.get_tags (start_offset, script_count, script_tags); }
- const JstfScript& get_script (unsigned int i) const
+ inline const JstfScript& get_script (unsigned int i) const
{ return this+scriptList[i].offset; }
- bool find_script_index (hb_tag_t tag, unsigned int *index) const
+ inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
{ return scriptList.find_index (tag, index); }
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
@@ -222,7 +221,7 @@ struct JSTF
FixedVersion<>version; /* Version of the JSTF table--initially set
* to 0x00010000u */
RecordArrayOf<JstfScript>
- scriptList; /* Array of JstfScripts--listed
+ scriptList; /* Array of JstfScripts--listed
* alphabetically by ScriptTag */
public:
DEFINE_SIZE_ARRAY (6, scriptList);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh
new file mode 100644
index 00000000000..b52b1215d2d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-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_LAYOUT_MATH_TABLE_HH
+#define HB_OT_LAYOUT_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:
+ SHORT 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 NULL.
+ * 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:
+ SHORT percentScaleDown[2];
+ USHORT minHeight[2];
+ MathValueRecord mathValueRecords[51];
+ SHORT 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:
+ USHORT 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 NULL. */
+ 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 NULL.. */
+ 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. */
+ USHORT advanceMeasurement; /* Advance width/height, in design units, of the
+ * variant, in the direction of requested
+ * glyph extension. */
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct PartFlags : USHORT
+{
+ 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);
+
+ ASSERT_STATIC ((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. */
+ USHORT 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. */
+ USHORT 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. */
+ USHORT 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 NULL. */
+ 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:
+ USHORT 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. */
+ USHORT vertGlyphCount; /* Number of glyphs for which
+ * information is provided for
+ * vertically growing variants. */
+ USHORT 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);
+};
+
+} /* mathspace OT */
+
+
+#endif /* HB_OT_LAYOUT_MATH_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
index 9505d5f1470..0f0926f8906 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -26,43 +26,20 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_LAYOUT_HH
-#define HB_OT_LAYOUT_HH
+#ifndef HB_OT_LAYOUT_PRIVATE_HH
+#define HB_OT_LAYOUT_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-font.hh"
-#include "hb-buffer.hh"
-#include "hb-open-type.hh"
-#include "hb-ot-shape.hh"
-#include "hb-set-digest.hh"
-
-
-struct hb_ot_shape_plan_t;
-
-
-/*
- * kern
- */
-
-HB_INTERNAL bool
-hb_ot_layout_has_kerning (hb_face_t *face);
-
-HB_INTERNAL bool
-hb_ot_layout_has_machine_kerning (hb_face_t *face);
-
-HB_INTERNAL bool
-hb_ot_layout_has_cross_kerning (hb_face_t *face);
-
-HB_INTERNAL void
-hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-set-digest-private.hh"
+#include "hb-open-type-private.hh"
/* Private API corresponding to hb-ot-layout.h: */
-HB_INTERNAL bool
+HB_INTERNAL hb_bool_t
hb_ot_layout_table_find_feature (hb_face_t *face,
hb_tag_t table_tag,
hb_tag_t feature_tag,
@@ -96,26 +73,31 @@ HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t);
* GSUB/GPOS
*/
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context);
+
/* Should be called before all the substitute_lookup's are done. */
HB_INTERNAL void
hb_ot_layout_substitute_start (hb_font_t *font,
hb_buffer_t *buffer);
+
+struct hb_ot_layout_lookup_accelerator_t;
+
namespace OT {
- struct hb_ot_apply_context_t;
- struct hb_ot_layout_lookup_accelerator_t;
-namespace Layout {
-namespace GSUB_impl {
+ struct hb_apply_context_t;
struct SubstLookup;
}
-}
-}
HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
- const OT::Layout::GSUB_impl::SubstLookup &lookup,
- const OT::hb_ot_layout_lookup_accelerator_t &accel);
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+ const OT::SubstLookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel);
/* Should be called before all the position_lookup's are done. */
@@ -123,17 +105,85 @@ HB_INTERNAL void
hb_ot_layout_position_start (hb_font_t *font,
hb_buffer_t *buffer);
-/* Should be called after all the position_lookup's are done, to fini advances. */
+/* Should be called after all the position_lookup's are done, to finish advances. */
HB_INTERNAL void
hb_ot_layout_position_finish_advances (hb_font_t *font,
hb_buffer_t *buffer);
-/* Should be called after hb_ot_layout_position_finish_advances, to fini offsets. */
+/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */
HB_INTERNAL void
hb_ot_layout_position_finish_offsets (hb_font_t *font,
hb_buffer_t *buffer);
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+ struct GDEF;
+ struct GSUB;
+ struct GPOS;
+ struct MATH;
+ struct fvar;
+ struct avar;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+ template <typename TLookup>
+ inline void init (const TLookup &lookup)
+ {
+ digest.init ();
+ lookup.add_coverage (&digest);
+ }
+
+ inline void fini (void)
+ {
+ }
+
+ inline bool may_have (hb_codepoint_t g) const {
+ return digest.may_have (g);
+ }
+
+ private:
+ hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+ hb_blob_t *gdef_blob;
+ hb_blob_t *gsub_blob;
+ hb_blob_t *gpos_blob;
+
+ const struct OT::GDEF *gdef;
+ const struct OT::GSUB *gsub;
+ const struct OT::GPOS *gpos;
+
+ /* 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;
+
+ hb_ot_layout_lookup_accelerator_t *gsub_accels;
+ hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+
/*
* Buffer var routines.
*/
@@ -151,12 +201,12 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font,
#define foreach_syllable(buffer, start, end) \
for (unsigned int \
_count = buffer->len, \
- start = 0, end = _count ? _hb_next_syllable (buffer, 0) : 0; \
+ start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
start < _count; \
- start = end, end = _hb_next_syllable (buffer, start))
+ start = end, end = _next_syllable (buffer, start))
static inline unsigned int
-_hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
+_next_syllable (hb_buffer_t *buffer, unsigned int start)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
@@ -176,10 +226,10 @@ _hb_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 four 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.
- * * Whether it's a grapheme continuation.
+ * * One free bit right now.
*
* The high-byte has different meanings, switched by the Gen-Cat:
* - For Mn,Mc,Me: the modified Combining_Class.
@@ -191,8 +241,8 @@ _hb_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_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */
- UPROPS_MASK_CONTINUATION=0x0080u,
+ 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,
@@ -208,10 +258,9 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
unsigned int gen_cat = (unsigned int) unicode->general_category (u);
unsigned int props = gen_cat;
- if (u >= 0x80u)
+ if (u >= 0x80)
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
-
if (unlikely (unicode->is_default_ignorable (u)))
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
@@ -225,23 +274,43 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
* FVSes are GC=Mn, we have use a separate bit to remember them.
* Fixes:
* https://github.com/harfbuzz/harfbuzz/issues/234 */
- else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) props |= UPROPS_MASK_HIDDEN;
+ 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<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
+ 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))
- {
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
- props |= UPROPS_MASK_HIDDEN;
- }
+ else if (unlikely (u == 0x034Fu)) props |= UPROPS_MASK_HIDDEN;
}
-
- if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
+ else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
{
- props |= UPROPS_MASK_CONTINUATION;
- props |= unicode->modified_combining_class (u)<<8;
+ /* The above check is just an optimization to let in only things we need further
+ * processing on. */
+
+ /* Only Mn and Mc can have non-zero ccc:
+ * http://www.unicode.org/policies/stability_policy.html#Property_Value
+ * """
+ * Canonical_Combining_Class, General_Category
+ * All characters other than those with General_Category property values
+ * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class
+ * property value 0.
+ * 1.1.5+
+ * """
+ *
+ * Also, all Mn's that are Default_Ignorable, have ccc=0, hence
+ * the "else if".
+ */
+ props |= unicode->modified_combining_class (info->codepoint)<<8;
+
+ /* 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/harfbuzz/harfbuzz/issues/169
+ */
+ if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
+ {
+ props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
+ }
}
}
@@ -280,6 +349,7 @@ _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
@@ -303,56 +373,20 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info)
hb_unicode_funcs_t::NOT_SPACE;
}
-static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info);
+static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
-static inline bool
+static inline hb_bool_t
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
{
return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
- !_hb_glyph_info_substituted (info);
+ !_hb_glyph_info_ligated (info);
}
-static inline bool
+static inline hb_bool_t
_hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)
{
return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN))
== UPROPS_MASK_IGNORABLE) &&
- !_hb_glyph_info_substituted (info);
-}
-static inline void
-_hb_glyph_info_unhide (hb_glyph_info_t *info)
-{
- info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
-}
-
-static inline void
-_hb_glyph_info_set_continuation (hb_glyph_info_t *info)
-{
- info->unicode_props() |= UPROPS_MASK_CONTINUATION;
-}
-static inline void
-_hb_glyph_info_reset_continuation (hb_glyph_info_t *info)
-{
- info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION;
-}
-static inline bool
-_hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
-{
- return info->unicode_props() & UPROPS_MASK_CONTINUATION;
-}
-
-static inline bool
-_hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED,
- const hb_glyph_info_t& b)
-{ return _hb_glyph_info_is_continuation (&b); }
-
-#define foreach_grapheme(buffer, start, end) \
- foreach_group (buffer, start, end, _hb_grapheme_group_func)
-
-static inline void
-_hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer)
-{
- buffer->reverse_groups (_hb_grapheme_group_func,
- buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+ !_hb_glyph_info_ligated (info);
}
static inline bool
@@ -361,17 +395,17 @@ _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
return _hb_glyph_info_get_general_category (info) ==
HB_UNICODE_GENERAL_CATEGORY_FORMAT;
}
-static inline bool
+static inline hb_bool_t
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
{
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ);
}
-static inline bool
+static inline hb_bool_t
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
{
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ);
}
-static inline bool
+static inline hb_bool_t
_hb_glyph_info_is_joiner (const hb_glyph_info_t *info)
{
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ));
@@ -471,8 +505,7 @@ _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
}
static inline uint8_t
-_hb_allocate_lig_id (hb_buffer_t *buffer)
-{
+_hb_allocate_lig_id (hb_buffer_t *buffer) {
uint8_t lig_id = buffer->next_serial () & 0x07;
if (unlikely (!lig_id))
lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
@@ -548,18 +581,6 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
}
-static inline bool
-_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- hb_glyph_info_t *info = buffer->info;
- unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- _hb_glyph_info_clear_substituted (&info[i]);
- return false;
-}
-
/* Allocation / deallocation. */
@@ -586,11 +607,13 @@ _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
{
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
}
static inline void
_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
}
@@ -600,6 +623,7 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
{
HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
HB_BUFFER_ASSERT_VAR (buffer, lig_props);
+ HB_BUFFER_ASSERT_VAR (buffer, syllable);
}
/* Make sure no one directly touches our props... */
@@ -608,4 +632,4 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
#undef lig_props
#undef glyph_props
-#endif /* HB_OT_LAYOUT_HH */
+#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 256a055863b..88458898272 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -28,270 +28,222 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-private.hh"
-#ifndef HB_NO_OT_LAYOUT
-
-#ifdef HB_NO_OT_TAG
-#error "Cannot compile hb-ot-layout.cc with HB_NO_OT_TAG."
-#endif
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout.hh"
-#include "hb-ot-face.hh"
-#include "hb-ot-map.hh"
-#include "hb-map.hh"
-
-#include "hb-ot-kern-table.hh"
#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-base-table.hh"
#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-ot-name-table.hh"
-#include "hb-ot-os2-table.hh"
+#include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-aat-layout-morx-table.hh"
-#include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-map-private.hh"
-using OT::Layout::GSUB;
-using OT::Layout::GPOS;
-
-/**
- * SECTION:hb-ot-layout
- * @title: hb-ot-layout
- * @short_description: OpenType Layout
- * @include: hb-ot.h
- *
- * Functions for querying OpenType Layout features in the font face.
- * See the <ulink url="http://www.microsoft.com/typography/otspec/">OpenType
- * specification</ulink> for details.
- **/
+const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-/*
- * kern
- */
-#ifndef HB_NO_OT_KERN
-/**
- * hb_ot_layout_has_kerning:
- * @face: The #hb_face_t to work on
- *
- * Tests whether a face includes any kerning data in the 'kern' table.
- * Does NOT test for kerning lookups in the GPOS table.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
-bool
-hb_ot_layout_has_kerning (hb_face_t *face)
+hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face)
{
- return face->table.kern->has_data ();
-}
+ hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+ if (unlikely (!layout))
+ return nullptr;
-/**
- * hb_ot_layout_has_machine_kerning:
- * @face: The #hb_face_t to work on
- *
- * Tests whether a face includes any state-machine kerning in the 'kern' table.
- * Does NOT examine the GPOS table.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
-bool
-hb_ot_layout_has_machine_kerning (hb_face_t *face)
-{
- return face->table.kern->has_state_machine ();
-}
+ 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);
-/**
- * hb_ot_layout_has_cross_kerning:
- * @face: The #hb_face_t to work on
- *
- * Tests whether a face has any cross-stream kerning (i.e., kerns
- * that make adjustments perpendicular to the direction of the text
- * flow: Y adjustments in horizontal text or X adjustments in
- * vertical text) in the 'kern' table.
- *
- * Does NOT examine the GPOS table.
- *
- * Return value: `true` is data found, `false` otherwise
- *
- **/
-bool
-hb_ot_layout_has_cross_kerning (hb_face_t *face)
-{
- return face->table.kern->has_cross_stream ();
-}
+ layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
+ layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
-void
-hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- hb_blob_t *blob = font->face->table.kern.get_blob ();
- const AAT::kern& kern = *blob->as<AAT::kern> ();
+ 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);
- AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+ layout->math.init (face);
+ layout->fvar.init (face);
+ layout->avar.init (face);
- if (!buffer->message (font, "start table kern")) return;
- kern.apply (&c);
- (void) buffer->message (font, "end table kern");
-}
-#endif
+ {
+ /*
+ * The ugly business of blacklisting individual fonts' tables happen here!
+ * See this thread for why we finally had to bend in and do this:
+ * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
+ */
+ unsigned int gdef_len = hb_blob_get_length (layout->gdef_blob);
+ unsigned int gsub_len = hb_blob_get_length (layout->gsub_blob);
+ unsigned int gpos_len = hb_blob_get_length (layout->gpos_blob);
+ if (0
+ /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */
+ || (442 == gdef_len && 42038 == gpos_len && 2874 == gsub_len)
+ /* sha1sum:37fc8c16a0894ab7b749e35579856c73c840867b Windows 7? timesbi.ttf */
+ || (430 == gdef_len && 40662 == gpos_len && 2874 == gsub_len)
+ /* sha1sum:19fc45110ea6cd3cdd0a5faca256a3797a069a80 Windows 7 timesi.ttf */
+ || (442 == gdef_len && 39116 == gpos_len && 2874 == gsub_len)
+ /* sha1sum:6d2d3c9ed5b7de87bc84eae0df95ee5232ecde26 Windows 7 timesbi.ttf */
+ || (430 == gdef_len && 39374 == gpos_len && 2874 == gsub_len)
+ /* sha1sum:8583225a8b49667c077b3525333f84af08c6bcd8 OS X 10.11.3 Times New Roman Italic.ttf */
+ || (490 == gdef_len && 41638 == gpos_len && 3046 == gsub_len)
+ /* sha1sum:ec0f5a8751845355b7c3271d11f9918a966cb8c9 OS X 10.11.3 Times New Roman Bold Italic.ttf */
+ || (478 == gdef_len && 41902 == gpos_len && 3046 == gsub_len)
+ )
+ {
+ /* In certain versions of Times New Roman Italic and Bold Italic,
+ * ASCII double quotation mark U+0022, mapped to glyph 5, has wrong
+ * glyph class 3 (mark) in GDEF. Nuke the GDEF to avoid zero-width
+ * double-quote. See:
+ * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
+ */
+ if (3 == layout->gdef->get_glyph_class (5))
+ layout->gdef = &OT::Null(OT::GDEF);
+ }
+ else if (0
+ /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c tahoma.ttf from Windows 8 */
+ || (898 == gdef_len && 46470 == gpos_len && 12554 == gsub_len)
+ /* sha1sum:20928dc06014e0cd120b6fc942d0c3b1a46ac2bc tahomabd.ttf from Windows 8 */
+ || (910 == gdef_len && 47732 == gpos_len && 12566 == gsub_len)
+ /* sha1sum:4f95b7e4878f60fa3a39ca269618dfde9721a79e tahoma.ttf from Windows 8.1 */
+ || (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 */
+ || (192 == gdef_len && 7254 == gpos_len && 12690 == gsub_len)
+ /* 8d9267aea9cd2c852ecfb9f12a6e834bfaeafe44 cantarell-fonts-0.0.21/otf/Cantarell-Regular.otf */
+ /* 983988ff7b47439ab79aeaf9a45bd4a2c5b9d371 cantarell-fonts-0.0.21/otf/Cantarell-Oblique.otf */
+ || (188 == gdef_len && 3852 == gpos_len && 248 == gsub_len)
+ /* 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 */
+ || (1058 == gdef_len && 17514 == gpos_len && 71794 == gsub_len)
+ /* 824cfd193aaf6234b2b4dc0cf3c6ef576c0d00ef padauk-3.0/Padauk-book.ttf */
+ || (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
+ * such as certain IPA symbols as glyph class 3. So do older versions of Microsoft Himalaya,
+ * and the version of Cantarell shipped by Ubuntu 16.04.
+ * Nuke the GDEF tables of these fonts to avoid unwanted width-zeroing.
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=1279925
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875
+ */
+ layout->gdef = &OT::Null(OT::GDEF);
+ }
+ }
+ layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
+ layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
-/*
- * GDEF
- */
+ layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
+ layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
-bool
-OT::GDEF::is_blocklisted (hb_blob_t *blob,
- hb_face_t *face) const
-{
-#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
- return false;
-#endif
- /* The ugly business of blocklisting individual fonts' tables happen here!
- * See this thread for why we finally had to bend in and do this:
- * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
- *
- * In certain versions of Times New Roman Italic and Bold Italic,
- * ASCII double quotation mark U+0022 has wrong glyph class 3 (mark)
- * in GDEF. Many versions of Tahoma have bad GDEF tables that
- * incorrectly classify some spacing marks such as certain IPA
- * symbols as glyph class 3. So do older versions of Microsoft
- * Himalaya, and the version of Cantarell shipped by Ubuntu 16.04.
- *
- * Nuke the GDEF tables of to avoid unwanted width-zeroing.
- *
- * See https://bugzilla.mozilla.org/show_bug.cgi?id=1279925
- * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693
- * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875
- */
- switch HB_CODEPOINT_ENCODE3(blob->length,
- face->table.GSUB->table.get_length (),
- face->table.GPOS->table.get_length ())
+ if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) ||
+ (layout->gpos_lookup_count && !layout->gpos_accels)))
{
- /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */
- case HB_CODEPOINT_ENCODE3 (442, 2874, 42038):
- /* sha1sum:37fc8c16a0894ab7b749e35579856c73c840867b Windows 7? timesbi.ttf */
- case HB_CODEPOINT_ENCODE3 (430, 2874, 40662):
- /* sha1sum:19fc45110ea6cd3cdd0a5faca256a3797a069a80 Windows 7 timesi.ttf */
- case HB_CODEPOINT_ENCODE3 (442, 2874, 39116):
- /* sha1sum:6d2d3c9ed5b7de87bc84eae0df95ee5232ecde26 Windows 7 timesbi.ttf */
- case HB_CODEPOINT_ENCODE3 (430, 2874, 39374):
- /* sha1sum:8583225a8b49667c077b3525333f84af08c6bcd8 OS X 10.11.3 Times New Roman Italic.ttf */
- case HB_CODEPOINT_ENCODE3 (490, 3046, 41638):
- /* sha1sum:ec0f5a8751845355b7c3271d11f9918a966cb8c9 OS X 10.11.3 Times New Roman Bold Italic.ttf */
- case HB_CODEPOINT_ENCODE3 (478, 3046, 41902):
- /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c tahoma.ttf from Windows 8 */
- case HB_CODEPOINT_ENCODE3 (898, 12554, 46470):
- /* sha1sum:20928dc06014e0cd120b6fc942d0c3b1a46ac2bc tahomabd.ttf from Windows 8 */
- case HB_CODEPOINT_ENCODE3 (910, 12566, 47732):
- /* sha1sum:4f95b7e4878f60fa3a39ca269618dfde9721a79e tahoma.ttf from Windows 8.1 */
- case HB_CODEPOINT_ENCODE3 (928, 23298, 59332):
- /* sha1sum:6d400781948517c3c0441ba42acb309584b73033 tahomabd.ttf from Windows 8.1 */
- case HB_CODEPOINT_ENCODE3 (940, 23310, 60732):
- /* tahoma.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
- case HB_CODEPOINT_ENCODE3 (964, 23836, 60072):
- /* tahomabd.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
- case HB_CODEPOINT_ENCODE3 (976, 23832, 61456):
- /* sha1sum:e55fa2dfe957a9f7ec26be516a0e30b0c925f846 tahoma.ttf from Windows 10 */
- case HB_CODEPOINT_ENCODE3 (994, 24474, 60336):
- /* sha1sum:7199385abb4c2cc81c83a151a7599b6368e92343 tahomabd.ttf from Windows 10 */
- case HB_CODEPOINT_ENCODE3 (1006, 24470, 61740):
- /* tahoma.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
- case HB_CODEPOINT_ENCODE3 (1006, 24576, 61346):
- /* tahomabd.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
- case HB_CODEPOINT_ENCODE3 (1018, 24572, 62828):
- /* sha1sum:b9c84d820c49850d3d27ec498be93955b82772b5 tahoma.ttf from Windows 10 AU */
- case HB_CODEPOINT_ENCODE3 (1006, 24576, 61352):
- /* sha1sum:2bdfaab28174bdadd2f3d4200a30a7ae31db79d2 tahomabd.ttf from Windows 10 AU */
- case HB_CODEPOINT_ENCODE3 (1018, 24572, 62834):
- /* sha1sum:b0d36cf5a2fbe746a3dd277bffc6756a820807a7 Tahoma.ttf from Mac OS X 10.9 */
- case HB_CODEPOINT_ENCODE3 (832, 7324, 47162):
- /* sha1sum:12fc4538e84d461771b30c18b5eb6bd434e30fba Tahoma Bold.ttf from Mac OS X 10.9 */
- case HB_CODEPOINT_ENCODE3 (844, 7302, 45474):
- /* sha1sum:eb8afadd28e9cf963e886b23a30b44ab4fd83acc himalaya.ttf from Windows 7 */
- case HB_CODEPOINT_ENCODE3 (180, 13054, 7254):
- /* sha1sum:73da7f025b238a3f737aa1fde22577a6370f77b0 himalaya.ttf from Windows 8 */
- case HB_CODEPOINT_ENCODE3 (192, 12638, 7254):
- /* sha1sum:6e80fd1c0b059bbee49272401583160dc1e6a427 himalaya.ttf from Windows 8.1 */
- case HB_CODEPOINT_ENCODE3 (192, 12690, 7254):
- /* 8d9267aea9cd2c852ecfb9f12a6e834bfaeafe44 cantarell-fonts-0.0.21/otf/Cantarell-Regular.otf */
- /* 983988ff7b47439ab79aeaf9a45bd4a2c5b9d371 cantarell-fonts-0.0.21/otf/Cantarell-Oblique.otf */
- case HB_CODEPOINT_ENCODE3 (188, 248, 3852):
- /* 2c0c90c6f6087ffbfea76589c93113a9cbb0e75f cantarell-fonts-0.0.21/otf/Cantarell-Bold.otf */
- /* 55461f5b853c6da88069ffcdf7f4dd3f8d7e3e6b cantarell-fonts-0.0.21/otf/Cantarell-Bold-Oblique.otf */
- case HB_CODEPOINT_ENCODE3 (188, 264, 3426):
- /* d125afa82a77a6475ac0e74e7c207914af84b37a padauk-2.80/Padauk.ttf RHEL 7.2 */
- case HB_CODEPOINT_ENCODE3 (1058, 47032, 11818):
- /* 0f7b80437227b90a577cc078c0216160ae61b031 padauk-2.80/Padauk-Bold.ttf RHEL 7.2*/
- case HB_CODEPOINT_ENCODE3 (1046, 47030, 12600):
- /* d3dde9aa0a6b7f8f6a89ef1002e9aaa11b882290 padauk-2.80/Padauk.ttf Ubuntu 16.04 */
- case HB_CODEPOINT_ENCODE3 (1058, 71796, 16770):
- /* 5f3c98ccccae8a953be2d122c1b3a77fd805093f padauk-2.80/Padauk-Bold.ttf Ubuntu 16.04 */
- case HB_CODEPOINT_ENCODE3 (1046, 71790, 17862):
- /* 6c93b63b64e8b2c93f5e824e78caca555dc887c7 padauk-2.80/Padauk-book.ttf */
- case HB_CODEPOINT_ENCODE3 (1046, 71788, 17112):
- /* d89b1664058359b8ec82e35d3531931125991fb9 padauk-2.80/Padauk-bookbold.ttf */
- case HB_CODEPOINT_ENCODE3 (1058, 71794, 17514):
- /* 824cfd193aaf6234b2b4dc0cf3c6ef576c0d00ef padauk-3.0/Padauk-book.ttf */
- case HB_CODEPOINT_ENCODE3 (1330, 109904, 57938):
- /* 91fcc10cf15e012d27571e075b3b4dfe31754a8a padauk-3.0/Padauk-bookbold.ttf */
- case HB_CODEPOINT_ENCODE3 (1330, 109904, 58972):
- /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85 Padauk.ttf
- * "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */
- case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836):
- return true;
+ _hb_ot_layout_destroy (layout);
+ return nullptr;
}
- return false;
+
+ for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+ layout->gsub_accels[i].init (layout->gsub->get_lookup (i));
+ for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+ layout->gpos_accels[i].init (layout->gpos->get_lookup (i));
+
+ return layout;
}
-static void
-_hb_ot_layout_set_glyph_props (hb_font_t *font,
- hb_buffer_t *buffer)
+void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout)
{
- _hb_buffer_assert_gsubgpos_vars (buffer);
+ for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+ layout->gsub_accels[i].fini ();
+ for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+ layout->gpos_accels[i].fini ();
- const OT::GDEF &gdef = *font->face->table.GDEF->table;
- unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- {
- _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
- _hb_glyph_info_clear_lig_props (&buffer->info[i]);
- }
+ free (layout->gsub_accels);
+ free (layout->gpos_accels);
+
+ hb_blob_destroy (layout->gdef_blob);
+ hb_blob_destroy (layout->gsub_blob);
+ hb_blob_destroy (layout->gpos_blob);
+
+ layout->math.fini ();
+ layout->fvar.fini ();
+ layout->avar.fini ();
+
+ free (layout);
}
-/* Public API */
+static inline const OT::GDEF&
+_get_gdef (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
+ return *hb_ot_layout_from_face (face)->gdef;
+}
+static inline const OT::GSUB&
+_get_gsub (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
+ return *hb_ot_layout_from_face (face)->gsub;
+}
+static inline const OT::GPOS&
+_get_gpos (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
+ return *hb_ot_layout_from_face (face)->gpos;
+}
+
+/*
+ * GDEF
+ */
-/**
- * hb_ot_layout_has_glyph_classes:
- * @face: #hb_face_t to work upon
- *
- * Tests whether a face has any glyph classes defined in its GDEF table.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- **/
hb_bool_t
hb_ot_layout_has_glyph_classes (hb_face_t *face)
{
- return face->table.GDEF->table->has_glyph_classes ();
+ return _get_gdef (face).has_glyph_classes ();
}
/**
* hb_ot_layout_get_glyph_class:
- * @face: The #hb_face_t to work on
- * @glyph: The #hb_codepoint_t code point to query
- *
- * Fetches the GDEF class of the requested glyph in the specified face.
- *
- * Return value: The #hb_ot_layout_glyph_class_t glyph class of the given code
- * point in the GDEF table of the face.
*
* Since: 0.9.7
**/
@@ -299,18 +251,11 @@ hb_ot_layout_glyph_class_t
hb_ot_layout_get_glyph_class (hb_face_t *face,
hb_codepoint_t glyph)
{
- return (hb_ot_layout_glyph_class_t) face->table.GDEF->table->get_glyph_class (glyph);
+ return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
}
/**
* hb_ot_layout_get_glyphs_in_class:
- * @face: The #hb_face_t to work on
- * @klass: The #hb_ot_layout_glyph_class_t GDEF class to retrieve
- * @glyphs: (out): The #hb_set_t set of all glyphs belonging to the requested
- * class.
- *
- * Retrieves the set of all glyphs from the face that belong to the requested
- * glyph class in the face's GDEF table.
*
* Since: 0.9.7
**/
@@ -319,27 +264,9 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
hb_ot_layout_glyph_class_t klass,
hb_set_t *glyphs /* OUT */)
{
- return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs);
+ return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
}
-#ifndef HB_NO_LAYOUT_UNUSED
-/**
- * hb_ot_layout_get_attach_points:
- * @face: The #hb_face_t to work on
- * @glyph: The #hb_codepoint_t code point to query
- * @start_offset: offset of the first attachment point to retrieve
- * @point_count: (inout) (optional): Input = the maximum number of attachment points to return;
- * Output = the actual number of attachment points returned (may be zero)
- * @point_array: (out) (array length=point_count): The array of attachment points found for the query
- *
- * Fetches a list of all attachment points for the specified glyph in the GDEF
- * table of the face. The list returned will begin at the offset provided.
- *
- * Useful if the client program wishes to cache the list.
- *
- * Return value: Total number of attachment points for @glyph.
- *
- **/
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
hb_codepoint_t glyph,
@@ -347,34 +274,9 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */)
{
- return face->table.GDEF->table->get_attach_points (glyph,
- start_offset,
- point_count,
- point_array);
+ return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
}
-/**
- * hb_ot_layout_get_ligature_carets:
- * @font: The #hb_font_t to work on
- * @direction: The #hb_direction_t text direction to use
- * @glyph: The #hb_codepoint_t code point to query
- * @start_offset: offset of the first caret position to retrieve
- * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return;
- * Output = the actual number of caret positions returned (may be zero)
- * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query
- *
- * Fetches a list of the caret positions defined for a ligature glyph in the GDEF
- * table of the font. The list returned will begin at the offset provided.
- *
- * Note that a ligature that is formed from n characters will have n-1
- * caret positions. The first character is not represented in the array,
- * since its caret position is the glyph position.
- *
- * The positions returned by this function are 'unshaped', and will have to
- * be fixed up for kerning that may be applied to the ligature glyph.
- *
- * Return value: Total number of ligature caret positions for @glyph.
- *
- **/
+
unsigned int
hb_ot_layout_get_ligature_carets (hb_font_t *font,
hb_direction_t direction,
@@ -383,68 +285,32 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */)
{
- return font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+ return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
}
-#endif
/*
* GSUB/GPOS
*/
-bool
-GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED,
- hb_face_t *face) const
-{
-#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
- return false;
-#endif
- return false;
-}
-
-bool
-GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED,
- hb_face_t *face HB_UNUSED) const
-{
-#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
- return false;
-#endif
- return false;
-}
-
static const OT::GSUBGPOS&
get_gsubgpos_table (hb_face_t *face,
hb_tag_t table_tag)
{
switch (table_tag) {
- case HB_OT_TAG_GSUB: return *face->table.GSUB->table;
- case HB_OT_TAG_GPOS: return *face->table.GPOS->table;
- default: return Null (OT::GSUBGPOS);
+ case HB_OT_TAG_GSUB: return _get_gsub (face);
+ case HB_OT_TAG_GPOS: return _get_gpos (face);
+ default: return OT::Null(OT::GSUBGPOS);
}
}
-/**
- * hb_ot_layout_table_get_script_tags:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @start_offset: offset of the first script tag to retrieve
- * @script_count: (inout) (optional): Input = the maximum number of script tags to return;
- * Output = the actual number of script tags returned (may be zero)
- * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query
- *
- * Fetches a list of all scripts enumerated in the specified face's GSUB table
- * or GPOS table. The list returned will begin at the offset provided.
- *
- * Return value: Total number of script tags.
- *
- **/
unsigned int
hb_ot_layout_table_get_script_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *script_count /* IN/OUT */,
- hb_tag_t *script_tags /* OUT */)
+ hb_tag_t *script_tags /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -453,24 +319,11 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face,
#define HB_OT_TAG_LATIN_SCRIPT HB_TAG ('l', 'a', 't', 'n')
-/**
- * hb_ot_layout_table_find_script:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_tag: #hb_tag_t of the script tag requested
- * @script_index: (out): The index of the requested script tag
- *
- * Fetches the index if a given script tag in the specified face's GSUB table
- * or GPOS table.
- *
- * Return value: `true` if the script is found, `false` otherwise
- *
- **/
hb_bool_t
hb_ot_layout_table_find_script (hb_face_t *face,
hb_tag_t table_tag,
hb_tag_t script_tag,
- unsigned int *script_index /* OUT */)
+ unsigned int *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);
@@ -496,72 +349,24 @@ hb_ot_layout_table_find_script (hb_face_t *face,
return false;
}
-#ifndef HB_DISABLE_DEPRECATED
-/**
- * hb_ot_layout_table_choose_script:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_tags: Array of #hb_tag_t script tags
- * @script_index: (out): The index of the chosen script
- * @chosen_script: (out): #hb_tag_t of the chosen script
- *
- * Deprecated since 2.0.0
- **/
hb_bool_t
hb_ot_layout_table_choose_script (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *script_tags,
- unsigned int *script_index /* OUT */,
- hb_tag_t *chosen_script /* OUT */)
-{
- const hb_tag_t *t;
- for (t = script_tags; *t; t++);
- return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script);
-}
-#endif
-
-/**
- * hb_ot_layout_table_select_script:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_count: Number of script tags in the array
- * @script_tags: Array of #hb_tag_t script tags
- * @script_index: (out) (optional): The index of the requested script
- * @chosen_script: (out) (optional): #hb_tag_t of the requested script
- *
- * Selects an OpenType script for @table_tag from the @script_tags array.
- *
- * If the table does not have any of the requested scripts, then `DFLT`,
- * `dflt`, and `latn` tags are tried in that order. If the table still does not
- * have any of these scripts, @script_index is set to
- * #HB_OT_LAYOUT_NO_SCRIPT_INDEX and @chosen_script is set to #HB_TAG_NONE.
- *
- * Return value:
- * `true` if one of the requested scripts is selected, `false` if a fallback
- * script is selected or if no scripts are selected.
- *
- * Since: 2.0.0
- **/
-hb_bool_t
-hb_ot_layout_table_select_script (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_count,
- const hb_tag_t *script_tags,
- unsigned int *script_index /* OUT */,
- hb_tag_t *chosen_script /* OUT */)
+ unsigned int *script_index,
+ hb_tag_t *chosen_script)
{
static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- unsigned int i;
- for (i = 0; i < script_count; i++)
+ while (*script_tags)
{
- if (g.find_script_index (script_tags[i], script_index))
- {
+ if (g.find_script_index (*script_tags, script_index)) {
if (chosen_script)
- *chosen_script = script_tags[i];
+ *chosen_script = *script_tags;
return true;
}
+ script_tags++;
}
/* try finding 'DFLT' */
@@ -588,62 +393,27 @@ hb_ot_layout_table_select_script (hb_face_t *face,
if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
if (chosen_script)
- *chosen_script = HB_TAG_NONE;
+ *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
return false;
}
-
-/**
- * hb_ot_layout_table_get_feature_tags:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @start_offset: offset of the first feature tag to retrieve
- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
- * Output = the actual number of feature tags returned (may be zero)
- * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table
- *
- * Fetches a list of all feature tags in the given face's GSUB or GPOS table.
- * Note that there might be duplicate feature tags, belonging to different
- * script/language-system pairs of the table.
- *
- * Return value: Total number of feature tags.
- *
- * Since: 0.6.0
- *
- **/
unsigned int
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
- hb_tag_t *feature_tags /* OUT */)
+ hb_tag_t *feature_tags /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
return g.get_feature_tags (start_offset, feature_count, feature_tags);
}
-
-/**
- * hb_ot_layout_table_find_feature:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @feature_tag: The #hb_tag_t of the requested feature tag
- * @feature_index: (out): The index of the requested feature
- *
- * Fetches the index for a given feature tag in the specified face's GSUB table
- * or GPOS table.
- *
- * Return value: `true` if the feature is found, `false` otherwise
- *
- * Since: 0.6.0
- *
- **/
-bool
+hb_bool_t
hb_ot_layout_table_find_feature (hb_face_t *face,
hb_tag_t table_tag,
hb_tag_t feature_tag,
- unsigned int *feature_index /* OUT */)
+ unsigned int *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);
@@ -662,55 +432,19 @@ hb_ot_layout_table_find_feature (hb_face_t *face,
}
-/**
- * hb_ot_layout_script_get_language_tags:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @start_offset: offset of the first language tag to retrieve
- * @language_count: (inout) (optional): Input = the maximum number of language tags to return;
- * Output = the actual number of language tags returned (may be zero)
- * @language_tags: (out) (array length=language_count): Array of language tags found in the table
- *
- * Fetches a list of language tags in the given face's GSUB or GPOS table, underneath
- * the specified script index. The list returned will begin at the offset provided.
- *
- * Return value: Total number of language tags.
- *
- * Since: 0.6.0
- *
- **/
unsigned int
hb_ot_layout_script_get_language_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int start_offset,
unsigned int *language_count /* IN/OUT */,
- hb_tag_t *language_tags /* OUT */)
+ hb_tag_t *language_tags /* OUT */)
{
const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
return s.get_lang_sys_tags (start_offset, language_count, language_tags);
}
-
-#ifndef HB_DISABLE_DEPRECATED
-/**
- * hb_ot_layout_script_find_language:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_tag: The #hb_tag_t of the requested language
- * @language_index: The index of the requested language
- *
- * Fetches the index of a given language tag in the specified face's GSUB table
- * or GPOS table, underneath the specified script tag.
- *
- * Return value: `true` if the language tag is found, `false` otherwise
- *
- * Since: 0.6.0
- * Deprecated: 2.0.0
- **/
hb_bool_t
hb_ot_layout_script_find_language (hb_face_t *face,
hb_tag_t table_tag,
@@ -718,132 +452,26 @@ hb_ot_layout_script_find_language (hb_face_t *face,
hb_tag_t language_tag,
unsigned int *language_index)
{
- return hb_ot_layout_script_select_language (face,
- table_tag,
- script_index,
- 1,
- &language_tag,
- language_index);
-}
-#endif
-
-
-/**
- * hb_ot_layout_script_select_language2:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_count: The number of languages in the specified script
- * @language_tags: The array of language tags
- * @language_index: (out): The index of the chosen language
- * @chosen_language: (out): #hb_tag_t of the chosen language
- *
- * Fetches the index of the first language tag fom @language_tags that is present
- * in the specified face's GSUB or GPOS table, underneath the specified script
- * index.
- *
- * If none of the given language tags is found, `false` is returned and
- * @language_index is set to #HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX and
- * @chosen_language is set to #HB_TAG_NONE.
- *
- * Return value: `true` if one of the given language tags is found, `false` otherwise
- *
- * Since: 7.0.0
- **/
-hb_bool_t
-hb_ot_layout_script_select_language2 (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_index,
- unsigned int language_count,
- const hb_tag_t *language_tags,
- unsigned int *language_index /* OUT */,
- hb_tag_t *chosen_language /* OUT */)
-{
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);
- unsigned int i;
- for (i = 0; i < language_count; i++)
- {
- if (s.find_lang_sys_index (language_tags[i], language_index))
- {
- if (chosen_language)
- *chosen_language = language_tags[i];
- return true;
- }
- }
+ if (s.find_lang_sys_index (language_tag, language_index))
+ return true;
- /* try finding 'dflt' */
+ /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
- {
- if (chosen_language)
- *chosen_language = HB_OT_TAG_DEFAULT_LANGUAGE;
return false;
- }
- if (language_index)
- *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
- if (chosen_language)
- *chosen_language = HB_TAG_NONE;
+ if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
return false;
}
-/**
- * hb_ot_layout_script_select_language:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_count: The number of languages in the specified script
- * @language_tags: The array of language tags
- * @language_index: (out): The index of the requested language
- *
- * Fetches the index of the first language tag fom @language_tags that is present
- * in the specified face's GSUB or GPOS table, underneath the specified script
- * index.
- *
- * If none of the given language tags is found, `false` is returned and
- * @language_index is set to the default language index.
- *
- * Return value: `true` if one of the given language tags is found, `false` otherwise
- *
- * Since: 2.0.0
- **/
-hb_bool_t
-hb_ot_layout_script_select_language (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_index,
- unsigned int language_count,
- const hb_tag_t *language_tags,
- unsigned int *language_index /* OUT */)
-{
- return hb_ot_layout_script_select_language2 (face, table_tag,
- script_index,
- language_count, language_tags,
- language_index, nullptr);
-}
-
-/**
- * hb_ot_layout_language_get_required_feature_index:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_index: The index of the requested language tag
- * @feature_index: (out): The index of the requested feature
- *
- * Fetches the index of a requested feature in the given face's GSUB or GPOS table,
- * underneath the specified script and language.
- *
- * Return value: `true` if the feature is found, `false` otherwise
- *
- * Since: 0.6.0
- *
- **/
hb_bool_t
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
- unsigned int *feature_index /* OUT */)
+ unsigned int *feature_index)
{
return hb_ot_layout_language_get_required_feature (face,
table_tag,
@@ -853,20 +481,8 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
nullptr);
}
-
/**
* hb_ot_layout_language_get_required_feature:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_index: The index of the requested language tag
- * @feature_index: (out): The index of the requested feature
- * @feature_tag: (out): The #hb_tag_t of the requested feature
- *
- * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
- * underneath the specified script and language.
- *
- * Return value: `true` if the feature is found, `false` otherwise
*
* Since: 0.9.30
**/
@@ -875,8 +491,8 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
- unsigned int *feature_index /* OUT */,
- hb_tag_t *feature_tag /* OUT */)
+ unsigned int *feature_index,
+ hb_tag_t *feature_tag)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
@@ -888,34 +504,13 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face,
return l.has_required_feature ();
}
-
-/**
- * hb_ot_layout_language_get_feature_indexes:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_index: The index of the requested language tag
- * @start_offset: offset of the first feature tag to retrieve
- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
- * Output: the actual number of feature tags returned (may be zero)
- * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query
- *
- * Fetches a list of all features in the specified face's GSUB table
- * or GPOS table, underneath the specified script and language. The list
- * returned will begin at the offset provided.
- *
- * Return value: Total number of features.
- *
- * Since: 0.6.0
- *
- **/
unsigned int
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
unsigned int start_offset,
- unsigned int *feature_count /* IN/OUT */,
+ unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -924,27 +519,6 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
}
-
-/**
- * hb_ot_layout_language_get_feature_tags:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_index: The index of the requested language tag
- * @start_offset: offset of the first feature tag to retrieve
- * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
- * Output = the actual number of feature tags returned (may be zero)
- * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query
- *
- * Fetches a list of all features in the specified face's GSUB table
- * or GPOS table, underneath the specified script and language. The list
- * returned will begin at the offset provided.
- *
- * Return value: Total number of feature tags.
- *
- * Since: 0.6.0
- *
- **/
unsigned int
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
@@ -952,7 +526,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
unsigned int language_index,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
- hb_tag_t *feature_tags /* OUT */)
+ hb_tag_t *feature_tags /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
@@ -970,30 +544,13 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
}
-/**
- * hb_ot_layout_language_find_feature:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @script_index: The index of the requested script tag
- * @language_index: The index of the requested language tag
- * @feature_tag: #hb_tag_t of the feature tag requested
- * @feature_index: (out): The index of the requested feature
- *
- * Fetches the index of a given feature tag in the specified face's GSUB table
- * or GPOS table, underneath the specified script and language.
- *
- * Return value: `true` if the feature is found, `false` otherwise
- *
- * Since: 0.6.0
- *
- **/
hb_bool_t
hb_ot_layout_language_find_feature (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
hb_tag_t feature_tag,
- unsigned int *feature_index /* OUT */)
+ unsigned int *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);
@@ -1013,22 +570,8 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
return false;
}
-
/**
* hb_ot_layout_feature_get_lookups:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @feature_index: The index of the requested feature
- * @start_offset: offset of the first lookup to retrieve
- * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return;
- * Output = the actual number of lookups returned (may be zero)
- * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query
- *
- * Fetches a list of all lookups enumerated for the specified feature, in
- * the specified face's GSUB table or GPOS table. The list returned will
- * begin at the offset provided.
- *
- * Return value: Total number of lookups.
*
* Since: 0.9.7
**/
@@ -1037,7 +580,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
hb_tag_t table_tag,
unsigned int feature_index,
unsigned int start_offset,
- unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */)
{
return hb_ot_layout_feature_with_variations_get_lookups (face,
@@ -1049,16 +592,8 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
lookup_indexes);
}
-
/**
* hb_ot_layout_table_get_lookup_count:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- *
- * Fetches the total number of lookups enumerated in the specified
- * face's GSUB table or GPOS table.
- *
- * Return value: Total number of lookups.
*
* Since: 0.9.22
**/
@@ -1066,276 +601,208 @@ unsigned int
hb_ot_layout_table_get_lookup_count (hb_face_t *face,
hb_tag_t table_tag)
{
- return get_gsubgpos_table (face, table_tag).get_lookup_count ();
-}
-
-
-struct hb_collect_features_context_t
-{
- hb_collect_features_context_t (hb_face_t *face,
- hb_tag_t table_tag,
- hb_set_t *feature_indices_,
- const hb_tag_t *features)
-
- : g (get_gsubgpos_table (face, table_tag)),
- feature_indices (feature_indices_),
- has_feature_filter (false),
- script_count (0),langsys_count (0), feature_index_count (0)
- {
- compute_feature_filter (features);
- }
-
- void compute_feature_filter (const hb_tag_t *features)
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return 0;
+ switch (table_tag)
{
- if (features == nullptr)
+ case HB_OT_TAG_GSUB:
{
- has_feature_filter = false;
- return;
+ return hb_ot_layout_from_face (face)->gsub_lookup_count;
}
-
- has_feature_filter = true;
- hb_set_t features_set;
- for (; *features; features++)
- features_set.add (*features);
-
- for (unsigned i = 0; i < g.get_feature_count (); i++)
+ case HB_OT_TAG_GPOS:
{
- hb_tag_t tag = g.get_feature_tag (i);
- if (features_set.has (tag))
- feature_indices_filter.add(i);
+ return hb_ot_layout_from_face (face)->gpos_lookup_count;
}
}
-
- bool visited (const OT::Script &s)
- {
- /* We might have Null() object here. Don't want to involve
- * that in the memoize. So, detect empty objects and return. */
- if (unlikely (!s.has_default_lang_sys () &&
- !s.get_lang_sys_count ()))
- return true;
-
- if (script_count++ > HB_MAX_SCRIPTS)
- return true;
-
- return visited (s, visited_script);
- }
- bool visited (const OT::LangSys &l)
- {
- /* We might have Null() object here. Don't want to involve
- * that in the memoize. So, detect empty objects and return. */
- if (unlikely (!l.has_required_feature () &&
- !l.get_feature_count ()))
- return true;
-
- if (langsys_count++ > HB_MAX_LANGSYS)
- return true;
-
- return visited (l, visited_langsys);
- }
-
- bool visited_feature_indices (unsigned count)
- {
- feature_index_count += count;
- return feature_index_count > HB_MAX_FEATURE_INDICES;
- }
-
- private:
- template <typename T>
- bool visited (const T &p, hb_set_t &visited_set)
- {
- hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) &p - (uintptr_t) &g);
- if (visited_set.has (delta))
- return true;
-
- visited_set.add (delta);
- return false;
- }
-
- public:
- const OT::GSUBGPOS &g;
- hb_set_t *feature_indices;
- hb_set_t feature_indices_filter;
- bool has_feature_filter;
-
- private:
- hb_set_t visited_script;
- hb_set_t visited_langsys;
- unsigned int script_count;
- unsigned int langsys_count;
- unsigned int feature_index_count;
-};
+ return 0;
+}
static void
-langsys_collect_features (hb_collect_features_context_t *c,
- const OT::LangSys &l)
-{
- if (c->visited (l)) return;
+_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookups (face,
+ table_tag,
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ lookup_indexes->add (lookup_indices[i]);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
+}
- if (!c->has_feature_filter)
+static void
+_hb_ot_layout_collect_lookups_features (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ if (!features)
{
- /* All features. */
- if (l.has_required_feature () && !c->visited_feature_indices (1))
- c->feature_indices->add (l.get_required_feature_index ());
-
- // TODO(garretrieger): filter out indices >= feature count?
- if (!c->visited_feature_indices (l.featureIndex.len))
- l.add_feature_indexes_to (c->feature_indices);
+ unsigned int required_feature_index;
+ if (hb_ot_layout_language_get_required_feature (face,
+ table_tag,
+ script_index,
+ language_index,
+ &required_feature_index,
+ nullptr))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ required_feature_index,
+ lookup_indexes);
+
+ /* All features */
+ unsigned int feature_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (feature_indices);
+ hb_ot_layout_language_get_feature_indexes (face,
+ table_tag,
+ script_index,
+ language_index,
+ offset, &len,
+ feature_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_indices[i],
+ lookup_indexes);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (feature_indices));
}
else
{
- if (c->feature_indices_filter.is_empty()) return;
- unsigned int num_features = l.get_feature_count ();
- for (unsigned int i = 0; i < num_features; i++)
+ for (; *features; features++)
{
- unsigned int feature_index = l.get_feature_index (i);
- if (!c->feature_indices_filter.has (feature_index)) continue;
-
- c->feature_indices->add (feature_index);
- c->feature_indices_filter.del (feature_index);
+ unsigned int feature_index;
+ if (hb_ot_layout_language_find_feature (face,
+ table_tag,
+ script_index,
+ language_index,
+ *features,
+ &feature_index))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_index,
+ lookup_indexes);
}
}
}
static void
-script_collect_features (hb_collect_features_context_t *c,
- const OT::Script &s,
- const hb_tag_t *languages)
-{
- if (c->visited (s)) return;
+_hb_ot_layout_collect_lookups_languages (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+ features,
+ lookup_indexes);
if (!languages)
{
- /* All languages. */
- if (s.has_default_lang_sys ())
- langsys_collect_features (c,
- s.get_default_lang_sys ());
-
-
- unsigned int count = s.get_lang_sys_count ();
+ /* All languages */
+ unsigned int count = hb_ot_layout_script_get_language_tags (face,
+ table_tag,
+ script_index,
+ 0, nullptr, nullptr);
for (unsigned int language_index = 0; language_index < count; language_index++)
- langsys_collect_features (c,
- s.get_lang_sys (language_index));
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
}
else
{
for (; *languages; languages++)
{
unsigned int language_index;
- if (s.find_lang_sys_index (*languages, &language_index))
- langsys_collect_features (c,
- s.get_lang_sys (language_index));
-
+ if (hb_ot_layout_script_find_language (face,
+ table_tag,
+ script_index,
+ *languages,
+ &language_index))
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
}
}
}
-
/**
- * hb_ot_layout_collect_features:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @scripts: (nullable) (array zero-terminated=1): The array of scripts to collect features for,
- * terminated by %HB_TAG_NONE
- * @languages: (nullable) (array zero-terminated=1): The array of languages to collect features for,
- * terminated by %HB_TAG_NONE
- * @features: (nullable) (array zero-terminated=1): The array of features to collect,
- * terminated by %HB_TAG_NONE
- * @feature_indexes: (out): The array of feature indexes found for the query
- *
- * Fetches a list of all feature indexes in the specified face's GSUB table
- * or GPOS table, underneath the specified scripts, languages, and features.
- * If no list of scripts is provided, all scripts will be queried. If no list
- * of languages is provided, all languages will be queried. If no list of
- * features is provided, all features will be queried.
+ * hb_ot_layout_collect_lookups:
*
- * Since: 1.8.5
+ * Since: 0.9.8
**/
void
-hb_ot_layout_collect_features (hb_face_t *face,
- hb_tag_t table_tag,
- const hb_tag_t *scripts,
- const hb_tag_t *languages,
- const hb_tag_t *features,
- hb_set_t *feature_indexes /* OUT */)
+hb_ot_layout_collect_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *scripts,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
{
- hb_collect_features_context_t c (face, table_tag, feature_indexes, features);
if (!scripts)
{
- /* All scripts. */
- unsigned int count = c.g.get_script_count ();
+ /* All scripts */
+ unsigned int count = hb_ot_layout_table_get_script_tags (face,
+ table_tag,
+ 0, nullptr, nullptr);
for (unsigned int script_index = 0; script_index < count; script_index++)
- script_collect_features (&c,
- c.g.get_script (script_index),
- languages);
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
}
else
{
for (; *scripts; scripts++)
{
unsigned int script_index;
- if (c.g.find_script_index (*scripts, &script_index))
- script_collect_features (&c,
- c.g.get_script (script_index),
- languages);
+ if (hb_ot_layout_table_find_script (face,
+ table_tag,
+ *scripts,
+ &script_index))
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
}
}
}
-
-/**
- * hb_ot_layout_collect_lookups:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @scripts: (nullable) (array zero-terminated=1): The array of scripts to collect lookups for,
- * terminated by %HB_TAG_NONE
- * @languages: (nullable) (array zero-terminated=1): The array of languages to collect lookups for,
- * terminated by %HB_TAG_NONE
- * @features: (nullable) (array zero-terminated=1): The array of features to collect lookups for,
- * terminated by %HB_TAG_NONE
- * @lookup_indexes: (out): The array of lookup indexes found for the query
- *
- * Fetches a list of all feature-lookup indexes in the specified face's GSUB
- * table or GPOS table, underneath the specified scripts, languages, and
- * features. If no list of scripts is provided, all scripts will be queried.
- * If no list of languages is provided, all languages will be queried. If no
- * list of features is provided, all features will be queried.
- *
- * Since: 0.9.8
- **/
-void
-hb_ot_layout_collect_lookups (hb_face_t *face,
- hb_tag_t table_tag,
- const hb_tag_t *scripts,
- const hb_tag_t *languages,
- const hb_tag_t *features,
- hb_set_t *lookup_indexes /* OUT */)
-{
- const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
-
- hb_set_t feature_indexes;
- hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes);
-
- for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID;
- hb_set_next (&feature_indexes, &feature_index);)
- g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
-
- g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes);
-}
-
-
-#ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
/**
* hb_ot_layout_lookup_collect_glyphs:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @lookup_index: The index of the feature lookup to query
- * @glyphs_before: (out): Array of glyphs preceding the substitution range
- * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
- * @glyphs_after: (out): Array of glyphs following the substitution range
- * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup
- *
- * Fetches a list of all glyphs affected by the specified lookup in the
- * specified face's GSUB table or GPOS table.
*
* Since: 0.9.7
**/
@@ -1343,11 +810,13 @@ 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;
+
OT::hb_collect_glyphs_context_t c (face,
glyphs_before,
glyphs_input,
@@ -1358,40 +827,22 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
{
case HB_OT_TAG_GSUB:
{
- const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
l.collect_glyphs (&c);
return;
}
case HB_OT_TAG_GPOS:
{
- const OT::PosLookup& l = face->table.GPOS->table->get_lookup (lookup_index);
+ const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
l.collect_glyphs (&c);
return;
}
}
}
-#endif
/* Variations support */
-
-/**
- * hb_ot_layout_table_find_feature_variations:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @coords: The variation coordinates to query
- * @num_coords: The number of variation coordinates
- * @variations_index: (out): The array of feature variations found for the query
- *
- * Fetches a list of feature variations in the specified face's GSUB table
- * or GPOS table, at the specified variation coordinates.
- *
- * Return value: `true` if feature variations were found, `false` otherwise.
- *
- * Since: 1.4.0
- *
- **/
hb_bool_t
hb_ot_layout_table_find_feature_variations (hb_face_t *face,
hb_tag_t table_tag,
@@ -1404,27 +855,6 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face,
return g.find_variations_index (coords, num_coords, variations_index);
}
-
-/**
- * hb_ot_layout_feature_with_variations_get_lookups:
- * @face: #hb_face_t to work upon
- * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
- * @feature_index: The index of the feature to query
- * @variations_index: The index of the feature variation to query
- * @start_offset: offset of the first lookup to retrieve
- * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return;
- * Output = the actual number of lookups returned (may be zero)
- * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query
- *
- * Fetches a list of all lookups enumerated for the specified feature, in
- * the specified face's GSUB table or GPOS table, enabled at the specified
- * variations index. The list returned will begin at the offset provided.
- *
- * Return value: Total number of lookups.
- *
- * Since: 1.4.0
- *
- **/
unsigned int
hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
hb_tag_t table_tag,
@@ -1447,38 +877,14 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
* OT::GSUB
*/
-
-/**
- * hb_ot_layout_has_substitution:
- * @face: #hb_face_t to work upon
- *
- * Tests whether the specified face includes any GSUB substitutions.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 0.6.0
- *
- **/
hb_bool_t
hb_ot_layout_has_substitution (hb_face_t *face)
{
- return face->table.GSUB->table->has_data ();
+ return &_get_gsub (face) != &OT::Null(OT::GSUB);
}
-
/**
* hb_ot_layout_lookup_would_substitute:
- * @face: #hb_face_t to work upon
- * @lookup_index: The index of the lookup to query
- * @glyphs: The sequence of glyphs to query for substitution
- * @glyphs_length: The length of the glyph sequence
- * @zero_context: #hb_bool_t indicating whether pre-/post-context are disallowed
- * in substitutions
- *
- * Tests whether a specified lookup in the specified face would
- * trigger a substitution on the given glyph sequence.
- *
- * Return value: `true` if a substitution would be triggered, `false` otherwise
*
* Since: 0.9.7
**/
@@ -1489,195 +895,90 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face,
unsigned int glyphs_length,
hb_bool_t zero_context)
{
- auto &gsub = face->table.GSUB;
- if (unlikely (lookup_index >= gsub->lookup_count)) return false;
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
+ return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+}
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context)
+{
+ if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context);
- const OT::SubstLookup& l = gsub->table->get_lookup (lookup_index);
- auto *accel = gsub->get_accel (lookup_index);
- return accel && l.would_apply (&c, accel);
-}
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+ return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]);
+}
-/**
- * hb_ot_layout_substitute_start:
- * @font: #hb_font_t to use
- * @buffer: #hb_buffer_t buffer to work upon
- *
- * Called before substitution lookups are performed, to ensure that glyph
- * class and other properties are set on the glyphs in the buffer.
- *
- **/
void
-hb_ot_layout_substitute_start (hb_font_t *font,
- hb_buffer_t *buffer)
+hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
{
- _hb_ot_layout_set_glyph_props (font, buffer);
+ OT::GSUB::substitute_start (font, buffer);
}
/**
* hb_ot_layout_lookup_substitute_closure:
- * @face: #hb_face_t to work upon
- * @lookup_index: index of the feature lookup to query
- * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookup
- *
- * Compute the transitive closure of glyphs needed for a
- * specified lookup.
*
* Since: 0.9.7
**/
void
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
- unsigned int lookup_index,
- hb_set_t *glyphs /* OUT */)
+ unsigned int lookup_index,
+ hb_set_t *glyphs)
{
- hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> done_lookups_glyph_set;
- OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
+ OT::hb_closure_context_t c (face, glyphs);
- const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
+ const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
- l.closure (&c, lookup_index);
-}
-
-/**
- * hb_ot_layout_lookups_substitute_closure:
- * @face: #hb_face_t to work upon
- * @lookups: The set of lookups to query
- * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookups
- *
- * Compute the transitive closure of glyphs needed for all of the
- * provided lookups.
- *
- * Since: 1.8.1
- **/
-void
-hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
- const hb_set_t *lookups,
- hb_set_t *glyphs /* OUT */)
-{
- hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> done_lookups_glyph_set;
- OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
- const GSUB& gsub = *face->table.GSUB->table;
-
- unsigned int iteration_count = 0;
- unsigned int glyphs_length;
- do
- {
- c.reset_lookup_visit_count ();
- glyphs_length = glyphs->get_population ();
- if (lookups)
- {
- for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
- gsub.get_lookup (lookup_index).closure (&c, lookup_index);
- }
- else
- {
- for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
- gsub.get_lookup (i).closure (&c, i);
- }
- } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
- glyphs_length != glyphs->get_population ());
+ l.closure (&c);
}
/*
- * GPOS
+ * OT::GPOS
*/
-
-/**
- * hb_ot_layout_has_positioning:
- * @face: #hb_face_t to work upon
- *
- * Tests whether the specified face includes any GPOS positioning.
- *
- * Return value: `true` if the face has GPOS data, `false` otherwise
- *
- **/
hb_bool_t
hb_ot_layout_has_positioning (hb_face_t *face)
{
- return face->table.GPOS->table->has_data ();
+ return &_get_gpos (face) != &OT::Null(OT::GPOS);
}
-/**
- * hb_ot_layout_position_start:
- * @font: #hb_font_t to use
- * @buffer: #hb_buffer_t buffer to work upon
- *
- * Called before positioning lookups are performed, to ensure that glyph
- * attachment types and glyph-attachment chains are set for the glyphs in the buffer.
- *
- **/
void
hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_start (font, buffer);
+ OT::GPOS::position_start (font, buffer);
}
-
-/**
- * hb_ot_layout_position_finish_advances:
- * @font: #hb_font_t to use
- * @buffer: #hb_buffer_t buffer to work upon
- *
- * Called after positioning lookups are performed, to finish glyph advances.
- *
- **/
void
hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_finish_advances (font, buffer);
+ OT::GPOS::position_finish_advances (font, buffer);
}
-/**
- * hb_ot_layout_position_finish_offsets:
- * @font: #hb_font_t to use
- * @buffer: #hb_buffer_t buffer to work upon
- *
- * Called after positioning lookups are performed, to finish glyph offsets.
- *
- **/
void
hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
{
- GPOS::position_finish_offsets (font, buffer);
+ OT::GPOS::position_finish_offsets (font, buffer);
}
-
-#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
/**
* hb_ot_layout_get_size_params:
- * @face: #hb_face_t to work upon
- * @design_size: (out): The design size of the face
- * @subfamily_id: (out): The identifier of the face within the font subfamily
- * @subfamily_name_id: (out): The ‘name’ table name ID of the face within the font subfamily
- * @range_start: (out): The minimum size of the recommended size range for the face
- * @range_end: (out): The maximum size of the recommended size range for the face
- *
- * Fetches optical-size feature data (i.e., the `size` feature from GPOS). Note that
- * the subfamily_id and the subfamily name string (accessible via the subfamily_name_id)
- * as used here are defined as pertaining only to fonts within a font family that differ
- * specifically in their respective size ranges; other ways to differentiate fonts within
- * a subfamily are not covered by the `size` feature.
- *
- * For more information on this distinction, see the [`size` feature documentation](
- * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size).
- *
- * Return value: `true` if data found, `false` otherwise
*
* Since: 0.9.10
**/
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 */
- hb_ot_name_id_t *subfamily_name_id, /* OUT. May be NULL */
- unsigned int *range_start, /* OUT. May be NULL */
- unsigned int *range_end /* OUT. May be NULL */)
-{
- const GPOS &gpos = *face->table.GPOS->table;
+hb_ot_layout_get_size_params (hb_face_t *face,
+ 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');
unsigned int num_features = gpos.get_feature_count ();
@@ -1690,135 +991,29 @@ hb_ot_layout_get_size_params (hb_face_t *face,
if (params.designSize)
{
- if (design_size) *design_size = params.designSize;
- if (subfamily_id) *subfamily_id = params.subfamilyID;
- if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID;
- if (range_start) *range_start = params.rangeStart;
- if (range_end) *range_end = params.rangeEnd;
+#define PARAM(a, A) if (a) *a = params.A
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
return true;
}
}
}
- if (design_size) *design_size = 0;
- if (subfamily_id) *subfamily_id = 0;
- if (subfamily_name_id) *subfamily_name_id = HB_OT_NAME_ID_INVALID;
- if (range_start) *range_start = 0;
- if (range_end) *range_end = 0;
-
- return false;
-}
-
-
-/**
- * hb_ot_layout_feature_get_name_ids:
- * @face: #hb_face_t to work upon
- * @table_tag: table tag to query, "GSUB" or "GPOS".
- * @feature_index: index of feature to query.
- * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string
- * for a user-interface label for this feature. (May be NULL.)
- * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string
- * that an application can use for tooltip text for this
- * feature. (May be NULL.)
- * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text
- * that illustrates the effect of this feature. (May be NULL.)
- * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.)
- * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify
- * strings for user-interface labels for the feature
- * parameters. (Must be zero if numParameters is zero.)
- *
- * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
- * "Character Variant" ('cvXX') features.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.0.0
- **/
-hb_bool_t
-hb_ot_layout_feature_get_name_ids (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int feature_index,
- hb_ot_name_id_t *label_id, /* OUT. May be NULL */
- hb_ot_name_id_t *tooltip_id, /* OUT. May be NULL */
- hb_ot_name_id_t *sample_id, /* OUT. May be NULL */
- unsigned int *num_named_parameters, /* OUT. May be NULL */
- hb_ot_name_id_t *first_param_id /* OUT. May be NULL */)
-{
- const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
-
- hb_tag_t feature_tag = g.get_feature_tag (feature_index);
- const OT::Feature &f = g.get_feature (feature_index);
-
- const OT::FeatureParams &feature_params = f.get_feature_params ();
- if (&feature_params != &Null (OT::FeatureParams))
- {
- const OT::FeatureParamsStylisticSet& ss_params =
- feature_params.get_stylistic_set_params (feature_tag);
- if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */
- {
- if (label_id) *label_id = ss_params.uiNameID;
- // ssXX features don't have the rest
- if (tooltip_id) *tooltip_id = HB_OT_NAME_ID_INVALID;
- if (sample_id) *sample_id = HB_OT_NAME_ID_INVALID;
- if (num_named_parameters) *num_named_parameters = 0;
- if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID;
- return true;
- }
- const OT::FeatureParamsCharacterVariants& cv_params =
- feature_params.get_character_variants_params (feature_tag);
- if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */
- {
- if (label_id) *label_id = cv_params.featUILableNameID;
- if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID;
- if (sample_id) *sample_id = cv_params.sampleTextNameID;
- if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters;
- if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID;
- return true;
- }
- }
+#define PARAM(a, A) if (a) *a = 0
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
- if (label_id) *label_id = HB_OT_NAME_ID_INVALID;
- if (tooltip_id) *tooltip_id = HB_OT_NAME_ID_INVALID;
- if (sample_id) *sample_id = HB_OT_NAME_ID_INVALID;
- if (num_named_parameters) *num_named_parameters = 0;
- if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID;
return false;
}
-/**
- * hb_ot_layout_feature_get_characters:
- * @face: #hb_face_t to work upon
- * @table_tag: table tag to query, "GSUB" or "GPOS".
- * @feature_index: index of feature to query.
- * @start_offset: offset of the first character to retrieve
- * @char_count: (inout) (optional): Input = the maximum number of characters to return;
- * Output = the actual number of characters returned (may be zero)
- * @characters: (out caller-allocates) (array length=char_count): A buffer pointer.
- * The Unicode codepoints of the characters for which this feature provides
- * glyph variants.
- *
- * Fetches a list of the characters defined as having a variant under the specified
- * "Character Variant" ("cvXX") feature tag.
- *
- * Return value: Number of total sample characters in the cvXX feature.
- *
- * Since: 2.0.0
- **/
-unsigned int
-hb_ot_layout_feature_get_characters (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int feature_index,
- unsigned int start_offset,
- unsigned int *char_count, /* IN/OUT. May be NULL */
- hb_codepoint_t *characters /* OUT. May be NULL */)
-{
- const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
- return g.get_feature (feature_index)
- .get_feature_params ()
- .get_character_variants_params(g.get_feature_tag (feature_index))
- .get_characters (start_offset, char_count, characters);
-}
-#endif
/*
@@ -1829,74 +1024,133 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
struct GSUBProxy
{
- static constexpr unsigned table_index = 0u;
- static constexpr bool always_inplace = false;
+ static const unsigned int table_index = 0;
+ static const bool inplace = false;
typedef OT::SubstLookup Lookup;
GSUBProxy (hb_face_t *face) :
- accel (*face->table.GSUB) {}
+ table (*hb_ot_layout_from_face (face)->gsub),
+ accels (hb_ot_layout_from_face (face)->gsub_accels) {}
- const GSUB::accelerator_t &accel;
+ const OT::GSUB &table;
+ const hb_ot_layout_lookup_accelerator_t *accels;
};
struct GPOSProxy
{
- static constexpr unsigned table_index = 1u;
- static constexpr bool always_inplace = true;
+ static const unsigned int table_index = 1;
+ static const bool inplace = true;
typedef OT::PosLookup Lookup;
GPOSProxy (hb_face_t *face) :
- accel (*face->table.GPOS) {}
+ table (*hb_ot_layout_from_face (face)->gpos),
+ accels (hb_ot_layout_from_face (face)->gpos_accels) {}
- const GPOS::accelerator_t &accel;
+ const OT::GPOS &table;
+ const hb_ot_layout_lookup_accelerator_t *accels;
};
-static inline bool
-apply_forward (OT::hb_ot_apply_context_t *c,
- const OT::hb_ot_layout_lookup_accelerator_t &accel,
- unsigned subtable_count)
+struct hb_get_subtables_context_t :
+ OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
{
- bool use_cache = accel.cache_enter (c);
+ template <typename Type>
+ static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c)
+ {
+ const Type *typed_obj = (const Type *) obj;
+ return typed_obj->apply (c);
+ }
+
+ typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c);
+
+ struct hb_applicable_t
+ {
+ inline void init (const void *obj_, hb_apply_func_t apply_func_)
+ {
+ obj = obj_;
+ apply_func = apply_func_;
+ }
+ inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); }
+
+ private:
+ const void *obj;
+ hb_apply_func_t apply_func;
+ };
+
+ typedef hb_auto_array_t<hb_applicable_t> array_t;
+
+ /* Dispatch interface. */
+ inline const char *get_name (void) { return "GET_SUBTABLES"; }
+ template <typename T>
+ inline return_t dispatch (const T &obj)
+ {
+ hb_applicable_t *entry = array.push();
+ if (likely (entry))
+ entry->init (&obj, apply_to<T>);
+ return HB_VOID;
+ }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+
+ hb_get_subtables_context_t (array_t &array_) :
+ array (array_),
+ debug_depth (0) {}
+
+ array_t &array;
+ unsigned int debug_depth;
+};
+
+static inline bool
+apply_forward (OT::hb_apply_context_t *c,
+ const hb_ot_layout_lookup_accelerator_t &accel,
+ const hb_get_subtables_context_t::array_t &subtables)
+{
bool ret = false;
hb_buffer_t *buffer = c->buffer;
- while (buffer->idx < buffer->len && buffer->successful)
+ while (buffer->idx < buffer->len && !buffer->in_error)
{
bool applied = false;
- if (accel.digest.may_have (buffer->cur().codepoint) &&
+ if (accel.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
{
- applied = accel.apply (c, subtable_count, use_cache);
+ for (unsigned int i = 0; i < subtables.len; i++)
+ if (subtables[i].apply (c))
+ {
+ applied = true;
+ break;
+ }
}
if (applied)
ret = true;
else
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
-
- if (use_cache)
- accel.cache_leave (c);
-
return ret;
}
static inline bool
-apply_backward (OT::hb_ot_apply_context_t *c,
- const OT::hb_ot_layout_lookup_accelerator_t &accel,
- unsigned subtable_count)
+apply_backward (OT::hb_apply_context_t *c,
+ const hb_ot_layout_lookup_accelerator_t &accel,
+ const hb_get_subtables_context_t::array_t &subtables)
{
bool ret = false;
hb_buffer_t *buffer = c->buffer;
do
{
- if (accel.digest.may_have (buffer->cur().codepoint) &&
+ if (accel.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
- ret |= accel.apply (c, subtable_count, false);
-
+ {
+ for (unsigned int i = 0; i < subtables.len; i++)
+ if (subtables[i].apply (c))
+ {
+ ret = true;
+ break;
+ }
+ }
/* The reverse lookup doesn't "advance" cursor (for good reason). */
buffer->idx--;
@@ -1906,42 +1160,48 @@ apply_backward (OT::hb_ot_apply_context_t *c,
}
template <typename Proxy>
-static inline bool
-apply_string (OT::hb_ot_apply_context_t *c,
+static inline void
+apply_string (OT::hb_apply_context_t *c,
const typename Proxy::Lookup &lookup,
- const OT::hb_ot_layout_lookup_accelerator_t &accel)
+ const hb_ot_layout_lookup_accelerator_t &accel)
{
hb_buffer_t *buffer = c->buffer;
- unsigned subtable_count = lookup.get_subtable_count ();
if (unlikely (!buffer->len || !c->lookup_mask))
- return false;
-
- bool ret = false;
+ return;
c->set_lookup_props (lookup.get_props ());
+ hb_get_subtables_context_t::array_t subtables;
+ hb_get_subtables_context_t c_get_subtables (subtables);
+ lookup.dispatch (&c_get_subtables);
+
if (likely (!lookup.is_reverse ()))
{
/* in/out forward substitution/positioning */
- if (!Proxy::always_inplace)
+ if (Proxy::table_index == 0)
buffer->clear_output ();
-
buffer->idx = 0;
- ret = apply_forward (c, accel, subtable_count);
- if (!Proxy::always_inplace)
- buffer->sync ();
+ bool ret;
+ ret = apply_forward (c, accel, subtables);
+ if (ret)
+ {
+ if (!Proxy::inplace)
+ buffer->swap_buffers ();
+ else
+ assert (!buffer->has_separate_output ());
+ }
}
else
{
/* in-place backward substitution/positioning */
- assert (!buffer->have_output);
+ if (Proxy::table_index == 0)
+ buffer->remove_output ();
buffer->idx = buffer->len - 1;
- ret = apply_backward (c, accel, subtable_count);
- }
- return ret;
+ apply_backward (c, accel, subtables);
+ }
}
template <typename Proxy>
@@ -1952,55 +1212,29 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
{
const unsigned int table_index = proxy.table_index;
unsigned int i = 0;
- OT::hb_ot_apply_context_t c (table_index, font, buffer);
- c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>);
+ OT::hb_apply_context_t c (table_index, font, buffer);
+ c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
- for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
- {
+ for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) {
const stage_map_t *stage = &stages[table_index][stage_index];
for (; i < stage->last_lookup; i++)
{
- auto &lookup = lookups[table_index][i];
-
- unsigned int lookup_index = lookup.index;
-
- auto *accel = proxy.accel.get_accel (lookup_index);
- if (unlikely (!accel)) continue;
-
- if (buffer->messaging () &&
- !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue;
-
- /* c.digest is a digest of all the current glyphs in the buffer
- * (plus some past glyphs).
- *
- * Only try applying the lookup if there is any overlap. */
- if (accel->digest.may_have (c.digest))
- {
- c.set_lookup_index (lookup_index);
- c.set_lookup_mask (lookup.mask);
- c.set_auto_zwj (lookup.auto_zwj);
- c.set_auto_zwnj (lookup.auto_zwnj);
- c.set_random (lookup.random);
- c.set_per_syllable (lookup.per_syllable);
-
- apply_string<Proxy> (&c,
- proxy.accel.table->get_lookup (lookup_index),
- *accel);
- }
- else if (buffer->messaging ())
- (void) buffer->message (font, "skipped lookup %u feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag));
-
- if (buffer->messaging ())
- (void) buffer->message (font, "end lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag));
+ unsigned int lookup_index = lookups[table_index][i].index;
+ if (!buffer->message (font, "start lookup %d", lookup_index)) continue;
+ 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]);
+ (void) buffer->message (font, "end lookup %d", lookup_index);
}
if (stage->pause_func)
{
- if (stage->pause_func (plan, font, buffer))
- {
- /* Refresh working buffer digest since buffer changed. */
- c.digest = buffer->digest ();
- }
+ buffer->clear_output ();
+ stage->pause_func (plan, font, buffer);
}
}
}
@@ -2008,472 +1242,19 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
{
GSUBProxy proxy (font->face);
- if (buffer->messaging () &&
- !buffer->message (font, "start table GSUB")) return;
apply (proxy, plan, font, buffer);
- if (buffer->messaging ())
- (void) buffer->message (font, "end table GSUB");
}
void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
{
GPOSProxy proxy (font->face);
- if (buffer->messaging () &&
- !buffer->message (font, "start table GPOS")) return;
apply (proxy, plan, font, buffer);
- if (buffer->messaging ())
- (void) buffer->message (font, "end table GPOS");
}
-void
-hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
const OT::SubstLookup &lookup,
- const OT::hb_ot_layout_lookup_accelerator_t &accel)
+ const hb_ot_layout_lookup_accelerator_t &accel)
{
apply_string<GSUBProxy> (c, lookup, accel);
}
-
-#ifndef HB_NO_BASE
-/**
- * hb_ot_layout_get_horizontal_baseline_tag_for_script:
- * @script: a script tag.
- *
- * Fetches the dominant horizontal baseline tag used by @script.
- *
- * Return value: dominant baseline tag for the @script.
- *
- * Since: 4.0.0
- **/
-hb_ot_layout_baseline_tag_t
-hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script)
-{
- /* Keep in sync with hb_ot_layout_get_baseline_with_fallback */
- switch ((int) script)
- {
- /* Unicode-1.1 additions */
- case HB_SCRIPT_BENGALI:
- case HB_SCRIPT_DEVANAGARI:
- case HB_SCRIPT_GUJARATI:
- case HB_SCRIPT_GURMUKHI:
- /* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN:
- /* Unicode-4.0 additions */
- case HB_SCRIPT_LIMBU:
- /* Unicode-4.1 additions */
- case HB_SCRIPT_SYLOTI_NAGRI:
- /* Unicode-5.0 additions */
- case HB_SCRIPT_PHAGS_PA:
- /* Unicode-5.2 additions */
- case HB_SCRIPT_MEETEI_MAYEK:
- /* Unicode-6.1 additions */
- case HB_SCRIPT_SHARADA:
- case HB_SCRIPT_TAKRI:
- /* Unicode-7.0 additions */
- case HB_SCRIPT_MODI:
- case HB_SCRIPT_SIDDHAM:
- case HB_SCRIPT_TIRHUTA:
- /* Unicode-9.0 additions */
- case HB_SCRIPT_MARCHEN:
- case HB_SCRIPT_NEWA:
- /* Unicode-10.0 additions */
- case HB_SCRIPT_SOYOMBO:
- case HB_SCRIPT_ZANABAZAR_SQUARE:
- /* Unicode-11.0 additions */
- case HB_SCRIPT_DOGRA:
- case HB_SCRIPT_GUNJALA_GONDI:
- /* Unicode-12.0 additions */
- case HB_SCRIPT_NANDINAGARI:
- return HB_OT_LAYOUT_BASELINE_TAG_HANGING;
-
- /* Unicode-1.1 additions */
- case HB_SCRIPT_HANGUL:
- case HB_SCRIPT_HAN:
- case HB_SCRIPT_HIRAGANA:
- case HB_SCRIPT_KATAKANA:
- /* Unicode-3.0 additions */
- case HB_SCRIPT_BOPOMOFO:
- /* Unicode-9.0 additions */
- case HB_SCRIPT_TANGUT:
- /* Unicode-10.0 additions */
- case HB_SCRIPT_NUSHU:
- /* Unicode-13.0 additions */
- case HB_SCRIPT_KHITAN_SMALL_SCRIPT:
- return HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT;
-
- default:
- return HB_OT_LAYOUT_BASELINE_TAG_ROMAN;
- }
-}
-
-/**
- * hb_ot_layout_get_baseline:
- * @font: a font
- * @baseline_tag: a baseline tag
- * @direction: text direction.
- * @script_tag: script tag.
- * @language_tag: language tag, currently unused.
- * @coord: (out) (nullable): baseline value if found.
- *
- * Fetches a baseline value from the face.
- *
- * Return value: `true` if found baseline value in the font.
- *
- * Since: 2.6.0
- **/
-hb_bool_t
-hb_ot_layout_get_baseline (hb_font_t *font,
- hb_ot_layout_baseline_tag_t baseline_tag,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_position_t *coord /* OUT. May be NULL. */)
-{
- return font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
-}
-
-/**
- * hb_ot_layout_get_baseline_with_fallback:
- * @font: a font
- * @baseline_tag: a baseline tag
- * @direction: text direction.
- * @script_tag: script tag.
- * @language_tag: language tag, currently unused.
- * @coord: (out): baseline value if found.
- *
- * Fetches a baseline value from the face, and synthesizes
- * it if the font does not have it.
- *
- * Since: 4.0.0
- **/
-void
-hb_ot_layout_get_baseline_with_fallback (hb_font_t *font,
- hb_ot_layout_baseline_tag_t baseline_tag,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_position_t *coord /* OUT */)
-{
- if (hb_ot_layout_get_baseline (font,
- baseline_tag,
- direction,
- script_tag,
- language_tag,
- coord))
- return;
-
- /* Synthesize missing baselines.
- * See https://www.w3.org/TR/css-inline-3/#baseline-synthesis-fonts
- */
- switch (baseline_tag)
- {
- case HB_OT_LAYOUT_BASELINE_TAG_ROMAN:
- *coord = 0; // FIXME origin ?
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_MATH:
- {
- hb_codepoint_t glyph;
- hb_glyph_extents_t extents;
- if (HB_DIRECTION_IS_HORIZONTAL (direction) &&
- (hb_font_get_nominal_glyph (font, 0x2212u, &glyph) ||
- hb_font_get_nominal_glyph (font, '-', &glyph)) &&
- hb_font_get_glyph_extents (font, glyph, &extents))
- {
- *coord = extents.y_bearing + extents.height / 2;
- }
- else
- {
- hb_position_t x_height = font->y_scale / 2;
-#ifndef HB_NO_METRICS
- hb_ot_metrics_get_position_with_fallback (font, HB_OT_METRICS_TAG_X_HEIGHT, &x_height);
-#endif
- *coord = x_height / 2;
- }
- }
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT:
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT:
- {
- hb_position_t embox_top, embox_bottom;
-
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
- direction,
- script_tag,
- language_tag,
- &embox_top);
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
- direction,
- script_tag,
- language_tag,
- &embox_bottom);
-
- if (baseline_tag == HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT)
- *coord = embox_top + (embox_bottom - embox_top) / 10;
- else
- *coord = embox_bottom + (embox_top - embox_bottom) / 10;
- }
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT:
- if (hb_ot_layout_get_baseline (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
- direction,
- script_tag,
- language_tag,
- coord))
- *coord += HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
- else
- {
- hb_font_extents_t font_extents;
- hb_font_get_extents_for_direction (font, direction, &font_extents);
- *coord = font_extents.ascender;
- }
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT:
- if (hb_ot_layout_get_baseline (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
- direction,
- script_tag,
- language_tag,
- coord))
- *coord -= HB_DIRECTION_IS_HORIZONTAL (direction) ? font->y_scale : font->x_scale;
- else
- {
- hb_font_extents_t font_extents;
- hb_font_get_extents_for_direction (font, direction, &font_extents);
- *coord = font_extents.descender;
- }
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_HANGING:
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- {
- hb_codepoint_t ch;
- hb_codepoint_t glyph;
- hb_glyph_extents_t extents;
-
- /* Keep in sync with hb_ot_layout_get_horizontal_baseline_for_script */
- switch ((int) script_tag)
- {
- /* Unicode-1.1 additions */
- case HB_SCRIPT_BENGALI: ch = 0x0995u; break;
- case HB_SCRIPT_DEVANAGARI: ch = 0x0915u; break;
- case HB_SCRIPT_GUJARATI: ch = 0x0a95u; break;
- case HB_SCRIPT_GURMUKHI: ch = 0x0a15u; break;
- /* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN: ch = 0x0f40u; break;
- /* Unicode-4.0 additions */
- case HB_SCRIPT_LIMBU: ch = 0x1901u; break;
- /* Unicode-4.1 additions */
- case HB_SCRIPT_SYLOTI_NAGRI: ch = 0xa807u; break;
- /* Unicode-5.0 additions */
- case HB_SCRIPT_PHAGS_PA: ch = 0xa840u; break;
- /* Unicode-5.2 additions */
- case HB_SCRIPT_MEETEI_MAYEK: ch = 0xabc0u; break;
- /* Unicode-6.1 additions */
- case HB_SCRIPT_SHARADA: ch = 0x11191u; break;
- case HB_SCRIPT_TAKRI: ch = 0x1168cu; break;
- /* Unicode-7.0 additions */
- case HB_SCRIPT_MODI: ch = 0x1160eu;break;
- case HB_SCRIPT_SIDDHAM: ch = 0x11590u; break;
- case HB_SCRIPT_TIRHUTA: ch = 0x1148fu; break;
- /* Unicode-9.0 additions */
- case HB_SCRIPT_MARCHEN: ch = 0x11c72u; break;
- case HB_SCRIPT_NEWA: ch = 0x1140eu; break;
- /* Unicode-10.0 additions */
- case HB_SCRIPT_SOYOMBO: ch = 0x11a5cu; break;
- case HB_SCRIPT_ZANABAZAR_SQUARE: ch = 0x11a0bu; break;
- /* Unicode-11.0 additions */
- case HB_SCRIPT_DOGRA: ch = 0x1180au; break;
- case HB_SCRIPT_GUNJALA_GONDI: ch = 0x11d6cu; break;
- /* Unicode-12.0 additions */
- case HB_SCRIPT_NANDINAGARI: ch = 0x119b0u; break;
- default: ch = 0; break;
- }
-
- if (ch &&
- hb_font_get_nominal_glyph (font, ch, &glyph) &&
- hb_font_get_glyph_extents (font, glyph, &extents))
- *coord = extents.y_bearing;
- else
- *coord = font->y_scale * 6 / 10; // FIXME makes assumptions about origin
- }
- else
- *coord = font->x_scale * 6 / 10; // FIXME makes assumptions about origin
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL:
- {
- hb_position_t top, bottom;
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT,
- direction,
- script_tag,
- language_tag,
- &top);
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT,
- direction,
- script_tag,
- language_tag,
- &bottom);
- *coord = (top + bottom) / 2;
-
- }
- break;
-
- case HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL:
- {
- hb_position_t top, bottom;
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT,
- direction,
- script_tag,
- language_tag,
- &top);
- hb_ot_layout_get_baseline_with_fallback (font,
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT,
- direction,
- script_tag,
- language_tag,
- &bottom);
- *coord = (top + bottom) / 2;
-
- }
- break;
-
- case _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE:
- default:
- *coord = 0;
- break;
- }
-}
-
-#endif
-
-
-struct hb_get_glyph_alternates_dispatch_t :
- hb_dispatch_context_t<hb_get_glyph_alternates_dispatch_t, unsigned>
-{
- static return_t default_return_value () { return 0; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- private:
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.get_glyph_alternates (std::forward<Ts> (ds)...) )
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
- ( default_return_value () )
- public:
- template <typename T, typename ...Ts> auto
- dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
- ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
-};
-
-#ifndef HB_NO_LAYOUT_RARELY_USED
-/**
- * hb_ot_layout_lookup_get_glyph_alternates:
- * @face: a face.
- * @lookup_index: index of the feature lookup to query.
- * @glyph: a glyph id.
- * @start_offset: starting offset.
- * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return;
- * Output = the actual number of alternate glyphs returned (may be zero).
- * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer.
- * Alternate glyphs associated with the glyph id.
- *
- * Fetches alternates of a glyph from a given GSUB lookup index.
- *
- * Return value: Total number of alternates found in the specific lookup index for the given glyph id.
- *
- * Since: 2.6.8
- **/
-HB_EXTERN unsigned
-hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
- unsigned lookup_index,
- hb_codepoint_t glyph,
- unsigned start_offset,
- unsigned *alternate_count /* IN/OUT. May be NULL. */,
- hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */)
-{
- hb_get_glyph_alternates_dispatch_t c;
- const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index);
- auto ret = lookup.dispatch (&c, glyph, start_offset, alternate_count, alternate_glyphs);
- if (!ret && alternate_count) *alternate_count = 0;
- return ret;
-}
-
-
-struct hb_position_single_dispatch_t :
- hb_dispatch_context_t<hb_position_single_dispatch_t, bool>
-{
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- private:
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.position_single (std::forward<Ts> (ds)...) )
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
- ( default_return_value () )
- public:
- template <typename T, typename ...Ts> auto
- dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
- ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
-};
-
-/**
- * hb_ot_layout_lookup_get_optical_bound:
- * @font: a font.
- * @lookup_index: index of the feature lookup to query.
- * @direction: edge of the glyph to query.
- * @glyph: a glyph id.
- *
- * Fetches the optical bound of a glyph positioned at the margin of text.
- * The direction identifies which edge of the glyph to query.
- *
- * Return value: Adjustment value. Negative values mean the glyph will stick out of the margin.
- *
- * Since: 5.3.0
- **/
-hb_position_t
-hb_ot_layout_lookup_get_optical_bound (hb_font_t *font,
- unsigned lookup_index,
- hb_direction_t direction,
- hb_codepoint_t glyph)
-{
- const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index);
- hb_glyph_position_t pos = {0};
- hb_position_single_dispatch_t c;
- lookup.dispatch (&c, font, direction, glyph, pos);
- hb_position_t ret = 0;
- switch (direction)
- {
- case HB_DIRECTION_LTR:
- ret = pos.x_offset;
- break;
- case HB_DIRECTION_RTL:
- ret = pos.x_advance - pos.x_offset;
- break;
- case HB_DIRECTION_TTB:
- ret = pos.y_offset;
- break;
- case HB_DIRECTION_BTT:
- ret = pos.y_advance - pos.y_offset;
- break;
- case HB_DIRECTION_INVALID:
- default:
- break;
- }
- return ret;
-}
-#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
index 10dcc65ac07..9861f0fc7bb 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
@@ -33,118 +33,24 @@
#include "hb.h"
-#include "hb-ot-name.h"
+#include "hb-ot-tag.h"
HB_BEGIN_DECLS
-/**
- * HB_OT_TAG_BASE:
- *
- * OpenType [Baseline Table](https://docs.microsoft.com/en-us/typography/opentype/spec/base).
- */
-#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
-/**
- * HB_OT_TAG_GDEF:
- *
- * OpenType [Glyph Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef).
- */
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
-/**
- * HB_OT_TAG_GSUB:
- *
- * OpenType [Glyph Substitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub).
- */
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
-/**
- * HB_OT_TAG_GPOS:
- *
- * OpenType [Glyph Positioning Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos).
- */
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
-/**
- * HB_OT_TAG_JSTF:
- *
- * OpenType [Justification Table](https://docs.microsoft.com/en-us/typography/opentype/spec/jstf).
- */
#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
/*
- * Script & Language tags.
- */
-
-/**
- * HB_OT_TAG_DEFAULT_SCRIPT:
- *
- * OpenType script tag, `DFLT`, for features that are not script-specific.
- *
- */
-#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
-/**
- * HB_OT_TAG_DEFAULT_LANGUAGE:
- *
- * OpenType language tag, `dflt`. Not a valid language tag, but some fonts
- * mistakenly use it.
- */
-#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
-
-/**
- * HB_OT_MAX_TAGS_PER_SCRIPT:
- *
- * Maximum number of OpenType tags that can correspond to a give #hb_script_t.
- *
- * Since: 2.0.0
- **/
-#define HB_OT_MAX_TAGS_PER_SCRIPT 3u
-/**
- * HB_OT_MAX_TAGS_PER_LANGUAGE:
- *
- * Maximum number of OpenType tags that can correspond to a give #hb_language_t.
- *
- * Since: 2.0.0
- **/
-#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u
-
-HB_EXTERN void
-hb_ot_tags_from_script_and_language (hb_script_t script,
- hb_language_t language,
- unsigned int *script_count /* IN/OUT */,
- hb_tag_t *script_tags /* OUT */,
- unsigned int *language_count /* IN/OUT */,
- hb_tag_t *language_tags /* OUT */);
-
-HB_EXTERN hb_script_t
-hb_ot_tag_to_script (hb_tag_t tag);
-
-HB_EXTERN hb_language_t
-hb_ot_tag_to_language (hb_tag_t tag);
-
-HB_EXTERN void
-hb_ot_tags_to_script_and_language (hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_script_t *script /* OUT */,
- hb_language_t *language /* OUT */);
-
-
-/*
* GDEF
*/
HB_EXTERN hb_bool_t
hb_ot_layout_has_glyph_classes (hb_face_t *face);
-/**
- * hb_ot_layout_glyph_class_t:
- * @HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: Glyphs not matching the other classifications
- * @HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: Spacing, single characters, capable of accepting marks
- * @HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: Glyphs that represent ligation of multiple characters
- * @HB_OT_LAYOUT_GLYPH_CLASS_MARK: Non-spacing, combining glyphs that represent marks
- * @HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: Spacing glyphs that represent part of a single character
- *
- * The GDEF classes defined for glyphs.
- *
- **/
typedef enum {
HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 1,
@@ -162,6 +68,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
hb_ot_layout_glyph_class_t klass,
hb_set_t *glyphs /* OUT */);
+
/* Not that useful. Provides list of attach points for a glyph that a
* client may want to cache */
HB_EXTERN unsigned int
@@ -185,29 +92,9 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
* GSUB/GPOS feature query and enumeration interface
*/
-/**
- * HB_OT_LAYOUT_NO_SCRIPT_INDEX:
- *
- * Special value for script index indicating unsupported script.
- */
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu
-/**
- * HB_OT_LAYOUT_NO_FEATURE_INDEX:
- *
- * Special value for feature index indicating unsupported feature.
- */
#define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu
-/**
- * HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX:
- *
- * Special value for language index indicating default or unsupported language.
- */
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu
-/**
- * HB_OT_LAYOUT_NO_VARIATIONS_INDEX:
- *
- * Special value for variations index indicating unsupported variation.
- */
#define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu
HB_EXTERN unsigned int
@@ -221,15 +108,15 @@ HB_EXTERN hb_bool_t
hb_ot_layout_table_find_script (hb_face_t *face,
hb_tag_t table_tag,
hb_tag_t script_tag,
- unsigned int *script_index /* OUT */);
+ unsigned int *script_index);
+/* Like find_script, but takes zero-terminated array of scripts to test */
HB_EXTERN hb_bool_t
-hb_ot_layout_table_select_script (hb_face_t *face,
+hb_ot_layout_table_choose_script (hb_face_t *face,
hb_tag_t table_tag,
- unsigned int script_count,
const hb_tag_t *script_tags,
- unsigned int *script_index /* OUT */,
- hb_tag_t *chosen_script /* OUT */);
+ unsigned int *script_index,
+ hb_tag_t *chosen_script);
HB_EXTERN unsigned int
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
@@ -247,36 +134,26 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
hb_tag_t *language_tags /* OUT */);
HB_EXTERN hb_bool_t
-hb_ot_layout_script_select_language (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_index,
- unsigned int language_count,
- const hb_tag_t *language_tags,
- unsigned int *language_index /* OUT */);
-
-HB_EXTERN hb_bool_t
-hb_ot_layout_script_select_language2 (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int script_index,
- unsigned int language_count,
- const hb_tag_t *language_tags,
- unsigned int *language_index /* OUT */,
- hb_tag_t *chosen_language /* OUT */);
+hb_ot_layout_script_find_language (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ hb_tag_t language_tag,
+ unsigned int *language_index);
HB_EXTERN hb_bool_t
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
- unsigned int *feature_index /* OUT */);
+ unsigned int *feature_index);
HB_EXTERN hb_bool_t
hb_ot_layout_language_get_required_feature (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
- unsigned int *feature_index /* OUT */,
- hb_tag_t *feature_tag /* OUT */);
+ unsigned int *feature_index,
+ hb_tag_t *feature_tag);
HB_EXTERN unsigned int
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
@@ -302,7 +179,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
unsigned int script_index,
unsigned int language_index,
hb_tag_t feature_tag,
- unsigned int *feature_index /* OUT */);
+ unsigned int *feature_index);
HB_EXTERN unsigned int
hb_ot_layout_feature_get_lookups (hb_face_t *face,
@@ -316,13 +193,6 @@ HB_EXTERN unsigned int
hb_ot_layout_table_get_lookup_count (hb_face_t *face,
hb_tag_t table_tag);
-HB_EXTERN void
-hb_ot_layout_collect_features (hb_face_t *face,
- hb_tag_t table_tag,
- const hb_tag_t *scripts,
- const hb_tag_t *languages,
- const hb_tag_t *features,
- hb_set_t *feature_indexes /* OUT */);
HB_EXTERN void
hb_ot_layout_collect_lookups (hb_face_t *face,
@@ -336,11 +206,36 @@ HB_EXTERN 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 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 */);
+
+#ifdef HB_NOT_IMPLEMENTED
+typedef struct
+{
+ const hb_codepoint_t *before,
+ unsigned int before_length,
+ const hb_codepoint_t *input,
+ unsigned int input_length,
+ const hb_codepoint_t *after,
+ unsigned int after_length,
+} hb_ot_layout_glyph_sequence_t;
+
+typedef hb_bool_t
+(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t *font,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ void *user_data);
+HB_EXTERN void
+Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_ot_layout_glyph_sequence_func_t callback,
+ void *user_data);
+#endif
/* Variations support */
@@ -368,14 +263,6 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
HB_EXTERN hb_bool_t
hb_ot_layout_has_substitution (hb_face_t *face);
-HB_EXTERN unsigned
-hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
- unsigned lookup_index,
- hb_codepoint_t glyph,
- unsigned start_offset,
- unsigned *alternate_count /* IN/OUT */,
- hb_codepoint_t *alternate_glyphs /* OUT */);
-
HB_EXTERN hb_bool_t
hb_ot_layout_lookup_would_substitute (hb_face_t *face,
unsigned int lookup_index,
@@ -385,14 +272,21 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face,
HB_EXTERN void
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
- unsigned int lookup_index,
- hb_set_t *glyphs
+ unsigned int lookup_index,
+ hb_set_t *glyphs
/*TODO , hb_bool_t inclusive */);
-HB_EXTERN void
-hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
- const hb_set_t *lookups,
- hb_set_t *glyphs);
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+HB_EXTERN hb_bool_t
+Xhb_ot_layout_lookup_substitute (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ unsigned int out_size,
+ hb_codepoint_t *glyphs_out, /* OUT */
+ unsigned int *clusters_out, /* OUT */
+ unsigned int *out_length /* OUT */);
+#endif
/*
@@ -402,110 +296,25 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
HB_EXTERN hb_bool_t
hb_ot_layout_has_positioning (hb_face_t *face);
-/* Optical 'size' feature info. Returns true if found.
- * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
HB_EXTERN 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 */
- hb_ot_name_id_t *subfamily_name_id, /* OUT. May be NULL */
- unsigned int *range_start, /* OUT. May be NULL */
- unsigned int *range_end /* OUT. May be NULL */);
-
-HB_EXTERN hb_position_t
-hb_ot_layout_lookup_get_optical_bound (hb_font_t *font,
- unsigned lookup_index,
- hb_direction_t direction,
- hb_codepoint_t glyph);
-
-
-/*
- * GSUB/GPOS
- */
-
-HB_EXTERN hb_bool_t
-hb_ot_layout_feature_get_name_ids (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int feature_index,
- hb_ot_name_id_t *label_id /* OUT. May be NULL */,
- hb_ot_name_id_t *tooltip_id /* OUT. May be NULL */,
- hb_ot_name_id_t *sample_id /* OUT. May be NULL */,
- unsigned int *num_named_parameters /* OUT. May be NULL */,
- hb_ot_name_id_t *first_param_id /* OUT. May be NULL */);
-
-
-HB_EXTERN unsigned int
-hb_ot_layout_feature_get_characters (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int feature_index,
- unsigned int start_offset,
- unsigned int *char_count /* IN/OUT. May be NULL */,
- hb_codepoint_t *characters /* OUT. May be NULL */);
-
-
-/*
- * BASE
- */
-
-/**
- * hb_ot_layout_baseline_tag_t:
- * @HB_OT_LAYOUT_BASELINE_TAG_ROMAN: The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek.
- * In vertical writing mode, the alphabetic baseline for characters rotated 90 degrees clockwise.
- * (This would not apply to alphabetic characters that remain upright in vertical writing mode, since these
- * characters are not rotated.)
- * @HB_OT_LAYOUT_BASELINE_TAG_HANGING: The hanging baseline. In horizontal direction, this is the horizontal
- * line from which syllables seem, to hang in Tibetan and other similar scripts. In vertical writing mode,
- * for Tibetan (or some other similar script) characters rotated 90 degrees clockwise.
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT: Ideographic character face bottom or left edge,
- * if the direction is horizontal or vertical, respectively.
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT: Ideographic character face top or right edge,
- * if the direction is horizontal or vertical, respectively.
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL: The center of the ideographic character face. Since: 4.0.0
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT: Ideographic em-box bottom or left edge,
- * if the direction is horizontal or vertical, respectively.
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT: Ideographic em-box top or right edge baseline,
- * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL: The center of the ideographic em-box. Since: 4.0.0
- * if the direction is horizontal or vertical, respectively.
- * @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered.
- * In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.
- *
- * Baseline tags from [Baseline Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags) registry.
- *
- * Since: 2.6.0
- */
-typedef enum {
- HB_OT_LAYOUT_BASELINE_TAG_ROMAN = HB_TAG ('r','o','m','n'),
- HB_OT_LAYOUT_BASELINE_TAG_HANGING = HB_TAG ('h','a','n','g'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT = HB_TAG ('i','c','f','b'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT = HB_TAG ('i','c','f','t'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL = HB_TAG ('I','c','f','c'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT = HB_TAG ('i','d','e','o'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT = HB_TAG ('i','d','t','p'),
- HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL = HB_TAG ('I','d','c','e'),
- HB_OT_LAYOUT_BASELINE_TAG_MATH = HB_TAG ('m','a','t','h'),
-
- /*< private >*/
- _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_ot_layout_baseline_tag_t;
-
-HB_EXTERN hb_ot_layout_baseline_tag_t
-hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script);
+Xhb_ot_layout_lookup_position (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ hb_glyph_position_t *positions /* IN / OUT */);
+#endif
+/* Optical 'size' feature info. Returns true if found.
+ * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
HB_EXTERN hb_bool_t
-hb_ot_layout_get_baseline (hb_font_t *font,
- hb_ot_layout_baseline_tag_t baseline_tag,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_position_t *coord /* OUT. May be NULL. */);
+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 */);
-HB_EXTERN void
-hb_ot_layout_get_baseline_with_fallback (hb_font_t *font,
- hb_ot_layout_baseline_tag_t baseline_tag,
- hb_direction_t direction,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_position_t *coord /* OUT */);
HB_END_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
index efc8cae96a4..97b92cc9a8c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
@@ -26,15 +26,12 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_MAP_HH
-#define HB_OT_MAP_HH
+#ifndef HB_OT_MAP_PRIVATE_HH
+#define HB_OT_MAP_PRIVATE_HH
-#include "hb-buffer.hh"
+#include "hb-buffer-private.hh"
-#define HB_OT_MAP_MAX_BITS 8u
-#define HB_OT_MAP_MAX_VALUE ((1u << HB_OT_MAP_MAX_BITS) - 1u)
-
struct hb_ot_shape_plan_t;
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
@@ -55,23 +52,18 @@ struct hb_ot_map_t
unsigned int needs_fallback : 1;
unsigned int auto_zwnj : 1;
unsigned int auto_zwj : 1;
- unsigned int random : 1;
- unsigned int per_syllable : 1;
- int cmp (const hb_tag_t tag_) const
- { return tag_ < tag ? -1 : tag_ > 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;
- unsigned short random : 1;
- unsigned short per_syllable : 1;
hb_mask_t mask;
- hb_tag_t feature_tag;
- HB_INTERNAL static int cmp (const void *pa, const void *pb)
+ 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;
@@ -79,171 +71,140 @@ struct hb_ot_map_t
}
};
- /* Pause functions return true if new glyph indices might have been
- * added to the buffer. This is used to update buffer digest. */
- typedef bool (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
+ typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
struct stage_map_t {
unsigned int last_lookup; /* Cumulative */
pause_func_t pause_func;
};
- void init ()
- {
- hb_memset (this, 0, sizeof (*this));
- features.init0 ();
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- {
- lookups[table_index].init0 ();
- stages[table_index].init0 ();
- }
- }
- void fini ()
- {
- features.fini ();
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- {
- lookups[table_index].fini ();
- stages[table_index].fini ();
- }
- }
+ hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
- hb_mask_t get_global_mask () const { return global_mask; }
+ inline hb_mask_t get_global_mask (void) const { return global_mask; }
- hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = nullptr) const
- {
- const feature_map_t *map = features.bsearch (feature_tag);
+ 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;
}
- bool needs_fallback (hb_tag_t feature_tag) const
- {
- const feature_map_t *map = features.bsearch (feature_tag);
+ inline bool needs_fallback (hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
return map ? map->needs_fallback : false;
}
- hb_mask_t get_1_mask (hb_tag_t feature_tag) const
- {
- const feature_map_t *map = features.bsearch (feature_tag);
+ inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
return map ? map->_1_mask : 0;
}
- unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const
- {
- const feature_map_t *map = features.bsearch (feature_tag);
+ inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
}
- unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const
- {
- const feature_map_t *map = features.bsearch (feature_tag);
- return map ? map->stage[table_index] : UINT_MAX;
+ inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->stage[table_index] : (unsigned int) -1;
}
- hb_array_t<const hb_ot_map_t::lookup_map_t>
- get_stage_lookups (unsigned int table_index, unsigned int stage) const
- {
- if (unlikely (stage > stages[table_index].length))
- return hb_array<const hb_ot_map_t::lookup_map_t> (nullptr, 0);
-
+ 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 = 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].length ? stages[table_index][stage].last_lookup : lookups[table_index].length;
- return lookups[table_index].as_array ().sub_array (start, end - start);
+ unsigned int end = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
+ *plookups = end == start ? nullptr : &lookups[table_index][start];
+ *lookup_count = end - start;
}
HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
template <typename Proxy>
- HB_INTERNAL void apply (const Proxy &proxy,
- const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+ HB_INTERNAL inline void apply (const Proxy &proxy,
+ const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+ inline void finish (void) {
+ features.finish ();
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ {
+ lookups[table_index].finish ();
+ stages[table_index].finish ();
+ }
+ }
+
public:
hb_tag_t chosen_script[2];
bool found_script[2];
private:
- hb_mask_t global_mask = 0;
+ hb_mask_t global_mask;
- hb_sorted_vector_t<feature_map_t> features;
- hb_vector_t<lookup_map_t> lookups[2]; /* GSUB/GPOS */
- hb_vector_t<stage_map_t> stages[2]; /* GSUB/GPOS */
+ hb_prealloced_array_t<feature_map_t, 8> features;
+ hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
+ hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
};
-enum hb_ot_map_feature_flags_t
-{
+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_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */
- F_MANUAL_JOINERS = F_MANUAL_ZWNJ | F_MANUAL_ZWJ,
- F_GLOBAL_MANUAL_JOINERS= F_GLOBAL | F_MANUAL_JOINERS,
- F_GLOBAL_HAS_FALLBACK = F_GLOBAL | F_HAS_FALLBACK,
- F_GLOBAL_SEARCH = 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
- F_RANDOM = 0x0020u, /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
- F_PER_SYLLABLE = 0x0040u /* Contain lookup application to within syllable. */
+ 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. */
+#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
-struct hb_ot_map_feature_t
-{
- hb_tag_t tag;
- hb_ot_map_feature_flags_t flags;
-};
-
-struct hb_ot_shape_plan_key_t;
-
struct hb_ot_map_builder_t
{
public:
HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
- const hb_segment_properties_t &props_);
-
- HB_INTERNAL ~hb_ot_map_builder_t ();
-
- HB_INTERNAL void add_feature (hb_tag_t tag,
- hb_ot_map_feature_flags_t flags=F_NONE,
- unsigned int value=1);
+ const hb_segment_properties_t *props_);
- HB_INTERNAL bool has_feature (hb_tag_t tag);
+ HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags);
- void add_feature (const hb_ot_map_feature_t &feat)
- { add_feature (feat.tag, feat.flags); }
+ inline void add_global_bool_feature (hb_tag_t tag)
+ { add_feature (tag, 1, F_GLOBAL); }
- void enable_feature (hb_tag_t tag,
- hb_ot_map_feature_flags_t flags=F_NONE,
- unsigned int value=1)
- { add_feature (tag, F_GLOBAL | flags, value); }
-
- void disable_feature (hb_tag_t tag)
- { add_feature (tag, F_GLOBAL, 0); }
-
- void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
+ inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (0, pause_func); }
- void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
+ inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (1, pause_func); }
- HB_INTERNAL void compile (hb_ot_map_t &m,
- const hb_ot_shape_plan_key_t &key);
+ HB_INTERNAL void compile (hb_ot_map_t &m,
+ const int *coords,
+ unsigned int num_coords);
+
+ inline void finish (void) {
+ feature_infos.finish ();
+ for (unsigned int table_index = 0; table_index < 2; table_index++)
+ {
+ stages[table_index].finish ();
+ }
+ }
private:
HB_INTERNAL void add_lookups (hb_ot_map_t &m,
+ hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
unsigned int variations_index,
hb_mask_t mask,
bool auto_zwnj = true,
- bool auto_zwj = true,
- bool random = false,
- bool per_syllable = false,
- hb_tag_t feature_tag = HB_TAG(' ',' ',' ',' '));
+ bool auto_zwj = true);
struct feature_info_t {
hb_tag_t tag;
@@ -253,7 +214,7 @@ 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 */
- HB_INTERNAL static int cmp (const void *pa, const void *pb)
+ 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;
@@ -281,10 +242,10 @@ struct hb_ot_map_builder_t
private:
unsigned int current_stage[2]; /* GSUB/GPOS */
- hb_vector_t<feature_info_t> feature_infos;
- hb_vector_t<stage_info_t> stages[2]; /* GSUB/GPOS */
+ hb_prealloced_array_t<feature_info_t, 32> feature_infos;
+ hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
};
-#endif /* HB_OT_MAP_HH */
+#endif /* HB_OT_MAP_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
index 8882dbaccb4..ea9bde9a662 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
@@ -26,82 +26,51 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-ot-map-private.hh"
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-map.hh"
-#include "hb-ot-shape.hh"
-#include "hb-ot-layout.hh"
+#include "hb-ot-layout-private.hh"
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
{
- for (unsigned int i = 0; i < lookups[table_index].length; i++)
- lookups_out->add (lookups[table_index][i].index);
+ for (unsigned int i = 0; i < lookups[table_index].len; i++)
+ hb_set_add (lookups_out, lookups[table_index][i].index);
}
hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
- const hb_segment_properties_t &props_)
+ const hb_segment_properties_t *props_)
{
- hb_memset (this, 0, sizeof (*this));
-
- feature_infos.init ();
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- stages[table_index].init ();
+ memset (this, 0, sizeof (*this));
face = face_;
- props = props_;
+ props = *props_;
+
/* Fetch script/language indices for GSUB/GPOS. We need these later to skip
* features not available in either table and not waste precious bits for them. */
- unsigned int script_count = HB_OT_MAX_TAGS_PER_SCRIPT;
- unsigned int language_count = HB_OT_MAX_TAGS_PER_LANGUAGE;
- hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
- hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+ hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
+ hb_tag_t language_tag;
- hb_ot_tags_from_script_and_language (props.script,
- props.language,
- &script_count,
- script_tags,
- &language_count,
- language_tags);
+ hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
+ language_tag = hb_ot_tag_from_language (props.language);
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- {
+ for (unsigned int table_index = 0; table_index < 2; table_index++) {
hb_tag_t table_tag = table_tags[table_index];
- found_script[table_index] = (bool) hb_ot_layout_table_select_script (face,
- table_tag,
- script_count,
- script_tags,
- &script_index[table_index],
- &chosen_script[table_index]);
- hb_ot_layout_script_select_language (face,
- table_tag,
- script_index[table_index],
- language_count,
- language_tags,
- &language_index[table_index]);
+ found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
+ hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
}
}
-hb_ot_map_builder_t::~hb_ot_map_builder_t ()
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags)
{
- feature_infos.fini ();
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- stages[table_index].fini ();
-}
-
-void hb_ot_map_builder_t::add_feature (hb_tag_t tag,
- hb_ot_map_feature_flags_t flags,
- unsigned int value)
-{
- if (unlikely (!tag)) return;
feature_info_t *info = feature_infos.push();
+ if (unlikely (!info)) return;
+ if (unlikely (!tag)) return;
info->tag = tag;
- info->seq = feature_infos.length;
+ info->seq = feature_infos.len;
info->max_value = value;
info->flags = flags;
info->default_value = (flags & F_GLOBAL) ? value : 0;
@@ -109,32 +78,15 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag,
info->stage[1] = current_stage[1];
}
-bool hb_ot_map_builder_t::has_feature (hb_tag_t tag)
-{
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- {
- if (hb_ot_layout_language_find_feature (face,
- table_tags[table_index],
- script_index[table_index],
- language_index[table_index],
- tag,
- nullptr))
- return true;
- }
- return false;
-}
-
void
hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
+ hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
unsigned int variations_index,
hb_mask_t mask,
bool auto_zwnj,
- bool auto_zwj,
- bool random,
- bool per_syllable,
- hb_tag_t feature_tag)
+ bool auto_zwj)
{
unsigned int lookup_indices[32];
unsigned int offset, len;
@@ -157,13 +109,12 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
if (lookup_indices[i] >= table_lookup_count)
continue;
hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push ();
+ if (unlikely (!lookup))
+ return;
lookup->mask = mask;
lookup->index = lookup_indices[i];
lookup->auto_zwnj = auto_zwnj;
lookup->auto_zwj = auto_zwj;
- lookup->random = random;
- lookup->per_syllable = per_syllable;
- lookup->feature_tag = feature_tag;
}
offset += len;
@@ -174,18 +125,22 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
{
stage_info_t *s = stages[table_index].push ();
- s->index = current_stage[table_index];
- s->pause_func = pause_func;
+ if (likely (s)) {
+ s->index = current_stage[table_index];
+ s->pause_func = pause_func;
+ }
current_stage[table_index]++;
}
void
-hb_ot_map_builder_t::compile (hb_ot_map_t &m,
- const hb_ot_shape_plan_key_t &key)
+hb_ot_map_builder_t::compile (hb_ot_map_t &m,
+ const int *coords,
+ unsigned int num_coords)
{
- unsigned int global_bit_shift = 8 * sizeof (hb_mask_t) - 1;
- unsigned int global_bit_mask = 1u << global_bit_shift;
+ 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;
@@ -210,41 +165,38 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
&required_feature_tag[table_index]);
}
+ if (!feature_infos.len)
+ return;
+
/* Sort features and merge duplicates */
- if (feature_infos.length)
{
feature_infos.qsort ();
- auto *f = feature_infos.arrayZ;
unsigned int j = 0;
- unsigned count = feature_infos.length;
- for (unsigned int i = 1; i < count; i++)
- if (f[i].tag != f[j].tag)
- f[++j] = f[i];
+ for (unsigned int i = 1; i < feature_infos.len; i++)
+ if (feature_infos[i].tag != feature_infos[j].tag)
+ feature_infos[++j] = feature_infos[i];
else {
- if (f[i].flags & F_GLOBAL) {
- f[j].flags |= F_GLOBAL;
- f[j].max_value = f[i].max_value;
- f[j].default_value = f[i].default_value;
+ if (feature_infos[i].flags & F_GLOBAL) {
+ feature_infos[j].flags |= F_GLOBAL;
+ feature_infos[j].max_value = feature_infos[i].max_value;
+ feature_infos[j].default_value = feature_infos[i].default_value;
} else {
- if (f[j].flags & F_GLOBAL)
- f[j].flags ^= F_GLOBAL;
- f[j].max_value = hb_max (f[j].max_value, f[i].max_value);
+ feature_infos[j].flags &= ~F_GLOBAL;
+ feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
/* Inherit default_value from j */
}
- f[j].flags |= (f[i].flags & F_HAS_FALLBACK);
- f[j].stage[0] = hb_min (f[j].stage[0], f[i].stage[0]);
- f[j].stage[1] = hb_min (f[j].stage[1], f[i].stage[1]);
+ feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
+ feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
+ feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
}
feature_infos.shrink (j + 1);
}
/* Allocate bits now */
- static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
- unsigned int next_bit = hb_popcount (HB_GLYPH_FLAG_DEFINED) + 1;
+ unsigned int next_bit = global_bit_shift + 1;
- unsigned count = feature_infos.length;
- for (unsigned int i = 0; i < count; i++)
+ for (unsigned int i = 0; i < feature_infos.len; i++)
{
const feature_info_t *info = &feature_infos[i];
@@ -254,35 +206,35 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
/* Uses the global bit */
bits_needed = 0;
else
- /* Limit bits per feature. */
- bits_needed = hb_min (HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
+ /* Limit to 8 bits per feature. */
+ bits_needed = MIN(8u, _hb_bit_storage (info->max_value));
- if (!info->max_value || next_bit + bits_needed >= global_bit_shift)
+ if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
continue; /* Feature disabled, or not enough bits. */
- bool found = false;
+ hb_bool_t found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
if (required_feature_tag[table_index] == info->tag)
required_feature_stage[table_index] = info->stage[table_index];
- found |= (bool) hb_ot_layout_language_find_feature (face,
- table_tags[table_index],
- script_index[table_index],
- language_index[table_index],
- info->tag,
- &feature_index[table_index]);
+ found |= hb_ot_layout_language_find_feature (face,
+ table_tags[table_index],
+ script_index[table_index],
+ language_index[table_index],
+ info->tag,
+ &feature_index[table_index]);
}
if (!found && (info->flags & F_GLOBAL_SEARCH))
{
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
- found |= (bool) hb_ot_layout_table_find_feature (face,
- table_tags[table_index],
- info->tag,
- &feature_index[table_index]);
+ found |= hb_ot_layout_table_find_feature (face,
+ table_tags[table_index],
+ info->tag,
+ &feature_index[table_index]);
}
}
if (!found && !(info->flags & F_HAS_FALLBACK))
@@ -290,6 +242,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
hb_ot_map_t::feature_map_t *map = m.features.push ();
+ if (unlikely (!map))
+ break;
map->tag = info->tag;
map->index[0] = feature_index[0];
@@ -298,8 +252,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
map->stage[1] = info->stage[1];
map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
- map->random = !!(info->flags & F_RANDOM);
- map->per_syllable = !!(info->flags & F_PER_SYLLABLE);
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */
map->shift = global_bit_shift;
@@ -312,8 +264,9 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
}
map->_1_mask = (1u << map->shift) & map->mask;
map->needs_fallback = !found;
+
}
- //feature_infos.shrink (0); /* Done with these */
+ feature_infos.shrink (0); /* Done with these */
add_gsub_pause (nullptr);
@@ -322,7 +275,13 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
/* Collect lookup indices for features */
- auto &lookups = m.lookups[table_index];
+
+ unsigned int variations_index;
+ hb_ot_layout_table_find_feature_variations (face,
+ table_tags[table_index],
+ coords,
+ num_coords,
+ &variations_index);
unsigned int stage_index = 0;
unsigned int last_num_lookups = 0;
@@ -330,55 +289,49 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
{
if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
required_feature_stage[table_index] == stage)
- add_lookups (m, table_index,
+ add_lookups (m, face, table_index,
required_feature_index[table_index],
- key.variations_index[table_index],
+ variations_index,
global_bit_mask);
- for (auto &feature : m.features)
- {
- if (feature.stage[table_index] == stage)
- add_lookups (m, table_index,
- feature.index[table_index],
- key.variations_index[table_index],
- feature.mask,
- feature.auto_zwnj,
- feature.auto_zwj,
- feature.random,
- feature.per_syllable,
- feature.tag);
- }
+ for (unsigned i = 0; i < m.features.len; i++)
+ if (m.features[i].stage[table_index] == stage)
+ add_lookups (m, face, table_index,
+ 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 */
- if (last_num_lookups < lookups.length)
+ if (last_num_lookups < m.lookups[table_index].len)
{
- lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort ();
+ m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].len);
unsigned int j = last_num_lookups;
- for (unsigned int i = j + 1; i < lookups.length; i++)
- if (lookups.arrayZ[i].index != lookups.arrayZ[j].index)
- lookups.arrayZ[++j] = lookups.arrayZ[i];
+ for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
+ if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
+ m.lookups[table_index][++j] = m.lookups[table_index][i];
else
{
- lookups.arrayZ[j].mask |= lookups.arrayZ[i].mask;
- lookups.arrayZ[j].auto_zwnj &= lookups.arrayZ[i].auto_zwnj;
- lookups.arrayZ[j].auto_zwj &= lookups.arrayZ[i].auto_zwj;
+ 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;
}
- lookups.shrink (j + 1);
+ m.lookups[table_index].shrink (j + 1);
}
- last_num_lookups = lookups.length;
+ last_num_lookups = m.lookups[table_index].len;
- if (stage_index < stages[table_index].length && stages[table_index][stage_index].index == stage) {
+ if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
- stage_map->last_lookup = last_num_lookups;
- stage_map->pause_func = stages[table_index][stage_index].pause_func;
+ if (likely (stage_map)) {
+ stage_map->last_lookup = last_num_lookups;
+ stage_map->pause_func = stages[table_index][stage_index].pause_func;
+ }
stage_index++;
}
}
}
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh
index dccf720f46b..7dc3283a289 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh
@@ -27,8 +27,8 @@
#ifndef HB_OT_MATH_TABLE_HH
#define HB_OT_MATH_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-common-private.hh"
#include "hb-ot-math.h"
namespace OT {
@@ -36,31 +36,21 @@ namespace OT {
struct MathValueRecord
{
- hb_position_t get_x_value (hb_font_t *font, const void *base) const
+ 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); }
- hb_position_t get_y_value (hb_font_t *font, const void *base) const
+ 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); }
- MathValueRecord* copy (hb_serialize_context_t *c, const void *base) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
- out->deviceTable.serialize_copy (c, deviceTable, base, 0, hb_serialize_context_t::Head);
-
- return_trace (out);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ 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:
- HBINT16 value; /* The X or Y value in design units */
- Offset16To<Device> deviceTable; /* Offset to the device table - from the
- * beginning of parent table. May be NULL.
+ 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:
@@ -69,30 +59,7 @@ struct MathValueRecord
struct MathConstants
{
- MathConstants* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
- if (unlikely (!p)) return_trace (nullptr);
- hb_memcpy (p, percentScaleDown, HBINT16::static_size * 2);
-
- HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
- if (unlikely (!m)) return_trace (nullptr);
- hb_memcpy (m, minHeight, HBUINT16::static_size * 2);
-
- unsigned count = ARRAY_LENGTH (mathValueRecords);
- for (unsigned i = 0; i < count; i++)
- if (!c->copy (mathValueRecords[i], this))
- return_trace (nullptr);
-
- if (!c->embed (radicalDegreeBottomRaisePercent)) return_trace (nullptr);
- return_trace (out);
- }
-
- bool sanitize_math_value_records (hb_sanitize_context_t *c) const
+ inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -104,14 +71,14 @@ struct MathConstants
return_trace (true);
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && sanitize_math_value_records (c));
+ return_trace (c->check_struct (this) && sanitize_math_value_records(c));
}
- hb_position_t get_value (hb_ot_math_constant_t constant,
- hb_font_t *font) const
+ inline hb_position_t get_value (hb_ot_math_constant_t constant,
+ hb_font_t *font) const
{
switch (constant) {
@@ -127,7 +94,7 @@ struct MathConstants
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);
+ 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:
@@ -176,7 +143,7 @@ struct MathConstants
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);
+ 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;
@@ -187,10 +154,10 @@ struct MathConstants
}
protected:
- HBINT16 percentScaleDown[2];
- HBUINT16 minHeight[2];
+ INT16 percentScaleDown[2];
+ UINT16 minHeight[2];
MathValueRecord mathValueRecords[51];
- HBINT16 radicalDegreeBottomRaisePercent;
+ INT16 radicalDegreeBottomRaisePercent;
public:
DEFINE_SIZE_STATIC (214);
@@ -198,29 +165,7 @@ struct MathConstants
struct MathItalicsCorrectionInfo
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = c->plan->_glyphset_mathed;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+coverage, italicsCorrection)
- | hb_filter (glyphset, hb_first)
- | hb_filter (serialize_math_record_array (c->serializer, out->italicsCorrection, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -228,19 +173,19 @@ struct MathItalicsCorrectionInfo
italicsCorrection.sanitize (c, this));
}
- hb_position_t get_value (hb_codepoint_t glyph,
- hb_font_t *font) const
+ 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:
- Offset16To<Coverage> coverage; /* Offset to Coverage table -
+ OffsetTo<Coverage> coverage; /* Offset to Coverage table -
* from the beginning of
* MathItalicsCorrectionInfo
* table. */
- Array16Of<MathValueRecord> italicsCorrection; /* Array of MathValueRecords
+ ArrayOf<MathValueRecord> italicsCorrection; /* Array of MathValueRecords
* defining italics correction
* values for each
* covered glyph. */
@@ -251,29 +196,7 @@ struct MathItalicsCorrectionInfo
struct MathTopAccentAttachment
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = c->plan->_glyphset_mathed;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+topAccentCoverage, topAccentAttachment)
- | hb_filter (glyphset, hb_first)
- | hb_filter (serialize_math_record_array (c->serializer, out->topAccentAttachment, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->topAccentCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -281,21 +204,21 @@ struct MathTopAccentAttachment
topAccentAttachment.sanitize (c, this));
}
- hb_position_t get_value (hb_codepoint_t glyph,
- hb_font_t *font) const
+ 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);
+ return topAccentAttachment[index].get_x_value(font, this);
}
protected:
- Offset16To<Coverage> topAccentCoverage; /* Offset to Coverage table -
+ OffsetTo<Coverage> topAccentCoverage; /* Offset to Coverage table -
* from the beginning of
* MathTopAccentAttachment
* table. */
- Array16Of<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
+ ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
* defining top accent
* attachment points for each
* covered glyph. */
@@ -306,43 +229,29 @@ struct MathTopAccentAttachment
struct MathKern
{
- MathKern* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
-
- unsigned count = 2 * heightCount + 1;
- for (unsigned i = 0; i < count; i++)
- if (!c->copy (mathValueRecordsZ.arrayZ[i], this))
- return_trace (nullptr);
-
- return_trace (out);
- }
-
- bool sanitize_math_value_records (hb_sanitize_context_t *c) const
+ 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 (!mathValueRecordsZ.arrayZ[i].sanitize (c, this)) return_trace (false);
+ if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
return_trace (true);
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) &&
+ c->check_array (mathValueRecords,
+ mathValueRecords[0].static_size,
+ 2 * heightCount + 1) &&
sanitize_math_value_records (c));
}
- hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
+ inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
{
- const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
- const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
+ 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
@@ -358,7 +267,7 @@ struct MathKern
while (count > 0)
{
unsigned int half = count / 2;
- hb_position_t height = correctionHeight[i + half].get_y_value (font, this);
+ hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
if (sign * height < sign * correction_height)
{
i += half + 1;
@@ -366,73 +275,27 @@ struct MathKern
} else
count = half;
}
- return kernValue[i].get_x_value (font, this);
- }
-
- unsigned int get_entries (unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries, /* OUT */
- hb_font_t *font) const
- {
- const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
- const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
- const unsigned int entriesCount = heightCount + 1;
-
- if (entries_count)
- {
- unsigned int start = hb_min (start_offset, entriesCount);
- unsigned int end = hb_min (start + *entries_count, entriesCount);
- *entries_count = end - start;
-
- for (unsigned int i = 0; i < *entries_count; i++) {
- unsigned int j = start + i;
-
- hb_position_t max_height;
- if (j == heightCount) {
- max_height = INT32_MAX;
- } else {
- max_height = correctionHeight[j].get_y_value (font, this);
- }
-
- kern_entries[i] = {max_height, kernValue[j].get_x_value (font, this)};
- }
- }
- return entriesCount;
+ return kernValue[i].get_x_value(font, this);
}
protected:
- HBUINT16 heightCount;
- UnsizedArrayOf<MathValueRecord>
- mathValueRecordsZ;
- /* 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).
- */
+ 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, mathValueRecordsZ);
+ DEFINE_SIZE_ARRAY (2, mathValueRecords);
};
struct MathKernInfoRecord
{
- MathKernInfoRecord* copy (hb_serialize_context_t *c, const void *base) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- unsigned count = ARRAY_LENGTH (mathKern);
- for (unsigned i = 0; i < count; i++)
- out->mathKern[i].serialize_copy (c, mathKern[i], base, 0, hb_serialize_context_t::Head);
-
- return_trace (out);
- }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -444,38 +307,20 @@ struct MathKernInfoRecord
return_trace (true);
}
- hb_position_t get_kerning (hb_ot_math_kern_t kern,
- hb_position_t correction_height,
- hb_font_t *font,
- const void *base) const
+ 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);
}
- unsigned int get_kernings (hb_ot_math_kern_t kern,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries, /* OUT */
- hb_font_t *font,
- const void *base) const
- {
- unsigned int idx = kern;
- if (unlikely (idx >= ARRAY_LENGTH (mathKern)) || !mathKern[idx]) {
- if (entries_count) *entries_count = 0;
- return 0;
- }
- return (base+mathKern[idx]).get_entries (start_offset,
- entries_count,
- kern_entries,
- font);
- }
-
protected:
/* Offset to MathKern table for each corner -
- * from the beginning of MathKernInfo table. May be NULL. */
- Offset16To<MathKern> mathKern[4];
+ * from the beginning of MathKernInfo table. May be nullptr. */
+ OffsetTo<MathKern> mathKern[4];
public:
DEFINE_SIZE_STATIC (8);
@@ -483,29 +328,7 @@ struct MathKernInfoRecord
struct MathKernInfo
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = c->plan->_glyphset_mathed;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_coverage;
- + hb_zip (this+mathKernCoverage, mathKernInfoRecords)
- | hb_filter (glyphset, hb_first)
- | hb_filter (serialize_math_record_array (c->serializer, out->mathKernInfoRecords, this), hb_second)
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- out->mathKernCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
@@ -513,44 +336,25 @@ struct MathKernInfo
mathKernInfoRecords.sanitize (c, this));
}
- 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
+ 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);
}
- unsigned int get_kernings (hb_codepoint_t glyph,
- hb_ot_math_kern_t kern,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries, /* OUT */
- hb_font_t *font) const
- {
- unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
- return mathKernInfoRecords[index].get_kernings (kern,
- start_offset,
- entries_count,
- kern_entries,
- font,
- this);
- }
-
protected:
- Offset16To<Coverage>
- mathKernCoverage;
- /* Offset to Coverage table -
- * from the beginning of the
- * MathKernInfo table. */
- Array16Of<MathKernInfoRecord>
- mathKernInfoRecords;
- /* Array of MathKernInfoRecords,
- * per-glyph information for
- * mathematical positioning
- * of subscripts and
- * superscripts. */
+ 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);
@@ -558,90 +362,52 @@ struct MathKernInfo
struct MathGlyphInfo
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this);
- out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this);
-
- const hb_set_t &glyphset = c->plan->_glyphset_mathed;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto it =
- + hb_iter (this+extendedShapeCoverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting (glyph_map)
- ;
-
- if (it) out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
- else out->extendedShapeCoverage = 0;
-
- out->mathKernInfo.serialize_subset (c, mathKernInfo, this);
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ 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));
+ mathKernInfo.sanitize(c, this));
}
- hb_position_t
+ inline hb_position_t
get_italics_correction (hb_codepoint_t glyph, hb_font_t *font) const
{ return (this+mathItalicsCorrectionInfo).get_value (glyph, font); }
- hb_position_t
+ inline hb_position_t
get_top_accent_attachment (hb_codepoint_t glyph, hb_font_t *font) const
{ return (this+mathTopAccentAttachment).get_value (glyph, font); }
- bool is_extended_shape (hb_codepoint_t glyph) const
+ inline bool is_extended_shape (hb_codepoint_t glyph) const
{ return (this+extendedShapeCoverage).get_coverage (glyph) != NOT_COVERED; }
- 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
+ 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); }
- hb_position_t get_kernings (hb_codepoint_t glyph,
- hb_ot_math_kern_t kern,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries, /* OUT */
- hb_font_t *font) const
- { return (this+mathKernInfo).get_kernings (glyph,
- kern,
- start_offset,
- entries_count,
- kern_entries,
- font); }
-
protected:
/* Offset to MathItalicsCorrectionInfo table -
* from the beginning of MathGlyphInfo table. */
- Offset16To<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
+ OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
/* Offset to MathTopAccentAttachment table -
* from the beginning of MathGlyphInfo table. */
- Offset16To<MathTopAccentAttachment> mathTopAccentAttachment;
+ 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 NULL.. */
- Offset16To<Coverage> extendedShapeCoverage;
+ * vertical positioning purposes. May be nullptr.. */
+ OffsetTo<Coverage> extendedShapeCoverage;
/* Offset to MathKernInfo table -
* from the beginning of MathGlyphInfo table. */
- Offset16To<MathKernInfo> mathKernInfo;
+ OffsetTo<MathKernInfo> mathKernInfo;
public:
DEFINE_SIZE_STATIC (8);
@@ -651,36 +417,23 @@ struct MathGlyphVariantRecord
{
friend struct MathGlyphConstruction;
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- const hb_map_t& glyph_map = *c->plan->glyph_map;
- return_trace (c->serializer->check_assign (out->variantGlyph, glyph_map.get (variantGlyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
- void closure_glyphs (hb_set_t *variant_glyphs) const
- { variant_glyphs->add (variantGlyph); }
-
protected:
- HBGlyphID16 variantGlyph; /* Glyph ID for the variant. */
- HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
- * variant, in the direction of requested
- * glyph extension. */
+ 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 : HBUINT16
+struct PartFlags : UINT16
{
enum Flags {
Extender = 0x0001u, /* If set, the part can be skipped or repeated. */
@@ -694,33 +447,23 @@ struct PartFlags : HBUINT16
struct MathGlyphPartRecord
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- const hb_map_t& glyph_map = *c->plan->glyph_map;
- return_trace (c->serializer->check_assign (out->glyph, glyph_map.get (glyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
- void extract (hb_ot_math_glyph_part_t &out,
- int64_t mult,
- hb_font_t *font) const
+ 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_mult (startConnectorLength, mult);
- out.end_connector_length = font->em_mult (endConnectorLength, mult);
- out.full_advance = font->em_mult (fullAdvance, mult);
+ 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_OT_MATH_GLYPH_PART_FLAG_EXTENDER ==
+ static_assert ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER ==
(unsigned int) PartFlags::Extender, "");
out.flags = (hb_ot_math_glyph_part_flags_t)
@@ -728,25 +471,20 @@ struct MathGlyphPartRecord
(partFlags & PartFlags::Defined);
}
- void closure_glyphs (hb_set_t *variant_glyphs) const
- { variant_glyphs->add (glyph); }
-
protected:
- HBGlyphID16 glyph; /* Glyph ID for the part. */
- HBUINT16 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. */
- HBUINT16 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. */
- HBUINT16 fullAdvance; /* Full advance width/height for this part,
- * in the direction of the extension.
- * In design units. */
- PartFlags partFlags; /* Part qualifiers. */
+ 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);
@@ -754,41 +492,29 @@ struct MathGlyphPartRecord
struct MathGlyphAssembly
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
- if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false);
-
- for (const auto& record : partRecords.iter ())
- if (!record.subset (c)) return_trace (false);
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ 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));
+ italicsCorrection.sanitize(c, this) &&
+ partRecords.sanitize(c));
}
- 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
+ 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)
{
- int64_t mult = font->dir_mult (direction);
- for (auto _ : hb_zip (partRecords.as_array ().sub_array (start_offset, parts_count),
- hb_array (parts, *parts_count)))
- _.first.extract (_.second, mult, font);
+ 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)
@@ -797,22 +523,13 @@ struct MathGlyphAssembly
return partRecords.len;
}
- void closure_glyphs (hb_set_t *variant_glyphs) const
- {
- for (const auto& _ : partRecords.iter ())
- _.closure_glyphs (variant_glyphs);
- }
-
protected:
- MathValueRecord
- italicsCorrection;
- /* Italics correction of this
- * MathGlyphAssembly. Should not
- * depend on the assembly size. */
- Array16Of<MathGlyphPartRecord>
- partRecords; /* Array of part records, from
- * left to right and bottom to
- * top. */
+ 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);
@@ -820,63 +537,45 @@ struct MathGlyphAssembly
struct MathGlyphConstruction
{
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- out->glyphAssembly.serialize_subset (c, glyphAssembly, this);
-
- if (!c->serializer->check_assign (out->mathGlyphVariantRecord.len, mathGlyphVariantRecord.len, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- for (const auto& record : mathGlyphVariantRecord.iter ())
- if (!record.subset (c)) return_trace (false);
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ 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));
+ glyphAssembly.sanitize(c, this) &&
+ mathGlyphVariantRecord.sanitize(c));
}
- const MathGlyphAssembly &get_assembly () const { return this+glyphAssembly; }
+ inline const MathGlyphAssembly &get_assembly (void) const
+ { return this+glyphAssembly; }
- 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
+ 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)
{
- int64_t mult = font->dir_mult (direction);
- for (auto _ : hb_zip (mathGlyphVariantRecord.as_array ().sub_array (start_offset, variants_count),
- hb_array (variants, *variants_count)))
- _.second = {_.first.variantGlyph, font->em_mult (_.first.advanceMeasurement, mult)};
+ 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;
}
- void closure_glyphs (hb_set_t *variant_glyphs) const
- {
- (this+glyphAssembly).closure_glyphs (variant_glyphs);
-
- for (const auto& _ : mathGlyphVariantRecord.iter ())
- _.closure_glyphs (variant_glyphs);
- }
-
protected:
/* Offset to MathGlyphAssembly table for this shape - from the beginning of
- MathGlyphConstruction table. May be NULL. */
- Offset16To<MathGlyphAssembly> glyphAssembly;
+ MathGlyphConstruction table. May be nullptr. */
+ OffsetTo<MathGlyphAssembly> glyphAssembly;
/* MathGlyphVariantRecords for alternative variants of the glyphs. */
- Array16Of<MathGlyphVariantRecord> mathGlyphVariantRecord;
+ ArrayOf<MathGlyphVariantRecord> mathGlyphVariantRecord;
public:
DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord);
@@ -884,133 +583,47 @@ struct MathGlyphConstruction
struct MathVariants
{
- void closure_glyphs (const hb_set_t *glyph_set,
- hb_set_t *variant_glyphs) const
- {
- const hb_array_t<const Offset16To<MathGlyphConstruction>> glyph_construction_offsets = glyphConstruction.as_array (vertGlyphCount + horizGlyphCount);
-
- if (vertGlyphCoverage)
- {
- const auto vert_offsets = glyph_construction_offsets.sub_array (0, vertGlyphCount);
- + hb_zip (this+vertGlyphCoverage, vert_offsets)
- | hb_filter (glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
- ;
- }
-
- if (horizGlyphCoverage)
- {
- const auto hori_offsets = glyph_construction_offsets.sub_array (vertGlyphCount, horizGlyphCount);
- + hb_zip (this+horizGlyphCoverage, hori_offsets)
- | hb_filter (glyph_set, hb_first)
- | hb_map (hb_second)
- | hb_map (hb_add (this))
- | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
- ;
- }
- }
-
- void collect_coverage_and_indices (hb_sorted_vector_t<hb_codepoint_t>& new_coverage,
- const Offset16To<Coverage>& coverage,
- unsigned i,
- unsigned end_index,
- hb_set_t& indices,
- const hb_set_t& glyphset,
- const hb_map_t& glyph_map) const
- {
- if (!coverage) return;
-
- for (const auto _ : (this+coverage).iter ())
- {
- if (i >= end_index) return;
- if (glyphset.has (_))
- {
- unsigned new_gid = glyph_map.get (_);
- new_coverage.push (new_gid);
- indices.add (i);
- }
- i++;
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = c->plan->_glyphset_mathed;
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage;
- hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage;
- hb_set_t indices;
- collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, vertGlyphCount, indices, glyphset, glyph_map);
- collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, vertGlyphCount + horizGlyphCount, indices, glyphset, glyph_map);
-
- if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- for (unsigned i : indices.iter ())
- {
- auto *o = c->serializer->embed (glyphConstruction[i]);
- if (!o) return_trace (false);
- o->serialize_subset (c, glyphConstruction[i], this);
- }
-
- if (new_vert_coverage)
- out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
-
- if (new_hori_coverage)
- out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ());
- return_trace (true);
- }
-
- bool sanitize_offsets (hb_sanitize_context_t *c) const
+ 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.arrayZ[i].sanitize (c, this)) return_trace (false);
+ if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
return_trace (true);
}
- bool sanitize (hb_sanitize_context_t *c) const
+ 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.arrayZ, vertGlyphCount + horizGlyphCount) &&
+ c->check_array (glyphConstruction,
+ glyphConstruction[0].static_size,
+ vertGlyphCount + horizGlyphCount) &&
sanitize_offsets (c));
}
- hb_position_t get_min_connector_overlap (hb_direction_t direction,
+ inline hb_position_t get_min_connector_overlap (hb_direction_t direction,
hb_font_t *font) const
{ return font->em_scale_dir (minConnectorOverlap, direction); }
- 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
+ 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); }
- 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
+ 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,
@@ -1018,18 +631,18 @@ struct MathVariants
italics_correction); }
private:
- const MathGlyphConstruction &
- get_glyph_construction (hb_codepoint_t glyph,
- hb_direction_t direction,
- hb_font_t *font HB_UNUSED) const
+ 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 Offset16To<Coverage> &coverage = vertical ? vertGlyphCoverage
+ const OffsetTo<Coverage> &coverage = vertical ? vertGlyphCoverage
: horizGlyphCoverage;
unsigned int index = (this+coverage).get_coverage (glyph);
- if (unlikely (index >= count)) return Null (MathGlyphConstruction);
+ if (unlikely (index >= count)) return Null(MathGlyphConstruction);
if (!vertical)
index += vertGlyphCount;
@@ -1038,30 +651,26 @@ struct MathVariants
}
protected:
- HBUINT16 minConnectorOverlap;
- /* Minimum overlap of connecting
- * glyphs during glyph construction,
- * in design units. */
- Offset16To<Coverage> vertGlyphCoverage;
- /* Offset to Coverage table -
- * from the beginning of MathVariants
- * table. */
- Offset16To<Coverage> horizGlyphCoverage;
- /* Offset to Coverage table -
- * from the beginning of MathVariants
- * table. */
- HBUINT16 vertGlyphCount; /* Number of glyphs for which
- * information is provided for
- * vertically growing variants. */
- HBUINT16 horizGlyphCount;/* Number of glyphs for which
- * information is provided for
- * horizontally growing variants. */
+ 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. */
- UnsizedArrayOf<Offset16To<MathGlyphConstruction>>
- glyphConstruction;
+ OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
public:
DEFINE_SIZE_ARRAY (10, glyphConstruction);
@@ -1069,39 +678,14 @@ struct MathVariants
/*
- * MATH -- Mathematical typesetting
- * https://docs.microsoft.com/en-us/typography/opentype/spec/math
+ * MATH -- The MATH Table
*/
struct MATH
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_MATH;
-
- bool has_data () const { return version.to_int (); }
-
- void closure_glyphs (hb_set_t *glyph_set) const
- {
- if (mathVariants)
- {
- hb_set_t variant_glyphs;
- (this+mathVariants).closure_glyphs (glyph_set, &variant_glyphs);
- hb_set_union (glyph_set, &variant_glyphs);
- }
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->embed (*this);
- if (unlikely (!out)) return_trace (false);
-
- out->mathConstants.serialize_copy (c->serializer, mathConstants, this, 0, hb_serialize_context_t::Head);
- out->mathGlyphInfo.serialize_subset (c, mathGlyphInfo, this);
- out->mathVariants.serialize_subset (c, mathVariants, this);
- return_trace (true);
- }
+ static const hb_tag_t tableTag = HB_OT_TAG_MATH;
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
@@ -1111,23 +695,22 @@ struct MATH
mathVariants.sanitize (c, this));
}
- hb_position_t get_constant (hb_ot_math_constant_t constant,
- hb_font_t *font) const
+ inline hb_position_t get_constant (hb_ot_math_constant_t constant,
+ hb_font_t *font) const
{ return (this+mathConstants).get_value (constant, font); }
- const MathGlyphInfo &get_glyph_info () const { return this+mathGlyphInfo; }
+ inline const MathGlyphInfo &get_math_glyph_info (void) const
+ { return this+mathGlyphInfo; }
- const MathVariants &get_variants () const { return this+mathVariants; }
+ inline const MathVariants &get_math_variants (void) const
+ { return this+mathVariants; }
protected:
- FixedVersion<>version; /* Version of the MATH table
- * initially set to 0x00010000u */
- Offset16To<MathConstants>
- mathConstants; /* MathConstants table */
- Offset16To<MathGlyphInfo>
- mathGlyphInfo; /* MathGlyphInfo table */
- Offset16To<MathVariants>
- mathVariants; /* MathVariants table */
+ 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);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
index c515867bdf1..f82a07353c9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
@@ -24,27 +24,18 @@
* Igalia Author(s): Frédéric Wang
*/
-#include "hb.hh"
-
-#ifndef HB_NO_MATH
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-private.hh"
#include "hb-ot-math-table.hh"
-
-/**
- * SECTION:hb-ot-math
- * @title: hb-ot-math
- * @short_description: OpenType Math information
- * @include: hb-ot.h
- *
- * Functions for fetching mathematics layout data from OpenType fonts.
- *
- * HarfBuzz itself does not implement a math layout solution. The
- * functions and types provided can be used by client programs to access
- * the font data necessary for typesetting OpenType Math layout.
- *
- **/
-
+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);
+ return *(layout->math.get ());
+}
/*
* OT::MATH
@@ -54,32 +45,31 @@
* hb_ot_math_has_data:
* @face: #hb_face_t to test
*
- * Tests whether a face has a `MATH` table.
+ * This function allows to verify the presence of an OpenType MATH table on the
+ * face.
*
- * Return value: `true` if the table is found, `false` otherwise
+ * Return value: true if face has a MATH table, false otherwise
*
* Since: 1.3.3
**/
hb_bool_t
hb_ot_math_has_data (hb_face_t *face)
{
- return face->table.MATH->has_data ();
+ return &_get_math (face) != &OT::Null(OT::MATH);
}
/**
* hb_ot_math_get_constant:
- * @font: #hb_font_t to work upon
+ * @font: #hb_font_t from which to retrieve the value
* @constant: #hb_ot_math_constant_t the constant to retrieve
*
- * Fetches the specified math constant. For most constants, the value returned
- * is an #hb_position_t.
- *
- * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
- * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
- * an integer between 0 and 100 representing that percentage.
+ * This function returns the requested math constants as a #hb_position_t.
+ * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
+ * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
+ * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
+ * actually an integer between 0 and 100 representing that percentage.
*
- * Return value: the requested constant or zero
+ * Return value: the requested constant or 0
*
* Since: 1.3.3
**/
@@ -87,18 +77,16 @@ hb_position_t
hb_ot_math_get_constant (hb_font_t *font,
hb_ot_math_constant_t constant)
{
- return font->face->table.MATH->get_constant(constant, font);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_constant(constant, font);
}
/**
* hb_ot_math_get_glyph_italics_correction:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph index from which to retrieve the value
+ * @font: #hb_font_t from which to retrieve the value
+ * @glyph: glyph index from which to retrieve the value
*
- * Fetches an italics-correction value (if one exists) for the specified
- * glyph index.
- *
- * Return value: the italics correction of the glyph or zero
+ * Return value: the italics correction of the glyph or 0
*
* Since: 1.3.3
**/
@@ -106,25 +94,16 @@ hb_position_t
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
hb_codepoint_t glyph)
{
- return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_glyph_info().get_italics_correction (glyph, font);
}
/**
* hb_ot_math_get_glyph_top_accent_attachment:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph index from which to retrieve the value
- *
- * Fetches a top-accent-attachment value (if one exists) for the specified
- * glyph index.
+ * @font: #hb_font_t from which to retrieve the value
+ * @glyph: glyph index from which to retrieve the value
*
- * For any glyph that does not have a top-accent-attachment value - that is,
- * a glyph not covered by the `MathTopAccentAttachment` table (or, when
- * @font has no `MathTopAccentAttachment` table or no `MATH` table, any
- * glyph) - the function synthesizes a value, returning the position at
- * one-half the glyph's advance width.
- *
- * Return value: the top accent attachment of the glyph or 0.5 * the advance
- * width of @glyph
+ * Return value: the top accent attachment of the glyph or 0
*
* Since: 1.3.3
**/
@@ -132,17 +111,16 @@ hb_position_t
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
hb_codepoint_t glyph)
{
- return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_glyph_info().get_top_accent_attachment (glyph, font);
}
/**
* hb_ot_math_is_glyph_extended_shape:
- * @face: #hb_face_t to work upon
- * @glyph: The glyph index to test
- *
- * Tests whether the given glyph index is an extended shape in the face.
+ * @face: a #hb_face_t to test
+ * @glyph: a glyph index to test
*
- * Return value: `true` if the glyph is an extended shape, `false` otherwise
+ * Return value: true if the glyph is an extended shape, false otherwise
*
* Since: 1.3.3
**/
@@ -150,25 +128,24 @@ hb_bool_t
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
hb_codepoint_t glyph)
{
- return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
+ const OT::MATH &math = _get_math (face);
+ return math.get_math_glyph_info().is_extended_shape (glyph);
}
/**
* hb_ot_math_get_glyph_kerning:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph index from which to retrieve the value
- * @kern: The #hb_ot_math_kern_t from which to retrieve the value
+ * @font: #hb_font_t from which to retrieve the value
+ * @glyph: glyph index from which to retrieve the value
+ * @kern: the #hb_ot_math_kern_t from which to retrieve the value
* @correction_height: the correction height to use to determine the kerning.
*
- * Fetches the math kerning (cut-ins) value for the specified font, glyph index, and
- * @kern.
+ * This function tries to retrieve the MathKern table for the specified font,
+ * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
+ * MathKern table to find one value that is greater or equal to specified
+ * correction_height. If one is found the corresponding value from the list of
+ * kerns is returned and otherwise the last kern value is returned.
*
- * If the MathKern table is found, the function examines it to find a height
- * value that is greater or equal to @correction_height. If such a height
- * value is found, corresponding kerning value from the table is returned. If
- * no such height value is found, the last kerning value is returned.
- *
- * Return value: requested kerning value or zero
+ * Return value: requested kerning or 0
*
* Since: 1.3.3
**/
@@ -178,77 +155,26 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
hb_ot_math_kern_t kern,
hb_position_t correction_height)
{
- return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
- kern,
- correction_height,
- font);
-}
-
-/**
- * hb_ot_math_get_glyph_kernings:
- * @font: #hb_font_t to work upon
- * @glyph: The glyph index from which to retrieve the kernings
- * @kern: The #hb_ot_math_kern_t from which to retrieve the kernings
- * @start_offset: offset of the first kern entry to retrieve
- * @entries_count: (inout) (optional): Input = the maximum number of kern entries to return;
- * Output = the actual number of kern entries returned
- * @kern_entries: (out caller-allocates) (array length=entries_count): array of kern entries returned
- *
- * Fetches the raw MathKern (cut-in) data for the specified font, glyph index,
- * and @kern. The corresponding list of kern values and correction heights is
- * returned as a list of #hb_ot_math_kern_entry_t structs.
- *
- * See also #hb_ot_math_get_glyph_kerning, which handles selecting the
- * appropriate kern value for a given correction height.
- *
- * <note>For a glyph with @n defined kern values (where @n > 0), there are only
- * @n−1 defined correction heights, as each correction height defines a boundary
- * past which the next kern value should be selected. Therefore, only the
- * #hb_ot_math_kern_entry_t.kern_value of the uppermost #hb_ot_math_kern_entry_t
- * actually comes from the font; its corresponding
- * #hb_ot_math_kern_entry_t.max_correction_height is always set to
- * <code>INT32_MAX</code>.</note>
- *
- * Return value: the total number of kern values available or zero
- *
- * Since: 3.4.0
- **/
-unsigned int
-hb_ot_math_get_glyph_kernings (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_ot_math_kern_t kern,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries /* OUT */)
-{
- return font->face->table.MATH->get_glyph_info().get_kernings (glyph,
- kern,
- start_offset,
- entries_count,
- kern_entries,
- font);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height, font);
}
/**
* hb_ot_math_get_glyph_variants:
- * @font: #hb_font_t to work upon
- * @glyph: The index of the glyph to stretch
- * @direction: The direction of the stretching (horizontal or vertical)
+ * @font: #hb_font_t from which to retrieve the values
+ * @glyph: index of the glyph to stretch
+ * @direction: direction of the stretching
* @start_offset: offset of the first variant to retrieve
- * @variants_count: (inout): Input = the maximum number of variants to return;
- * Output = the actual number of variants returned
- * @variants: (out) (array length=variants_count): array of variants returned
- *
- * Fetches the MathGlyphConstruction for the specified font, glyph index, and
- * direction. The corresponding list of size variants is returned as a list of
- * #hb_ot_math_glyph_variant_t structs.
+ * @variants_count: maximum number of variants to retrieve after start_offset
+ * (IN) and actual number of variants retrieved (OUT)
+ * @variants: array of size at least @variants_count to store the result
*
- * <note>The @direction parameter is only used to select between horizontal
- * or vertical directions for the construction. Even though all #hb_direction_t
- * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
- * considered.</note>
+ * This function tries to retrieve the MathGlyphConstruction for the specified
+ * font, glyph and direction. Note that only the value of
+ * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
+ * of size variants as an array of hb_ot_math_glyph_variant_t structs.
*
- * Return value: the total number of size variants available or zero
+ * Return value: the total number of size variants available or 0
*
* Since: 1.3.3
**/
@@ -260,27 +186,24 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
unsigned int *variants_count, /* IN/OUT */
hb_ot_math_glyph_variant_t *variants /* OUT */)
{
- return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
- start_offset,
- variants_count,
- variants);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_variants().get_glyph_variants (glyph, direction, font,
+ start_offset,
+ variants_count,
+ variants);
}
/**
* hb_ot_math_get_min_connector_overlap:
- * @font: #hb_font_t to work upon
- * @direction: direction of the stretching (horizontal or vertical)
+ * @font: #hb_font_t from which to retrieve the value
+ * @direction: direction of the stretching
*
- * Fetches the MathVariants table for the specified font and returns the
- * minimum overlap of connecting glyphs that are required to draw a glyph
- * assembly in the specified direction.
+ * This function tries to retrieve the MathVariants table for the specified
+ * font and returns the minimum overlap of connecting glyphs to draw a glyph
+ * assembly in the specified direction. Note that only the value of
+ * #HB_DIRECTION_IS_HORIZONTAL is considered.
*
- * <note>The @direction parameter is only used to select between horizontal
- * or vertical directions for the construction. Even though all #hb_direction_t
- * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
- * considered.</note>
- *
- * Return value: requested minimum connector overlap or zero
+ * Return value: requested min connector overlap or 0
*
* Since: 1.3.3
**/
@@ -288,29 +211,25 @@ hb_position_t
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
hb_direction_t direction)
{
- return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_variants().get_min_connector_overlap (direction, font);
}
/**
* hb_ot_math_get_glyph_assembly:
- * @font: #hb_font_t to work upon
- * @glyph: The index of the glyph to stretch
- * @direction: direction of the stretching (horizontal or vertical)
+ * @font: #hb_font_t from which to retrieve the values
+ * @glyph: index of the glyph to stretch
+ * @direction: direction of the stretching
* @start_offset: offset of the first glyph part to retrieve
- * @parts_count: (inout): Input = maximum number of glyph parts to return;
- * Output = actual number of parts returned
- * @parts: (out) (array length=parts_count): the glyph parts returned
- * @italics_correction: (out): italics correction of the glyph assembly
- *
- * Fetches the GlyphAssembly for the specified font, glyph index, and direction.
- * Returned are a list of #hb_ot_math_glyph_part_t glyph parts that can be
- * used to draw the glyph and an italics-correction value (if one is defined
- * in the font).
+ * @parts_count: maximum number of glyph parts to retrieve after start_offset
+ * (IN) and actual number of parts retrieved (OUT)
+ * @parts: array of size at least @parts_count to store the result
+ * @italics_correction: italic correction of the glyph assembly
*
- * <note>The @direction parameter is only used to select between horizontal
- * or vertical directions for the construction. Even though all #hb_direction_t
- * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
- * considered.</note>
+ * This function tries to retrieve the GlyphAssembly for the specified font,
+ * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
+ * is considered. It provides the information necessary to draw the glyph
+ * assembly as an array of #hb_ot_math_glyph_part_t.
*
* Return value: the total number of parts in the glyph assembly
*
@@ -325,14 +244,10 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
hb_ot_math_glyph_part_t *parts, /* OUT */
hb_position_t *italics_correction /* OUT */)
{
- return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
- direction,
- font,
- start_offset,
- parts_count,
- parts,
- italics_correction);
+ const OT::MATH &math = _get_math (font->face);
+ return math.get_math_variants().get_glyph_parts (glyph, direction, font,
+ start_offset,
+ parts_count,
+ parts,
+ italics_correction);
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h
index 1378a0639a3..521a5ca0376 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h
@@ -24,7 +24,7 @@
* Igalia Author(s): Frédéric Wang
*/
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
@@ -40,93 +40,15 @@ HB_BEGIN_DECLS
* MATH
*/
-/**
- * HB_OT_TAG_MATH:
- *
- * OpenType [Mathematical Typesetting Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math).
- *
- * Since: 1.3.3
- */
#define HB_OT_TAG_MATH HB_TAG('M','A','T','H')
-/**
- * HB_OT_TAG_MATH_SCRIPT:
- *
- * OpenType script tag, `math`, for features specific to math shaping.
- *
- * <note>#HB_OT_TAG_MATH_SCRIPT is not a valid #hb_script_t and should only be
- * used with functions that accept raw OpenType script tags, such as
- * #hb_ot_layout_collect_features. In other cases, #HB_SCRIPT_MATH should be
- * used instead.</note>
- *
- * Since: 3.4.0
- */
-#define HB_OT_TAG_MATH_SCRIPT HB_TAG('m','a','t','h')
+/* Use with hb_buffer_set_script() for math shaping. */
+#define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h')
/* Types */
/**
* hb_ot_math_constant_t:
- * @HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN: scriptPercentScaleDown
- * @HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN: scriptScriptPercentScaleDown
- * @HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT: delimitedSubFormulaMinHeight
- * @HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT: displayOperatorMinHeight
- * @HB_OT_MATH_CONSTANT_MATH_LEADING: mathLeading
- * @HB_OT_MATH_CONSTANT_AXIS_HEIGHT: axisHeight
- * @HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: accentBaseHeight
- * @HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT: flattenedAccentBaseHeight
- * @HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN: subscriptShiftDown
- * @HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX: subscriptTopMax
- * @HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN: subscriptBaselineDropMin
- * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP: superscriptShiftUp
- * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED: superscriptShiftUpCramped
- * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN: superscriptBottomMin
- * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX: superscriptBaselineDropMax
- * @HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN: subSuperscriptGapMin
- * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT: superscriptBottomMaxWithSubscript
- * @HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: spaceAfterScript
- * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: upperLimitGapMin
- * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: upperLimitBaselineRiseMin
- * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN: lowerLimitGapMin
- * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN: lowerLimitBaselineDropMin
- * @HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP: stackTopShiftUp
- * @HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP: stackTopDisplayStyleShiftUp
- * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN: stackBottomShiftDown
- * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN: stackBottomDisplayStyleShiftDown
- * @HB_OT_MATH_CONSTANT_STACK_GAP_MIN: stackGapMin
- * @HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN: stackDisplayStyleGapMin
- * @HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP: stretchStackTopShiftUp
- * @HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN: stretchStackBottomShiftDown
- * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN: stretchStackGapAboveMin
- * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN: stretchStackGapBelowMin
- * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP: fractionNumeratorShiftUp
- * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP: fractionNumeratorDisplayStyleShiftUp
- * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN: fractionDenominatorShiftDown
- * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN: fractionDenominatorDisplayStyleShiftDown
- * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN: fractionNumeratorGapMin
- * @HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN: fractionNumDisplayStyleGapMin
- * @HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS: fractionRuleThickness
- * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN: fractionDenominatorGapMin
- * @HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN: fractionDenomDisplayStyleGapMin
- * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: skewedFractionHorizontalGap
- * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP: skewedFractionVerticalGap
- * @HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP: overbarVerticalGap
- * @HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS: overbarRuleThickness
- * @HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER: overbarExtraAscender
- * @HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: underbarVerticalGap
- * @HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS: underbarRuleThickness
- * @HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER: underbarExtraDescender
- * @HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP: radicalVerticalGap
- * @HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP: radicalDisplayStyleVerticalGap
- * @HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS: radicalRuleThickness
- * @HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER: radicalExtraAscender
- * @HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: radicalKernBeforeDegree
- * @HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE: radicalKernAfterDegree
- * @HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: radicalDegreeBottomRaisePercent
- *
- * The 'MATH' table constants, refer to
- * [OpenType documentation](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table)
- * For more explanations.
*
* Since: 1.3.3
*/
@@ -191,13 +113,6 @@ typedef enum {
/**
* hb_ot_math_kern_t:
- * @HB_OT_MATH_KERN_TOP_RIGHT: The top right corner of the glyph.
- * @HB_OT_MATH_KERN_TOP_LEFT: The top left corner of the glyph.
- * @HB_OT_MATH_KERN_BOTTOM_RIGHT: The bottom right corner of the glyph.
- * @HB_OT_MATH_KERN_BOTTOM_LEFT: The bottom left corner of the glyph.
- *
- * The math kerning-table types defined for the four corners
- * of a glyph.
*
* Since: 1.3.3
*/
@@ -209,25 +124,7 @@ typedef enum {
} hb_ot_math_kern_t;
/**
- * hb_ot_math_kern_entry_t:
- * @max_correction_height: The maximum height at which this entry should be used
- * @kern_value: The kern value of the entry
- *
- * Data type to hold math kerning (cut-in) information for a glyph.
- *
- * Since: 3.4.0
- */
-typedef struct {
- hb_position_t max_correction_height;
- hb_position_t kern_value;
-} hb_ot_math_kern_entry_t;
-
-/**
* hb_ot_math_glyph_variant_t:
- * @glyph: The glyph index of the variant
- * @advance: The advance width of the variant
- *
- * Data type to hold math-variant information for a glyph.
*
* Since: 1.3.3
*/
@@ -238,28 +135,15 @@ typedef struct hb_ot_math_glyph_variant_t {
/**
* hb_ot_math_glyph_part_flags_t:
- * @HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER: This is an extender glyph part that
- * can be repeated to reach the desired length.
- *
- * Flags for math glyph parts.
*
* Since: 1.3.3
*/
typedef enum { /*< flags >*/
- HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER = 0x00000001u /* Extender glyph */
+ HB_MATH_GLYPH_PART_FLAG_EXTENDER = 0x00000001u /* Extender glyph */
} hb_ot_math_glyph_part_flags_t;
/**
* hb_ot_math_glyph_part_t:
- * @glyph: The glyph index of the variant part
- * @start_connector_length: The length of the connector on the starting side of the variant part
- * @end_connector_length: The length of the connector on the ending side of the variant part
- * @full_advance: The total advance of the part
- * @flags: #hb_ot_math_glyph_part_flags_t flags for the part
- *
- * Data type to hold information for a "part" component of a math-variant glyph.
- * Large variants for stretchable math glyphs (such as parentheses) can be constructed
- * on the fly from parts.
*
* Since: 1.3.3
*/
@@ -299,14 +183,6 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
hb_position_t correction_height);
HB_EXTERN unsigned int
-hb_ot_math_get_glyph_kernings (hb_font_t *font,
- hb_codepoint_t glyph,
- hb_ot_math_kern_t kern,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT */
- hb_ot_math_kern_entry_t *kern_entries /* OUT */);
-
-HB_EXTERN unsigned int
hb_ot_math_get_glyph_variants (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
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 0f4cc414ef8..f6d283eb14a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -27,123 +27,40 @@
#ifndef HB_OT_MAXP_TABLE_HH
#define HB_OT_MAXP_TABLE_HH
-#include "hb-open-type.hh"
+#include "hb-open-type-private.hh"
+
namespace OT {
/*
- * maxp -- Maximum Profile
- * https://docs.microsoft.com/en-us/typography/opentype/spec/maxp
+ * maxp -- The Maximum Profile Table
*/
#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
-struct maxpV1Tail
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- HBUINT16 maxPoints; /* Maximum points in a non-composite glyph. */
- HBUINT16 maxContours; /* Maximum contours in a non-composite glyph. */
- HBUINT16 maxCompositePoints; /* Maximum points in a composite glyph. */
- HBUINT16 maxCompositeContours; /* Maximum contours in a composite glyph. */
- HBUINT16 maxZones; /* 1 if instructions do not use the twilight zone (Z0),
- * or 2 if instructions do use Z0; should be set to 2 in
- * most cases. */
- HBUINT16 maxTwilightPoints; /* Maximum points used in Z0. */
- HBUINT16 maxStorage; /* Number of Storage Area locations. */
- HBUINT16 maxFunctionDefs; /* Number of FDEFs, equal to the highest function number + 1. */
- HBUINT16 maxInstructionDefs; /* Number of IDEFs. */
- HBUINT16 maxStackElements; /* Maximum stack depth. (This includes Font and CVT
- * Programs, as well as the instructions for each glyph.) */
- HBUINT16 maxSizeOfInstructions; /* Maximum byte count for glyph instructions. */
- HBUINT16 maxComponentElements; /* Maximum number of components referenced at
- * "top level" for any composite glyph. */
- HBUINT16 maxComponentDepth; /* Maximum levels of recursion; 1 for simple components. */
- public:
- DEFINE_SIZE_STATIC (26);
-};
-
-
struct maxp
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_maxp;
+ static const hb_tag_t tableTag = HB_OT_TAG_maxp;
- unsigned int get_num_glyphs () const { return numGlyphs; }
-
- void set_num_glyphs (unsigned int count)
+ inline unsigned int get_num_glyphs (void) const
{
- numGlyphs = count;
+ return numGlyphs;
}
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- if (version.major == 1)
- {
- const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this);
- return_trace (v1.sanitize (c));
- }
- return_trace (likely (version.major == 0 && version.minor == 0x5000u));
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- maxp *maxp_prime = c->serializer->embed (this);
- if (unlikely (!maxp_prime)) return_trace (false);
-
- maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu);
- if (maxp_prime->version.major == 1)
- {
- const maxpV1Tail *src_v1 = &StructAfter<maxpV1Tail> (*this);
- maxpV1Tail *dest_v1 = c->serializer->embed<maxpV1Tail> (src_v1);
- if (unlikely (!dest_v1)) return_trace (false);
-
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- drop_hint_fields (dest_v1);
-
- if (c->plan->normalized_coords)
- instancing_update_fields (c->plan->head_maxp_info, dest_v1);
- }
-
- return_trace (true);
- }
-
- void instancing_update_fields (head_maxp_info_t& maxp_info, maxpV1Tail* dest_v1) const
- {
- dest_v1->maxPoints = maxp_info.maxPoints;
- dest_v1->maxContours = maxp_info.maxContours;
- dest_v1->maxCompositePoints = maxp_info.maxCompositePoints;
- dest_v1->maxCompositeContours = maxp_info.maxCompositeContours;
- dest_v1->maxComponentElements = maxp_info.maxComponentElements;
- dest_v1->maxComponentDepth = maxp_info.maxComponentDepth;
- }
-
- static void drop_hint_fields (maxpV1Tail* dest_v1)
- {
- dest_v1->maxZones = 1;
- dest_v1->maxTwilightPoints = 0;
- dest_v1->maxStorage = 0;
- dest_v1->maxFunctionDefs = 0;
- dest_v1->maxInstructionDefs = 0;
- dest_v1->maxStackElements = 0;
- dest_v1->maxSizeOfInstructions = 0;
+ return_trace (c->check_struct (this) &&
+ likely (version.major == 1 ||
+ (version.major == 0 && version.minor == 0x5000u)));
}
+ /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
protected:
- FixedVersion<>version;/* Version of the maxp table (0.5 or 1.0),
- * 0x00005000u or 0x00010000u. */
- HBUINT16 numGlyphs;
- /* The number of glyphs in the font. */
-/*maxpV1Tail v1Tail[HB_VAR_ARRAY]; */
+ FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
+ * 0x00005000u or 0x00010000u. */
+ UINT16 numGlyphs; /* The number of glyphs in the font. */
public:
DEFINE_SIZE_STATIC (6);
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh
deleted file mode 100644
index e1b68bcf91d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta-table.hh
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_OT_META_TABLE_HH
-#define HB_OT_META_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * meta -- Metadata Table
- * https://docs.microsoft.com/en-us/typography/opentype/spec/meta
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
- */
-#define HB_OT_TAG_meta HB_TAG ('m','e','t','a')
-
-
-namespace OT {
-
-
-struct DataMap
-{
- int cmp (hb_tag_t a) const { return tag.cmp (a); }
-
- hb_tag_t get_tag () const { return tag; }
-
- hb_blob_t *reference_entry (hb_blob_t *meta_blob) const
- { return hb_blob_create_sub_blob (meta_blob, dataZ, dataLength); }
-
- bool sanitize (hb_sanitize_context_t *c, const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- dataZ.sanitize (c, base, dataLength)));
- }
-
- protected:
- Tag tag; /* A tag indicating the type of metadata. */
- NNOffset32To<UnsizedArrayOf<HBUINT8>>
- dataZ; /* Offset in bytes from the beginning of the
- * metadata table to the data for this tag. */
- HBUINT32 dataLength; /* Length of the data. The data is not required to
- * be padded to any byte boundary. */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct meta
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_meta;
-
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- { table = hb_sanitize_context_t ().reference_table<meta> (face); }
- ~accelerator_t () { table.destroy (); }
-
- hb_blob_t *reference_entry (hb_tag_t tag) const
- { return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
-
- unsigned int get_entries (unsigned int start_offset,
- unsigned int *count,
- hb_ot_meta_tag_t *entries) const
- {
- if (count)
- {
- + table->dataMaps.as_array ().sub_array (start_offset, count)
- | hb_map (&DataMap::get_tag)
- | hb_map ([](hb_tag_t tag) { return (hb_ot_meta_tag_t) tag; })
- | hb_sink (hb_array (entries, *count))
- ;
- }
- return table->dataMaps.len;
- }
-
- private:
- hb_blob_ptr_t<meta> table;
- };
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version == 1 &&
- dataMaps.sanitize (c, this)));
- }
-
- protected:
- HBUINT32 version; /* Version number of the metadata table — set to 1. */
- HBUINT32 flags; /* Flags — currently unused; set to 0. */
- HBUINT32 dataOffset;
- /* Per Apple specification:
- * Offset from the beginning of the table to the data.
- * Per OT specification:
- * Reserved. Not used; should be set to 0. */
- Array32Of<DataMap>
- dataMaps;/* Array of data map records. */
- public:
- DEFINE_SIZE_ARRAY (16, dataMaps);
-};
-
-struct meta_accelerator_t : meta::accelerator_t {
- meta_accelerator_t (hb_face_t *face) : meta::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_META_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc
deleted file mode 100644
index 35c8eb523f9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_META
-
-#include "hb-ot-meta-table.hh"
-
-/**
- * SECTION:hb-ot-meta
- * @title: hb-ot-meta
- * @short_description: OpenType Metadata
- * @include: hb-ot.h
- *
- * Functions for fetching metadata from fonts.
- **/
-
-/**
- * hb_ot_meta_get_entry_tags:
- * @face: a face object
- * @start_offset: iteration's start offset
- * @entries_count:(inout) (optional): buffer size as input, filled size as output
- * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
- *
- * Fetches all available feature types.
- *
- * Return value: Number of all available feature types.
- *
- * Since: 2.6.0
- **/
-unsigned int
-hb_ot_meta_get_entry_tags (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT. May be NULL. */
- hb_ot_meta_tag_t *entries /* OUT. May be NULL. */)
-{
- return face->table.meta->get_entries (start_offset, entries_count, entries);
-}
-
-/**
- * hb_ot_meta_reference_entry:
- * @face: a #hb_face_t object.
- * @meta_tag: tag of metadata you like to have.
- *
- * It fetches metadata entry of a given tag from a font.
- *
- * Returns: (transfer full): A blob containing the blob.
- *
- * Since: 2.6.0
- **/
-hb_blob_t *
-hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag)
-{
- return face->table.meta->reference_entry (meta_tag);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h
deleted file mode 100644
index 7748eb49582..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-meta.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_META_H
-#define HB_OT_META_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-/**
- * hb_ot_meta_tag_t:
- * @HB_OT_META_TAG_DESIGN_LANGUAGES: Design languages. Text, using only
- * Basic Latin (ASCII) characters. Indicates languages and/or scripts
- * for the user audiences that the font was primarily designed for.
- * @HB_OT_META_TAG_SUPPORTED_LANGUAGES: Supported languages. Text, using
- * only Basic Latin (ASCII) characters. Indicates languages and/or scripts
- * that the font is declared to be capable of supporting.
- *
- * Known metadata tags from https://docs.microsoft.com/en-us/typography/opentype/spec/meta
- *
- * Since: 2.6.0
- **/
-typedef enum {
-/*
- HB_OT_META_TAG_APPL = HB_TAG ('a','p','p','l'),
- HB_OT_META_TAG_BILD = HB_TAG ('b','i','l','d'),
-*/
- HB_OT_META_TAG_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'),
- HB_OT_META_TAG_SUPPORTED_LANGUAGES = HB_TAG ('s','l','n','g'),
-
- /*< private >*/
- _HB_OT_META_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_ot_meta_tag_t;
-
-HB_EXTERN unsigned int
-hb_ot_meta_get_entry_tags (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *entries_count, /* IN/OUT. May be NULL. */
- hb_ot_meta_tag_t *entries /* OUT. May be NULL. */);
-
-HB_EXTERN hb_blob_t *
-hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag);
-
-HB_END_DECLS
-
-#endif /* HB_OT_META_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc
deleted file mode 100644
index 5b12482b979..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright © 2018-2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#include "hb-ot-var-mvar-table.hh"
-#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-post-table.hh"
-#include "hb-ot-hhea-table.hh"
-#include "hb-ot-metrics.hh"
-#include "hb-ot-face.hh"
-
-
-/**
- * SECTION:hb-ot-metrics
- * @title: hb-ot-metrics
- * @short_description: OpenType Metrics
- * @include: hb-ot.h
- *
- * Functions for fetching metrics from fonts.
- **/
-
-static float
-_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
-{
- if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER ||
- metrics_tag == HB_OT_METRICS_TAG_VERTICAL_ASCENDER)
- return fabs ((double) value);
- if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER ||
- metrics_tag == HB_OT_METRICS_TAG_VERTICAL_DESCENDER)
- return -fabs ((double) value);
- return value;
-}
-
-/* The common part of _get_position logic needed on hb-ot-font and here
- to be able to have slim builds without the not always needed parts */
-bool
-_hb_ot_metrics_get_position_common (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */)
-{
- hb_face_t *face = font->face;
- switch ((unsigned) metrics_tag)
- {
-#ifndef HB_NO_VAR
-#define GET_VAR face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords)
-#else
-#define GET_VAR .0f
-#endif
-#define GET_METRIC_X(TABLE, ATTR) \
- (face->table.TABLE->has_data () && \
- ((void) (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \
- face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true))
-#define GET_METRIC_Y(TABLE, ATTR) \
- (face->table.TABLE->has_data () && \
- ((void) (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
- face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true))
-
- case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
- return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
- GET_METRIC_Y (hhea, ascender);
- case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
- return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoDescender)) ||
- GET_METRIC_Y (hhea, descender);
- case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
- return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
- GET_METRIC_Y (hhea, lineGap);
-
-#ifndef HB_NO_VERTICAL
- case HB_OT_METRICS_TAG_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender);
- case HB_OT_METRICS_TAG_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
- case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap);
-#endif
-
-#undef GET_METRIC_Y
-#undef GET_METRIC_X
-#undef GET_VAR
- default: assert (0); return false;
- }
-}
-
-#ifndef HB_NO_METRICS
-
-#if 0
-static bool
-_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag)
-{
- const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
- if (&range == &Null (OT::GaspRange)) return false;
- if (result) *result = range.rangeMaxPPEM + font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
- return true;
-}
-#endif
-
-/* Private tags for https://github.com/harfbuzz/harfbuzz/issues/1866 */
-#define _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_OS2 HB_TAG ('O','a','s','c')
-#define _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_HHEA HB_TAG ('H','a','s','c')
-#define _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_OS2 HB_TAG ('O','d','s','c')
-#define _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_HHEA HB_TAG ('H','d','s','c')
-#define _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_OS2 HB_TAG ('O','l','g','p')
-#define _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_HHEA HB_TAG ('H','l','g','p')
-
-/**
- * hb_ot_metrics_get_position:
- * @font: an #hb_font_t object.
- * @metrics_tag: tag of metrics value you like to fetch.
- * @position: (out) (optional): result of metrics value from the font.
- *
- * Fetches metrics value corresponding to @metrics_tag from @font.
- *
- * Returns: Whether found the requested metrics in the font.
- * Since: 2.6.0
- **/
-hb_bool_t
-hb_ot_metrics_get_position (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */)
-{
- hb_face_t *face = font->face;
- switch ((unsigned) metrics_tag)
- {
- case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
- case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
- case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
- case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:
- case HB_OT_METRICS_TAG_VERTICAL_DESCENDER:
- case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: return _hb_ot_metrics_get_position_common (font, metrics_tag, position);
-#ifndef HB_NO_VAR
-#define GET_VAR hb_ot_metrics_get_variation (font, metrics_tag)
-#else
-#define GET_VAR 0
-#endif
-#define GET_METRIC_X(TABLE, ATTR) \
- (face->table.TABLE->has_data () && \
- ((void) (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR))), true))
-#define GET_METRIC_Y(TABLE, ATTR) \
- (face->table.TABLE->has_data () && \
- ((void) (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR))), true))
- case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
- case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
-
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
- {
- unsigned mult = 1u;
-
- if (font->slant)
- {
- unsigned rise = face->table.hhea->caretSlopeRise;
- unsigned upem = face->get_upem ();
- mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u;
- }
-
- if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE)
- {
- bool ret = GET_METRIC_Y (hhea, caretSlopeRise);
-
- if (position)
- *position *= mult;
-
- return ret;
- }
- else
- {
- hb_position_t rise = 0;
-
- if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise))
- rise = *position;
-
- bool ret = GET_METRIC_X (hhea, caretSlopeRun);
-
- if (position)
- {
- *position *= mult;
-
- if (font->slant)
- *position += _hb_roundf (mult * font->slant_xy * rise);
- }
-
- return ret;
- }
- }
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
-
-#ifndef HB_NO_VERTICAL
- case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
- case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
- case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset);
-#endif
- case HB_OT_METRICS_TAG_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight);
- case HB_OT_METRICS_TAG_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight);
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize);
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySubscriptYSize);
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySubscriptXOffset);
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySubscriptYOffset);
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySuperscriptXSize);
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySuperscriptYSize);
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySuperscriptXOffset);
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySuperscriptYOffset);
- case HB_OT_METRICS_TAG_STRIKEOUT_SIZE: return GET_METRIC_Y (OS2, yStrikeoutSize);
- case HB_OT_METRICS_TAG_STRIKEOUT_OFFSET: return GET_METRIC_Y (OS2, yStrikeoutPosition);
- case HB_OT_METRICS_TAG_UNDERLINE_SIZE: return GET_METRIC_Y (post->table, underlineThickness);
- case HB_OT_METRICS_TAG_UNDERLINE_OFFSET: return GET_METRIC_Y (post->table, underlinePosition);
-
- /* Private tags */
- case _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_OS2: return GET_METRIC_Y (OS2, sTypoAscender);
- case _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_HHEA: return GET_METRIC_Y (hhea, ascender);
- case _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_OS2: return GET_METRIC_Y (OS2, sTypoDescender);
- case _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_HHEA: return GET_METRIC_Y (hhea, descender);
- case _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_OS2: return GET_METRIC_Y (OS2, sTypoLineGap);
- case _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_HHEA: return GET_METRIC_Y (hhea, lineGap);
-#undef GET_METRIC_Y
-#undef GET_METRIC_X
-#undef GET_VAR
- default: return false;
- }
-}
-
-/**
- * hb_ot_metrics_get_position_with_fallback:
- * @font: an #hb_font_t object.
- * @metrics_tag: tag of metrics value you like to fetch.
- * @position: (out) (optional): result of metrics value from the font.
- *
- * Fetches metrics value corresponding to @metrics_tag from @font,
- * and synthesizes a value if it the value is missing in the font.
- *
- * Since: 4.0.0
- **/
-void
-hb_ot_metrics_get_position_with_fallback (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT */)
-{
- hb_font_extents_t font_extents;
- hb_codepoint_t glyph;
- hb_glyph_extents_t extents;
-
- if (hb_ot_metrics_get_position (font, metrics_tag, position))
- {
- if ((metrics_tag != HB_OT_METRICS_TAG_STRIKEOUT_SIZE &&
- metrics_tag != HB_OT_METRICS_TAG_UNDERLINE_SIZE) ||
- *position != 0)
- return;
- }
-
- switch (metrics_tag)
- {
- case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
- case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
- *position = font_extents.ascender;
- break;
-
- case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
- *position = font_extents.ascender;
- break;
-
- case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
- case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
- *position = font_extents.descender;
- break;
-
- case HB_OT_METRICS_TAG_VERTICAL_DESCENDER:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
- *position = font_extents.ascender;
- break;
-
- case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
- *position = font_extents.line_gap;
- break;
-
- case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP:
- hb_font_get_extents_for_direction (font, HB_DIRECTION_TTB, &font_extents);
- *position = font_extents.line_gap;
- break;
-
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
- case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE:
- *position = 1;
- break;
-
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
- case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN:
- *position = 0;
- break;
-
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET:
- case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET:
- *position = 0;
- break;
-
- case HB_OT_METRICS_TAG_X_HEIGHT:
- if (hb_font_get_nominal_glyph (font, 'x', &glyph) &&
- hb_font_get_glyph_extents (font, glyph, &extents))
- *position = extents.y_bearing;
- else
- *position = font->y_scale / 2;
- break;
-
- case HB_OT_METRICS_TAG_CAP_HEIGHT:
- if (hb_font_get_nominal_glyph (font, 'O', &glyph) &&
- hb_font_get_glyph_extents (font, glyph, &extents))
- *position = extents.height + 2 * extents.y_bearing;
- else
- *position = font->y_scale * 2 / 3;
- break;
-
- case HB_OT_METRICS_TAG_STRIKEOUT_SIZE:
- case HB_OT_METRICS_TAG_UNDERLINE_SIZE:
- *position = font->y_scale / 18;
- break;
-
- case HB_OT_METRICS_TAG_STRIKEOUT_OFFSET:
- {
- hb_position_t ascender;
- hb_ot_metrics_get_position_with_fallback (font,
- HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER,
- &ascender);
- *position = ascender / 2;
- }
- break;
-
- case HB_OT_METRICS_TAG_UNDERLINE_OFFSET:
- *position = - font->y_scale / 18;
- break;
-
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE:
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE:
- *position = font->x_scale * 10 / 12;
- break;
-
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE:
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE:
- *position = font->y_scale * 10 / 12;
- break;
-
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET:
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET:
- *position = 0;
- break;
-
- case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET:
- case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET:
- *position = font->y_scale / 5;
- break;
-
- case _HB_OT_METRICS_TAG_MAX_VALUE:
- default:
- *position = 0;
- break;
- }
-}
-
-#ifndef HB_NO_VAR
-/**
- * hb_ot_metrics_get_variation:
- * @font: an #hb_font_t object.
- * @metrics_tag: tag of metrics value you like to fetch.
- *
- * Fetches metrics value corresponding to @metrics_tag from @font with the
- * current font variation settings applied.
- *
- * Returns: The requested metric value.
- *
- * Since: 2.6.0
- **/
-float
-hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
-{
- return font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
-}
-
-/**
- * hb_ot_metrics_get_x_variation:
- * @font: an #hb_font_t object.
- * @metrics_tag: tag of metrics value you like to fetch.
- *
- * Fetches horizontal metrics value corresponding to @metrics_tag from @font
- * with the current font variation settings applied.
- *
- * Returns: The requested metric value.
- *
- * Since: 2.6.0
- **/
-hb_position_t
-hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
-{
- return font->em_scalef_x (hb_ot_metrics_get_variation (font, metrics_tag));
-}
-
-/**
- * hb_ot_metrics_get_y_variation:
- * @font: an #hb_font_t object.
- * @metrics_tag: tag of metrics value you like to fetch.
- *
- * Fetches vertical metrics value corresponding to @metrics_tag from @font with
- * the current font variation settings applied.
- *
- * Returns: The requested metric value.
- *
- * Since: 2.6.0
- **/
-hb_position_t
-hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
-{
- return font->em_scalef_y (hb_ot_metrics_get_variation (font, metrics_tag));
-}
-#endif
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h
deleted file mode 100644
index 30de5000889..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_METRICS_H
-#define HB_OT_METRICS_H
-
-#include "hb.h"
-#include "hb-ot-name.h"
-
-HB_BEGIN_DECLS
-
-
-/**
- * hb_ot_metrics_tag_t:
- * @HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: horizontal ascender.
- * @HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER: horizontal descender.
- * @HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP: horizontal line gap.
- * @HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: horizontal clipping ascent.
- * @HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: horizontal clipping descent.
- * @HB_OT_METRICS_TAG_VERTICAL_ASCENDER: vertical ascender.
- * @HB_OT_METRICS_TAG_VERTICAL_DESCENDER: vertical descender.
- * @HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: vertical line gap.
- * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: horizontal caret rise.
- * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: horizontal caret run.
- * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: horizontal caret offset.
- * @HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: vertical caret rise.
- * @HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: vertical caret run.
- * @HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: vertical caret offset.
- * @HB_OT_METRICS_TAG_X_HEIGHT: x height.
- * @HB_OT_METRICS_TAG_CAP_HEIGHT: cap height.
- * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: subscript em x size.
- * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE: subscript em y size.
- * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET: subscript em x offset.
- * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET: subscript em y offset.
- * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE: superscript em x size.
- * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE: superscript em y size.
- * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET: superscript em x offset.
- * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET: superscript em y offset.
- * @HB_OT_METRICS_TAG_STRIKEOUT_SIZE: strikeout size.
- * @HB_OT_METRICS_TAG_STRIKEOUT_OFFSET: strikeout offset.
- * @HB_OT_METRICS_TAG_UNDERLINE_SIZE: underline size.
- * @HB_OT_METRICS_TAG_UNDERLINE_OFFSET: underline offset.
- *
- * Metric tags corresponding to [MVAR Value
- * Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags)
- *
- * Since: 2.6.0
- **/
-typedef enum {
- HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER = HB_TAG ('h','a','s','c'),
- HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER = HB_TAG ('h','d','s','c'),
- HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP = HB_TAG ('h','l','g','p'),
- HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT = HB_TAG ('h','c','l','a'),
- HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT = HB_TAG ('h','c','l','d'),
- HB_OT_METRICS_TAG_VERTICAL_ASCENDER = HB_TAG ('v','a','s','c'),
- HB_OT_METRICS_TAG_VERTICAL_DESCENDER = HB_TAG ('v','d','s','c'),
- HB_OT_METRICS_TAG_VERTICAL_LINE_GAP = HB_TAG ('v','l','g','p'),
- HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE = HB_TAG ('h','c','r','s'),
- HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN = HB_TAG ('h','c','r','n'),
- HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET = HB_TAG ('h','c','o','f'),
- HB_OT_METRICS_TAG_VERTICAL_CARET_RISE = HB_TAG ('v','c','r','s'),
- HB_OT_METRICS_TAG_VERTICAL_CARET_RUN = HB_TAG ('v','c','r','n'),
- HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET = HB_TAG ('v','c','o','f'),
- HB_OT_METRICS_TAG_X_HEIGHT = HB_TAG ('x','h','g','t'),
- HB_OT_METRICS_TAG_CAP_HEIGHT = HB_TAG ('c','p','h','t'),
- HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE = HB_TAG ('s','b','x','s'),
- HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE = HB_TAG ('s','b','y','s'),
- HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET = HB_TAG ('s','b','x','o'),
- HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET = HB_TAG ('s','b','y','o'),
- HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE = HB_TAG ('s','p','x','s'),
- HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE = HB_TAG ('s','p','y','s'),
- HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET = HB_TAG ('s','p','x','o'),
- HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET = HB_TAG ('s','p','y','o'),
- HB_OT_METRICS_TAG_STRIKEOUT_SIZE = HB_TAG ('s','t','r','s'),
- HB_OT_METRICS_TAG_STRIKEOUT_OFFSET = HB_TAG ('s','t','r','o'),
- HB_OT_METRICS_TAG_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'),
- HB_OT_METRICS_TAG_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'),
-
- /*< private >*/
- _HB_OT_METRICS_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_ot_metrics_tag_t;
-
-HB_EXTERN hb_bool_t
-hb_ot_metrics_get_position (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */);
-
-HB_EXTERN void
-hb_ot_metrics_get_position_with_fallback (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT */);
-
-HB_EXTERN float
-hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
-
-HB_EXTERN hb_position_t
-hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
-
-HB_EXTERN hb_position_t
-hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
-
-HB_END_DECLS
-
-#endif /* HB_OT_METRICS_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.hh
deleted file mode 100644
index 19a5e9ed41f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.hh
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_OT_METRICS_HH
-#define HB_OT_METRICS_HH
-
-#include "hb.hh"
-
-HB_INTERNAL bool
-_hb_ot_metrics_get_position_common (hb_font_t *font,
- hb_ot_metrics_tag_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */);
-
-#endif /* HB_OT_METRICS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh
deleted file mode 100644
index 0e0f2d632af..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language-static.hh
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Copyright © 2018 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_NAME_LANGUAGE_STATIC_HH
-#define HB_OT_NAME_LANGUAGE_STATIC_HH
-
-#include "hb-ot-name-language.hh"
-
-/* Following two tables were generated by joining FreeType, FontConfig,
- * and OpenType specification language lists, then filled in missing
- * entries using:
- * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings
- */
-
-struct hb_ot_language_map_t
-{
- int cmp (unsigned int key) const
- { return key < code ? -1 : key > code ? +1 : 0; }
-
- uint16_t code;
- char lang[6];
-};
-
-static const hb_ot_language_map_t
-_hb_ms_language_map[] =
-{
- {0x0001, "ar"}, /* ??? */
- {0x0004, "zh"}, /* ??? */
- {0x0009, "en"}, /* ??? */
- {0x0401, "ar"}, /* Arabic (Saudi Arabia) */
- {0x0402, "bg"}, /* Bulgarian (Bulgaria) */
- {0x0403, "ca"}, /* Catalan (Catalan) */
- {0x0404, "zh-tw"}, /* Chinese (Taiwan) */
- {0x0405, "cs"}, /* Czech (Czech Republic) */
- {0x0406, "da"}, /* Danish (Denmark) */
- {0x0407, "de"}, /* German (Germany) */
- {0x0408, "el"}, /* Greek (Greece) */
- {0x0409, "en"}, /* English (United States) */
- {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */
- {0x040B, "fi"}, /* Finnish (Finland) */
- {0x040C, "fr"}, /* French (France) */
- {0x040D, "he"}, /* Hebrew (Israel) */
- {0x040E, "hu"}, /* Hungarian (Hungary) */
- {0x040F, "is"}, /* Icelandic (Iceland) */
- {0x0410, "it"}, /* Italian (Italy) */
- {0x0411, "ja"}, /* Japanese (Japan) */
- {0x0412, "ko"}, /* Korean (Korea) */
- {0x0413, "nl"}, /* Dutch (Netherlands) */
- {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */
- {0x0415, "pl"}, /* Polish (Poland) */
- {0x0416, "pt"}, /* Portuguese (Brazil) */
- {0x0417, "rm"}, /* Romansh (Switzerland) */
- {0x0418, "ro"}, /* Romanian (Romania) */
- {0x0419, "ru"}, /* Russian (Russia) */
- {0x041A, "hr"}, /* Croatian (Croatia) */
- {0x041B, "sk"}, /* Slovak (Slovakia) */
- {0x041C, "sq"}, /* Albanian (Albania) */
- {0x041D, "sv"}, /* Swedish (Sweden) */
- {0x041E, "th"}, /* Thai (Thailand) */
- {0x041F, "tr"}, /* Turkish (Turkey) */
- {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */
- {0x0421, "id"}, /* Indonesian (Indonesia) */
- {0x0422, "uk"}, /* Ukrainian (Ukraine) */
- {0x0423, "be"}, /* Belarusian (Belarus) */
- {0x0424, "sl"}, /* Slovenian (Slovenia) */
- {0x0425, "et"}, /* Estonian (Estonia) */
- {0x0426, "lv"}, /* Latvian (Latvia) */
- {0x0427, "lt"}, /* Lithuanian (Lithuania) */
- {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */
- {0x0429, "fa"}, /* Persian (Iran) */
- {0x042A, "vi"}, /* Vietnamese (Vietnam) */
- {0x042B, "hy"}, /* Armenian (Armenia) */
- {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */
- {0x042D, "eu"}, /* Basque (Basque) */
- {0x042E, "hsb"}, /* Upper Sorbian (Germany) */
- {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */
- {0x0430, "st"}, /* ??? */
- {0x0431, "ts"}, /* ??? */
- {0x0432, "tn"}, /* Setswana (South Africa) */
- {0x0433, "ven"}, /* ??? */
- {0x0434, "xh"}, /* isiXhosa (South Africa) */
- {0x0435, "zu"}, /* isiZulu (South Africa) */
- {0x0436, "af"}, /* Afrikaans (South Africa) */
- {0x0437, "ka"}, /* Georgian (Georgia) */
- {0x0438, "fo"}, /* Faroese (Faroe Islands) */
- {0x0439, "hi"}, /* Hindi (India) */
- {0x043A, "mt"}, /* Maltese (Malta) */
- {0x043B, "se"}, /* Sami (Northern) (Norway) */
- {0x043C, "ga"}, /* ??? */
- {0x043D, "yi"}, /* ??? */
- {0x043E, "ms"}, /* Malay (Malaysia) */
- {0x043F, "kk"}, /* Kazakh (Kazakhstan) */
- {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */
- {0x0441, "sw"}, /* Kiswahili (Kenya) */
- {0x0442, "tk"}, /* Turkmen (Turkmenistan) */
- {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */
- {0x0444, "tt"}, /* Tatar (Russia) */
- {0x0445, "bn"}, /* Bengali (India) */
- {0x0446, "pa"}, /* Punjabi (India) */
- {0x0447, "gu"}, /* Gujarati (India) */
- {0x0448, "or"}, /* Odia (formerly Oriya) (India) */
- {0x0449, "ta"}, /* Tamil (India) */
- {0x044A, "te"}, /* Telugu (India) */
- {0x044B, "kn"}, /* Kannada (India) */
- {0x044C, "ml"}, /* Malayalam (India) */
- {0x044D, "as"}, /* Assamese (India) */
- {0x044E, "mr"}, /* Marathi (India) */
- {0x044F, "sa"}, /* Sanskrit (India) */
- {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */
- {0x0451, "bo"}, /* Tibetan (PRC) */
- {0x0452, "cy"}, /* Welsh (United Kingdom) */
- {0x0453, "km"}, /* Khmer (Cambodia) */
- {0x0454, "lo"}, /* Lao (Lao P.D.R.) */
- {0x0455, "my"}, /* ??? */
- {0x0456, "gl"}, /* Galician (Galician) */
- {0x0457, "kok"}, /* Konkani (India) */
- {0x0458, "mni"}, /* ??? */
- {0x0459, "sd"}, /* ??? */
- {0x045A, "syr"}, /* Syriac (Syria) */
- {0x045B, "si"}, /* Sinhala (Sri Lanka) */
- {0x045C, "chr"}, /* ??? */
- {0x045D, "iu"}, /* Inuktitut (Canada) */
- {0x045E, "am"}, /* Amharic (Ethiopia) */
- {0x0460, "ks"}, /* ??? */
- {0x0461, "ne"}, /* Nepali (Nepal) */
- {0x0462, "fy"}, /* Frisian (Netherlands) */
- {0x0463, "ps"}, /* Pashto (Afghanistan) */
- {0x0464, "phi"}, /* Filipino (Philippines) */
- {0x0465, "div"}, /* Divehi (Maldives) */
- {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */
- {0x046A, "yo"}, /* Yoruba (Nigeria) */
- {0x046B, "quz"}, /* Quechua (Bolivia) */
- {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */
- {0x046D, "ba"}, /* Bashkir (Russia) */
- {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */
- {0x046F, "kl"}, /* Greenlandic (Greenland) */
- {0x0470, "ibo"}, /* Igbo (Nigeria) */
- {0x0471, "kau"}, /* ??? */
- {0x0472, "om"}, /* ??? */
- {0x0473, "ti"}, /* ??? */
- {0x0474, "gn"}, /* ??? */
- {0x0475, "haw"}, /* ??? */
- {0x0476, "la"}, /* ??? */
- {0x0477, "so"}, /* ??? */
- {0x0478, "ii"}, /* Yi (PRC) */
- {0x0479, "pap"}, /* ??? */
- {0x047A, "arn"}, /* Mapudungun (Chile) */
- {0x047C, "moh"}, /* Mohawk (Mohawk) */
- {0x047E, "br"}, /* Breton (France) */
- {0x0480, "ug"}, /* Uighur (PRC) */
- {0x0481, "mi"}, /* Maori (New Zealand) */
- {0x0482, "oc"}, /* Occitan (France) */
- {0x0483, "co"}, /* Corsican (France) */
- {0x0484, "gsw"}, /* Alsatian (France) */
- {0x0485, "sah"}, /* Yakut (Russia) */
- {0x0486, "qut"}, /* K'iche (Guatemala) */
- {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */
- {0x0488, "wo"}, /* Wolof (Senegal) */
- {0x048C, "fa"}, /* Dari (Afghanistan) */
- {0x0801, "ar"}, /* Arabic (Iraq) */
- {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */
- {0x0807, "de"}, /* German (Switzerland) */
- {0x0809, "en"}, /* English (United Kingdom) */
- {0x080A, "es"}, /* Spanish (Mexico) */
- {0x080C, "fr"}, /* French (Belgium) */
- {0x0810, "it"}, /* Italian (Switzerland) */
- {0x0812, "ko"}, /* ??? */
- {0x0813, "nl"}, /* Dutch (Belgium) */
- {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */
- {0x0816, "pt"}, /* Portuguese (Portugal) */
- {0x0818, "mo"}, /* ??? */
- {0x0819, "ru"}, /* ??? */
- {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */
- {0x081D, "sv"}, /* Sweden (Finland) */
- {0x0820, "ur"}, /* ??? */
- {0x0827, "lt"}, /* ??? */
- {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */
- {0x082E, "dsb"}, /* Lower Sorbian (Germany) */
-//{0x083B, ""}, /* Sami (Northern) (Sweden) */
- {0x083C, "gd"}, /* Irish (Ireland) */
- {0x083E, "ms"}, /* Malay (Brunei Darussalam) */
- {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */
- {0x0845, "bn"}, /* Bengali (Bangladesh) */
- {0x0846, "ar"}, /* ??? */
- {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */
- {0x0851, "dz"}, /* ??? */
- {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */
- {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */
- {0x0861, "ne"}, /* ??? */
-//{0x086B, ""}, /* Quechua (Ecuador) */
- {0x0873, "ti"}, /* ??? */
- {0x0C01, "ar"}, /* Arabic (Egypt) */
- {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */
- {0x0C07, "de"}, /* German (Austria) */
- {0x0C09, "en"}, /* English (Australia) */
- {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */
- {0x0C0C, "fr"}, /* French (Canada) */
- {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */
- {0x0C3B, "se"}, /* Sami (Northern) (Finland) */
-//{0x0C6B, ""}, /* Quechua (Peru) */
- {0x1001, "ar"}, /* Arabic (Libya) */
- {0x1004, "zh-sg"}, /* Chinese (Singapore) */
- {0x1007, "de"}, /* German (Luxembourg) */
- {0x1009, "en"}, /* English (Canada) */
- {0x100A, "es"}, /* Spanish (Guatemala) */
- {0x100C, "fr"}, /* French (Switzerland) */
- {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */
- {0x103B, "smj"}, /* Sami (Lule) (Norway) */
- {0x1401, "ar"}, /* Arabic (Algeria) */
-//{0x1404, ""}, /* Chinese (Macao S.A.R.) */
- {0x1407, "de"}, /* German (Liechtenstein) */
- {0x1409, "en"}, /* English (New Zealand) */
- {0x140A, "es"}, /* Spanish (Costa Rica) */
- {0x140C, "fr"}, /* French (Luxembourg) */
- {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */
-//{0x143B, ""}, /* Sami (Lule) (Sweden) */
- {0x1801, "ar"}, /* Arabic (Morocco) */
- {0x1809, "en"}, /* English (Ireland) */
- {0x180A, "es"}, /* Spanish (Panama) */
- {0x180C, "fr"}, /* French (Principality of Monaco) */
-//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */
- {0x183B, "sma"}, /* Sami (Southern) (Norway) */
- {0x1C01, "ar"}, /* Arabic (Tunisia) */
- {0x1C09, "en"}, /* English (South Africa) */
- {0x1C0A, "es"}, /* Spanish (Dominican Republic) */
- {0x1C0C, "fr"}, /* ??? */
-//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */
-//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */
- {0x2001, "ar"}, /* Arabic (Oman) */
- {0x2009, "en"}, /* English (Jamaica) */
- {0x200A, "es"}, /* Spanish (Venezuela) */
- {0x200C, "fr"}, /* ??? */
- {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */
- {0x203B, "sms"}, /* Sami (Skolt) (Finland) */
- {0x2401, "ar"}, /* Arabic (Yemen) */
- {0x2409, "en"}, /* English (Caribbean) */
- {0x240A, "es"}, /* Spanish (Colombia) */
- {0x240C, "fr"}, /* ??? */
- {0x243B, "smn"}, /* Sami (Inari) (Finland) */
- {0x2801, "ar"}, /* Arabic (Syria) */
- {0x2809, "en"}, /* English (Belize) */
- {0x280A, "es"}, /* Spanish (Peru) */
- {0x280C, "fr"}, /* ??? */
- {0x2C01, "ar"}, /* Arabic (Jordan) */
- {0x2C09, "en"}, /* English (Trinidad and Tobago) */
- {0x2C0A, "es"}, /* Spanish (Argentina) */
- {0x2C0C, "fr"}, /* ??? */
- {0x3001, "ar"}, /* Arabic (Lebanon) */
- {0x3009, "en"}, /* English (Zimbabwe) */
- {0x300A, "es"}, /* Spanish (Ecuador) */
- {0x300C, "fr"}, /* ??? */
- {0x3401, "ar"}, /* Arabic (Kuwait) */
- {0x3409, "en"}, /* English (Republic of the Philippines) */
- {0x340A, "es"}, /* Spanish (Chile) */
- {0x340C, "fr"}, /* ??? */
- {0x3801, "ar"}, /* Arabic (U.A.E.) */
- {0x380A, "es"}, /* Spanish (Uruguay) */
- {0x380C, "fr"}, /* ??? */
- {0x3C01, "ar"}, /* Arabic (Bahrain) */
- {0x3C09, "en"}, /* ??? */
- {0x3C0A, "es"}, /* Spanish (Paraguay) */
- {0x3C0C, "fr"}, /* ??? */
- {0x4001, "ar"}, /* Arabic (Qatar) */
- {0x4009, "en"}, /* English (India) */
- {0x400A, "es"}, /* Spanish (Bolivia) */
- {0x4409, "en"}, /* English (Malaysia) */
- {0x440A, "es"}, /* Spanish (El Salvador) */
- {0x4809, "en"}, /* English (Singapore) */
- {0x480A, "es"}, /* Spanish (Honduras) */
- {0x4C0A, "es"}, /* Spanish (Nicaragua) */
- {0x500A, "es"}, /* Spanish (Puerto Rico) */
- {0x540A, "es"}, /* Spanish (United States) */
- {0xE40A, "es"}, /* ??? */
- {0xE40C, "fr"}, /* ??? */
-};
-
-static const hb_ot_language_map_t
-_hb_mac_language_map[] =
-{
- { 0, "en"}, /* English */
- { 1, "fr"}, /* French */
- { 2, "de"}, /* German */
- { 3, "it"}, /* Italian */
- { 4, "nl"}, /* Dutch */
- { 5, "sv"}, /* Swedish */
- { 6, "es"}, /* Spanish */
- { 7, "da"}, /* Danish */
- { 8, "pt"}, /* Portuguese */
- { 9, "no"}, /* Norwegian */
- { 10, "he"}, /* Hebrew */
- { 11, "ja"}, /* Japanese */
- { 12, "ar"}, /* Arabic */
- { 13, "fi"}, /* Finnish */
- { 14, "el"}, /* Greek */
- { 15, "is"}, /* Icelandic */
- { 16, "mt"}, /* Maltese */
- { 17, "tr"}, /* Turkish */
- { 18, "hr"}, /* Croatian */
- { 19, "zh-tw"}, /* Chinese (Traditional) */
- { 20, "ur"}, /* Urdu */
- { 21, "hi"}, /* Hindi */
- { 22, "th"}, /* Thai */
- { 23, "ko"}, /* Korean */
- { 24, "lt"}, /* Lithuanian */
- { 25, "pl"}, /* Polish */
- { 26, "hu"}, /* Hungarian */
- { 27, "et"}, /* Estonian */
- { 28, "lv"}, /* Latvian */
-//{ 29, ""}, /* Sami */
- { 30, "fo"}, /* Faroese */
- { 31, "fa"}, /* Farsi/Persian */
- { 32, "ru"}, /* Russian */
- { 33, "zh-cn"}, /* Chinese (Simplified) */
- { 34, "nl"}, /* Flemish */
- { 35, "ga"}, /* Irish Gaelic */
- { 36, "sq"}, /* Albanian */
- { 37, "ro"}, /* Romanian */
- { 38, "cs"}, /* Czech */
- { 39, "sk"}, /* Slovak */
- { 40, "sl"}, /* Slovenian */
- { 41, "yi"}, /* Yiddish */
- { 42, "sr"}, /* Serbian */
- { 43, "mk"}, /* Macedonian */
- { 44, "bg"}, /* Bulgarian */
- { 45, "uk"}, /* Ukrainian */
- { 46, "be"}, /* Byelorussian */
- { 47, "uz"}, /* Uzbek */
- { 48, "kk"}, /* Kazakh */
- { 49, "az"}, /* Azerbaijani (Cyrillic script) */
- { 50, "az"}, /* Azerbaijani (Arabic script) */
- { 51, "hy"}, /* Armenian */
- { 52, "ka"}, /* Georgian */
- { 53, "mo"}, /* Moldavian */
- { 54, "ky"}, /* Kirghiz */
- { 55, "tg"}, /* Tajiki */
- { 56, "tk"}, /* Turkmen */
- { 57, "mn"}, /* Mongolian (Mongolian script) */
- { 58, "mn"}, /* Mongolian (Cyrillic script) */
- { 59, "ps"}, /* Pashto */
- { 60, "ku"}, /* Kurdish */
- { 61, "ks"}, /* Kashmiri */
- { 62, "sd"}, /* Sindhi */
- { 63, "bo"}, /* Tibetan */
- { 64, "ne"}, /* Nepali */
- { 65, "sa"}, /* Sanskrit */
- { 66, "mr"}, /* Marathi */
- { 67, "bn"}, /* Bengali */
- { 68, "as"}, /* Assamese */
- { 69, "gu"}, /* Gujarati */
- { 70, "pa"}, /* Punjabi */
- { 71, "or"}, /* Oriya */
- { 72, "ml"}, /* Malayalam */
- { 73, "kn"}, /* Kannada */
- { 74, "ta"}, /* Tamil */
- { 75, "te"}, /* Telugu */
- { 76, "si"}, /* Sinhalese */
- { 77, "my"}, /* Burmese */
- { 78, "km"}, /* Khmer */
- { 79, "lo"}, /* Lao */
- { 80, "vi"}, /* Vietnamese */
- { 81, "id"}, /* Indonesian */
- { 82, "tl"}, /* Tagalog */
- { 83, "ms"}, /* Malay (Roman script) */
- { 84, "ms"}, /* Malay (Arabic script) */
- { 85, "am"}, /* Amharic */
- { 86, "ti"}, /* Tigrinya */
- { 87, "om"}, /* Galla */
- { 88, "so"}, /* Somali */
- { 89, "sw"}, /* Swahili */
- { 90, "rw"}, /* Kinyarwanda/Ruanda */
- { 91, "rn"}, /* Rundi */
- { 92, "ny"}, /* Nyanja/Chewa */
- { 93, "mg"}, /* Malagasy */
- { 94, "eo"}, /* Esperanto */
- {128, "cy"}, /* Welsh */
- {129, "eu"}, /* Basque */
- {130, "ca"}, /* Catalan */
- {131, "la"}, /* Latin */
- {132, "qu"}, /* Quechua */
- {133, "gn"}, /* Guarani */
- {134, "ay"}, /* Aymara */
- {135, "tt"}, /* Tatar */
- {136, "ug"}, /* Uighur */
- {137, "dz"}, /* Dzongkha */
- {138, "jw"}, /* Javanese (Roman script) */
- {139, "su"}, /* Sundanese (Roman script) */
- {140, "gl"}, /* Galician */
- {141, "af"}, /* Afrikaans */
- {142, "br"}, /* Breton */
- {143, "iu"}, /* Inuktitut */
- {144, "gd"}, /* Scottish Gaelic */
- {145, "gv"}, /* Manx Gaelic */
- {146, "ga"}, /* Irish Gaelic (with dot above) */
- {147, "to"}, /* Tongan */
- {148, "el"}, /* Greek (polytonic) */
- {149, "ik"}, /* Greenlandic */
- {150, "az"}, /* Azerbaijani (Roman script) */
-};
-
-
-static hb_language_t
-_hb_ot_name_language_for (unsigned int code,
- const hb_ot_language_map_t *array,
- unsigned int len)
-{
-#ifdef HB_NO_OT_NAME_LANGUAGE
- return HB_LANGUAGE_INVALID;
-#endif
- auto *entry = hb_bsearch (code, array, len);
-
- if (entry)
- return hb_language_from_string (entry->lang, -1);
-
- return HB_LANGUAGE_INVALID;
-}
-
-hb_language_t
-_hb_ot_name_language_for_ms_code (unsigned int code)
-{
- return _hb_ot_name_language_for (code,
- _hb_ms_language_map,
- ARRAY_LENGTH (_hb_ms_language_map));
-}
-
-hb_language_t
-_hb_ot_name_language_for_mac_code (unsigned int code)
-{
- return _hb_ot_name_language_for (code,
- _hb_mac_language_map,
- ARRAY_LENGTH (_hb_mac_language_map));
-}
-
-#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language.hh
deleted file mode 100644
index 903076c0d56..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-language.hh
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2018 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_NAME_LANGUAGE_HH
-#define HB_OT_NAME_LANGUAGE_HH
-
-#include "hb.hh"
-
-
-HB_INTERNAL hb_language_t
-_hb_ot_name_language_for_ms_code (unsigned int code);
-
-HB_INTERNAL hb_language_t
-_hb_ot_name_language_for_mac_code (unsigned int code);
-
-
-#endif /* HB_OT_NAME_LANGUAGE_HH */
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 85653224cc7..4c5b3c0f986 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -27,6 +27,112 @@
#ifndef HB_OT_NAME_TABLE_HH
#define HB_OT_NAME_TABLE_HH
-#include "OT/name/name.hh"
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * name -- The Naming Table
+ */
+
+#define HB_OT_TAG_name HB_TAG('n','a','m','e')
+
+
+struct NameRecord
+{
+ 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;
+ ret = b->encodingID.cmp (a->encodingID);
+ if (ret) return ret;
+ ret = b->languageID.cmp (a->languageID);
+ if (ret) return ret;
+ ret = b->nameID.cmp (a->nameID);
+ if (ret) return ret;
+ return 0;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ /* We can check from base all the way up to the end of string... */
+ return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
+ }
+
+ 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);
+};
+
+struct name
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_name;
+
+ inline unsigned int get_name (unsigned int platform_id,
+ unsigned int encoding_id,
+ unsigned int language_id,
+ unsigned int name_id,
+ void *buffer,
+ unsigned int buffer_length) const
+ {
+ NameRecord key;
+ key.platformID.set (platform_id);
+ 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]), NameRecord::cmp);
+
+ if (!match)
+ return 0;
+
+ unsigned int length = MIN (buffer_length, (unsigned int) match->length);
+ memcpy (buffer, (char *) this + stringOffset + match->offset, length);
+ return length;
+ }
+
+ inline unsigned int get_size (void) const
+ { return min_size + count * nameRecord[0].min_size; }
+
+ inline bool sanitize_records (hb_sanitize_context_t *c) const {
+ TRACE_SANITIZE (this);
+ char *string_pool = (char *) this + stringOffset;
+ unsigned int _count = count;
+ for (unsigned int i = 0; i < _count; i++)
+ if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ likely (format == 0 || format == 1) &&
+ c->check_array (nameRecord, nameRecord[0].static_size, count) &&
+ sanitize_records (c));
+ }
+
+ /* We only implement format 0 for now. */
+ 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);
+};
+
+
+} /* namespace OT */
+
#endif /* HB_OT_NAME_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc
deleted file mode 100644
index 6adf1e8fbea..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright © 2018 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.hh"
-
-#ifndef HB_NO_NAME
-
-#include "hb-ot-name-table.hh"
-
-#include "hb-utf.hh"
-
-
-/**
- * SECTION:hb-ot-name
- * @title: hb-ot-name
- * @short_description: OpenType font name information
- * @include: hb-ot.h
- *
- * Functions for fetching name strings from OpenType fonts.
- **/
-
-
-/**
- * hb_ot_name_list_names:
- * @face: font face.
- * @num_entries: (out) (optional): number of returned entries.
- *
- * Enumerates all available name IDs and language combinations. Returned
- * array is owned by the @face and should not be modified. It can be
- * used as long as @face is alive.
- *
- * Returns: (transfer none) (array length=num_entries): Array of available name entries.
- * Since: 2.1.0
- **/
-const hb_ot_name_entry_t *
-hb_ot_name_list_names (hb_face_t *face,
- unsigned int *num_entries /* OUT */)
-{
- const OT::name_accelerator_t &name = *face->table.name;
- if (num_entries) *num_entries = name.names.length;
- return (const hb_ot_name_entry_t *) name.names;
-}
-
-template <typename utf_t>
-static inline unsigned int
-hb_ot_name_get_utf (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- typename utf_t::codepoint_t *text /* OUT */)
-{
- const OT::name_accelerator_t &name = *face->table.name;
-
- if (!language)
- language = hb_language_from_string ("en", 2);
-
- unsigned int width;
- int idx = name.get_index (name_id, language, &width);
- if (idx != -1)
- {
- hb_bytes_t bytes = name.get_name (idx);
-
- if (width == 2) /* UTF16-BE */
- return OT::hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text);
-
- if (width == 1) /* ASCII */
- return OT::hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text);
- }
-
- if (text_size)
- {
- if (*text_size)
- *text = 0;
- *text_size = 0;
- }
- return 0;
-}
-
-/**
- * hb_ot_name_get_utf8:
- * @face: font face.
- * @name_id: OpenType name identifier to fetch.
- * @language: language to fetch the name for.
- * @text_size: (inout) (optional): input size of @text buffer, and output size of
- * text written to buffer.
- * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
- *
- * Fetches a font name from the OpenType 'name' table.
- * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed.
- * Returns string in UTF-8 encoding. A NUL terminator is always written
- * for convenience, and isn't included in the output @text_size.
- *
- * Returns: full length of the requested string, or 0 if not found.
- * Since: 2.1.0
- **/
-unsigned int
-hb_ot_name_get_utf8 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- char *text /* OUT */)
-{
- return hb_ot_name_get_utf<hb_utf8_t> (face, name_id, language, text_size,
- (hb_utf8_t::codepoint_t *) text);
-}
-
-/**
- * hb_ot_name_get_utf16:
- * @face: font face.
- * @name_id: OpenType name identifier to fetch.
- * @language: language to fetch the name for.
- * @text_size: (inout) (optional): input size of @text buffer, and output size of
- * text written to buffer.
- * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
- *
- * Fetches a font name from the OpenType 'name' table.
- * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed.
- * Returns string in UTF-16 encoding. A NUL terminator is always written
- * for convenience, and isn't included in the output @text_size.
- *
- * Returns: full length of the requested string, or 0 if not found.
- * Since: 2.1.0
- **/
-unsigned int
-hb_ot_name_get_utf16 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- uint16_t *text /* OUT */)
-{
- return hb_ot_name_get_utf<hb_utf16_t> (face, name_id, language, text_size, text);
-}
-
-/**
- * hb_ot_name_get_utf32:
- * @face: font face.
- * @name_id: OpenType name identifier to fetch.
- * @language: language to fetch the name for.
- * @text_size: (inout) (optional): input size of @text buffer, and output size of
- * text written to buffer.
- * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
- *
- * Fetches a font name from the OpenType 'name' table.
- * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed.
- * Returns string in UTF-32 encoding. A NUL terminator is always written
- * for convenience, and isn't included in the output @text_size.
- *
- * Returns: full length of the requested string, or 0 if not found.
- * Since: 2.1.0
- **/
-unsigned int
-hb_ot_name_get_utf32 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- uint32_t *text /* OUT */)
-{
- return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h
deleted file mode 100644
index 03e664bb93f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi.
- *
- * 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.
- */
-
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb-ot.h> instead."
-#endif
-
-#ifndef HB_OT_NAME_H
-#define HB_OT_NAME_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-/**
- * hb_ot_name_id_predefined_t:
- * @HB_OT_NAME_ID_COPYRIGHT: Copyright notice
- * @HB_OT_NAME_ID_FONT_FAMILY: Font Family name
- * @HB_OT_NAME_ID_FONT_SUBFAMILY: Font Subfamily name
- * @HB_OT_NAME_ID_UNIQUE_ID: Unique font identifier
- * @HB_OT_NAME_ID_FULL_NAME: Full font name that reflects
- * all family and relevant subfamily descriptors
- * @HB_OT_NAME_ID_VERSION_STRING: Version string
- * @HB_OT_NAME_ID_POSTSCRIPT_NAME: PostScript name for the font
- * @HB_OT_NAME_ID_TRADEMARK: Trademark
- * @HB_OT_NAME_ID_MANUFACTURER: Manufacturer Name
- * @HB_OT_NAME_ID_DESIGNER: Designer
- * @HB_OT_NAME_ID_DESCRIPTION: Description
- * @HB_OT_NAME_ID_VENDOR_URL: URL of font vendor
- * @HB_OT_NAME_ID_DESIGNER_URL: URL of typeface designer
- * @HB_OT_NAME_ID_LICENSE: License Description
- * @HB_OT_NAME_ID_LICENSE_URL: URL where additional licensing
- * information can be found
- * @HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY: Typographic Family name
- * @HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY: Typographic Subfamily name
- * @HB_OT_NAME_ID_MAC_FULL_NAME: Compatible Full Name for MacOS
- * @HB_OT_NAME_ID_SAMPLE_TEXT: Sample text
- * @HB_OT_NAME_ID_CID_FINDFONT_NAME: PostScript CID findfont name
- * @HB_OT_NAME_ID_WWS_FAMILY: WWS Family Name
- * @HB_OT_NAME_ID_WWS_SUBFAMILY: WWS Subfamily Name
- * @HB_OT_NAME_ID_LIGHT_BACKGROUND: Light Background Palette
- * @HB_OT_NAME_ID_DARK_BACKGROUND: Dark Background Palette
- * @HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: Variations PostScript Name Prefix
- * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID.
- *
- * An enum type representing the pre-defined name IDs.
- *
- * For more information on these fields, see the
- * [OpenType spec](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).
- *
- * Since: 7.0.0
- **/
-typedef enum
-{
- HB_OT_NAME_ID_COPYRIGHT = 0,
- HB_OT_NAME_ID_FONT_FAMILY = 1,
- HB_OT_NAME_ID_FONT_SUBFAMILY = 2,
- HB_OT_NAME_ID_UNIQUE_ID = 3,
- HB_OT_NAME_ID_FULL_NAME = 4,
- HB_OT_NAME_ID_VERSION_STRING = 5,
- HB_OT_NAME_ID_POSTSCRIPT_NAME = 6,
- HB_OT_NAME_ID_TRADEMARK = 7,
- HB_OT_NAME_ID_MANUFACTURER = 8,
- HB_OT_NAME_ID_DESIGNER = 9,
- HB_OT_NAME_ID_DESCRIPTION = 10,
- HB_OT_NAME_ID_VENDOR_URL = 11,
- HB_OT_NAME_ID_DESIGNER_URL = 12,
- HB_OT_NAME_ID_LICENSE = 13,
- HB_OT_NAME_ID_LICENSE_URL = 14,
-/*HB_OT_NAME_ID_RESERVED = 15,*/
- HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY = 16,
- HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY = 17,
- HB_OT_NAME_ID_MAC_FULL_NAME = 18,
- HB_OT_NAME_ID_SAMPLE_TEXT = 19,
- HB_OT_NAME_ID_CID_FINDFONT_NAME = 20,
- HB_OT_NAME_ID_WWS_FAMILY = 21,
- HB_OT_NAME_ID_WWS_SUBFAMILY = 22,
- HB_OT_NAME_ID_LIGHT_BACKGROUND = 23,
- HB_OT_NAME_ID_DARK_BACKGROUND = 24,
- HB_OT_NAME_ID_VARIATIONS_PS_PREFIX = 25,
-
- HB_OT_NAME_ID_INVALID = 0xFFFF
-} hb_ot_name_id_predefined_t;
-
-/**
- * hb_ot_name_id_t:
- *
- * An integral type representing an OpenType 'name' table name identifier.
- * There are predefined name IDs, as well as name IDs return from other
- * API. These can be used to fetch name strings from a font face.
- *
- * Since: 2.0.0
- **/
-typedef unsigned int hb_ot_name_id_t;
-
-
-/**
- * hb_ot_name_entry_t:
- * @name_id: name ID
- * @language: language
- *
- * Structure representing a name ID in a particular language.
- *
- * Since: 2.1.0
- **/
-typedef struct hb_ot_name_entry_t {
- hb_ot_name_id_t name_id;
- /*< private >*/
- hb_var_int_t var;
- /*< public >*/
- hb_language_t language;
-} hb_ot_name_entry_t;
-
-HB_EXTERN const hb_ot_name_entry_t *
-hb_ot_name_list_names (hb_face_t *face,
- unsigned int *num_entries /* OUT */);
-
-
-HB_EXTERN unsigned int
-hb_ot_name_get_utf8 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- char *text /* OUT */);
-
-HB_EXTERN unsigned int
-hb_ot_name_get_utf16 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- uint16_t *text /* OUT */);
-
-HB_EXTERN unsigned int
-hb_ot_name_get_utf32 (hb_face_t *face,
- hb_ot_name_id_t name_id,
- hb_language_t language,
- unsigned int *text_size /* IN/OUT */,
- uint32_t *text /* OUT */);
-
-
-HB_END_DECLS
-
-#endif /* HB_OT_NAME_H */
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 97d18b9d75d..aa78f1e0a6b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh
@@ -1,6 +1,5 @@
/*
* Copyright © 2011,2012 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -28,357 +27,76 @@
#ifndef HB_OT_OS2_TABLE_HH
#define HB_OT_OS2_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-os2-unicode-ranges.hh"
-#include "hb-ot-var-mvar-table.hh"
+#include "hb-open-type-private.hh"
-#include "hb-set.hh"
+
+namespace OT {
/*
* OS/2 and Windows Metrics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/os2
+ * http://www.microsoft.com/typography/otspec/os2.htm
*/
-#define HB_OT_TAG_OS2 HB_TAG('O','S','/','2')
-
-
-namespace OT {
-
-struct OS2V1Tail
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
- public:
- HBUINT32 ulCodePageRange1;
- HBUINT32 ulCodePageRange2;
- public:
- DEFINE_SIZE_STATIC (8);
-};
+#define HB_OT_TAG_os2 HB_TAG('O','S','/','2')
-struct OS2V2Tail
+struct os2
{
- bool has_data () const { return sxHeight || sCapHeight; }
-
- const OS2V2Tail * operator -> () const { return this; }
- OS2V2Tail * operator -> () { return this; }
+ static const hb_tag_t tableTag = HB_OT_TAG_os2;
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
- HBINT16 sxHeight;
- HBINT16 sCapHeight;
- HBUINT16 usDefaultChar;
- HBUINT16 usBreakChar;
- HBUINT16 usMaxContext;
- public:
- DEFINE_SIZE_STATIC (10);
-};
-
-struct OS2V5Tail
-{
- inline bool get_optical_size (unsigned int *lower, unsigned int *upper) const
- {
- unsigned int lower_optical_size = usLowerOpticalPointSize;
- unsigned int upper_optical_size = usUpperOpticalPointSize;
-
- /* Per https://docs.microsoft.com/en-us/typography/opentype/spec/os2#lps */
- if (lower_optical_size < upper_optical_size &&
- lower_optical_size >= 1 && lower_optical_size <= 0xFFFE &&
- upper_optical_size >= 2 && upper_optical_size <= 0xFFFF)
- {
- *lower = lower_optical_size;
- *upper = upper_optical_size;
- return true;
- }
- return false;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBUINT16 usLowerOpticalPointSize;
- HBUINT16 usUpperOpticalPointSize;
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct OS2
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_OS2;
-
- bool has_data () const { return usWeightClass || usWidthClass || usFirstCharIndex || usLastCharIndex; }
-
- const OS2V1Tail &v1 () const { return version >= 1 ? v1X : Null (OS2V1Tail); }
- const OS2V2Tail &v2 () const { return version >= 2 ? v2X : Null (OS2V2Tail); }
- const OS2V5Tail &v5 () const { return version >= 5 ? v5X : Null (OS2V5Tail); }
-
- enum selection_flag_t {
- ITALIC = 1u<<0,
- UNDERSCORE = 1u<<1,
- NEGATIVE = 1u<<2,
- OUTLINED = 1u<<3,
- STRIKEOUT = 1u<<4,
- BOLD = 1u<<5,
- REGULAR = 1u<<6,
- USE_TYPO_METRICS = 1u<<7,
- WWS = 1u<<8,
- OBLIQUE = 1u<<9
- };
-
- bool is_italic () const { return fsSelection & ITALIC; }
- bool is_oblique () const { return fsSelection & OBLIQUE; }
- bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
-
- enum width_class_t {
- FWIDTH_ULTRA_CONDENSED = 1, /* 50% */
- FWIDTH_EXTRA_CONDENSED = 2, /* 62.5% */
- FWIDTH_CONDENSED = 3, /* 75% */
- FWIDTH_SEMI_CONDENSED = 4, /* 87.5% */
- FWIDTH_NORMAL = 5, /* 100% */
- FWIDTH_SEMI_EXPANDED = 6, /* 112.5% */
- FWIDTH_EXPANDED = 7, /* 125% */
- FWIDTH_EXTRA_EXPANDED = 8, /* 150% */
- FWIDTH_ULTRA_EXPANDED = 9 /* 200% */
- };
-
- float get_width () const
- {
- switch (usWidthClass) {
- case FWIDTH_ULTRA_CONDENSED:return 50.f;
- case FWIDTH_EXTRA_CONDENSED:return 62.5f;
- case FWIDTH_CONDENSED: return 75.f;
- case FWIDTH_SEMI_CONDENSED: return 87.5f;
- default:
- case FWIDTH_NORMAL: return 100.f;
- case FWIDTH_SEMI_EXPANDED: return 112.5f;
- case FWIDTH_EXPANDED: return 125.f;
- case FWIDTH_EXTRA_EXPANDED: return 150.f;
- case FWIDTH_ULTRA_EXPANDED: return 200.f;
- }
- }
-
- float map_wdth_to_widthclass(float width) const
- {
- if (width < 50) return 1.0f;
- if (width > 200) return 9.0f;
-
- float ratio = (width - 50) / 12.5f;
- int a = (int) floorf (ratio);
- int b = (int) ceilf (ratio);
-
- /* follow this maping:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass
- */
- if (b <= 6) // 50-125
- {
- if (a == b) return a + 1.0f;
- }
- else if (b == 7) // no mapping for 137.5
- {
- a = 6;
- b = 8;
- }
- else if (b == 8)
- {
- if (a == b) return 8.0f; // 150
- a = 6;
- }
- else
- {
- if (a == b && a == 12) return 9.0f; //200
- b = 12;
- a = 8;
- }
-
- float va = 50 + a * 12.5f;
- float vb = 50 + b * 12.5f;
-
- float ret = a + (width - va) / (vb - va);
- if (a <= 6) ret += 1.0f;
- return ret;
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- OS2 *os2_prime = c->serializer->embed (this);
- if (unlikely (!os2_prime)) return_trace (false);
-
-#ifndef HB_NO_VAR
- if (c->plan->normalized_coords)
- {
- auto &MVAR = *c->plan->source->table.MVAR;
- auto *table = os2_prime;
-
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, sTypoAscender);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, sTypoDescender);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, sTypoLineGap);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT, usWinAscent);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT, usWinDescent);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE, ySubscriptXSize);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE, ySubscriptYSize);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET, ySubscriptXOffset);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET, ySubscriptYOffset);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE, ySuperscriptXSize);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE, ySuperscriptYSize);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET, ySuperscriptXOffset);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET, ySuperscriptYOffset);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_STRIKEOUT_SIZE, yStrikeoutSize);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, yStrikeoutPosition);
-
- if (os2_prime->version >= 2)
- {
- auto *table = & const_cast<OS2V2Tail &> (os2_prime->v2 ());
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT, sxHeight);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT, sCapHeight);
- }
- }
-#endif
-
- if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) &&
- !c->plan->pinned_at_default)
- {
- float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t'));
- if (!c->serializer->check_assign (os2_prime->usWeightClass,
- roundf (hb_clamp (weight_class, 1.0f, 1000.0f)),
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- }
-
- if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) &&
- !c->plan->pinned_at_default)
- {
- float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h'));
- if (!c->serializer->check_assign (os2_prime->usWidthClass,
- roundf (map_wdth_to_widthclass (width)),
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
- }
-
- if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
- return_trace (true);
-
- os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ());
- os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ());
-
- _update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange);
-
- return_trace (true);
- }
-
- void _update_unicode_ranges (const hb_set_t *codepoints,
- HBUINT32 ulUnicodeRange[4]) const
- {
- HBUINT32 newBits[4];
- for (unsigned int i = 0; i < 4; i++)
- newBits[i] = 0;
-
- /* This block doesn't show up in profiles. If it ever did,
- * we can rewrite it to iterate over OS/2 ranges and use
- * set iteration to check if the range matches. */
- for (hb_codepoint_t cp = HB_SET_VALUE_INVALID;
- codepoints->next (&cp);)
- {
- unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
- if (bit < 128)
- {
- unsigned int block = bit / 32;
- unsigned int bit_in_block = bit % 32;
- unsigned int mask = 1 << bit_in_block;
- newBits[block] = newBits[block] | mask;
- }
- if (cp >= 0x10000 && cp <= 0x110000)
- {
- /* the spec says that bit 57 ("Non Plane 0") implies that there's
- at least one codepoint beyond the BMP; so I also include all
- the non-BMP codepoints here */
- newBits[1] = newBits[1] | (1 << 25);
- }
- }
-
- for (unsigned int i = 0; i < 4; i++)
- ulUnicodeRange[i] = ulUnicodeRange[i] & newBits[i]; // set bits only if set in the original
- }
-
- /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
- * https://docs.microsoft.com/en-us/typography/legacy/legacy_arabic_fonts */
- enum font_page_t
- {
- FONT_PAGE_NONE = 0,
- FONT_PAGE_HEBREW = 0xB100, /* Hebrew Windows 3.1 font page */
- FONT_PAGE_SIMP_ARABIC = 0xB200, /* Simplified Arabic Windows 3.1 font page */
- FONT_PAGE_TRAD_ARABIC = 0xB300, /* Traditional Arabic Windows 3.1 font page */
- FONT_PAGE_OEM_ARABIC = 0xB400, /* OEM Arabic Windows 3.1 font page */
- FONT_PAGE_SIMP_FARSI = 0xBA00, /* Simplified Farsi Windows 3.1 font page */
- FONT_PAGE_TRAD_FARSI = 0xBB00, /* Traditional Farsi Windows 3.1 font page */
- FONT_PAGE_THAI = 0xDE00 /* Thai Windows 3.1 font page */
- };
- font_page_t get_font_page () const
- { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
-
- unsigned get_size () const
- {
- unsigned result = min_size;
- if (version >= 1) result += v1X.get_size ();
- if (version >= 2) result += v2X.get_size ();
- if (version >= 5) result += v5X.get_size ();
- return result;
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this))) return_trace (false);
- if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false);
- if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false);
- if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false);
- return_trace (true);
- }
-
- public:
- HBUINT16 version;
- HBINT16 xAvgCharWidth;
- HBUINT16 usWeightClass;
- HBUINT16 usWidthClass;
- HBUINT16 fsType;
- HBINT16 ySubscriptXSize;
- HBINT16 ySubscriptYSize;
- HBINT16 ySubscriptXOffset;
- HBINT16 ySubscriptYOffset;
- HBINT16 ySuperscriptXSize;
- HBINT16 ySuperscriptYSize;
- HBINT16 ySuperscriptXOffset;
- HBINT16 ySuperscriptYOffset;
- HBINT16 yStrikeoutSize;
- HBINT16 yStrikeoutPosition;
- HBINT16 sFamilyClass;
- HBUINT8 panose[10];
- HBUINT32 ulUnicodeRange[4];
+ UINT16 version;
+
+ /* Version 0 */
+ 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;
- HBUINT16 fsSelection;
- HBUINT16 usFirstCharIndex;
- HBUINT16 usLastCharIndex;
- HBINT16 sTypoAscender;
- HBINT16 sTypoDescender;
- HBINT16 sTypoLineGap;
- HBUINT16 usWinAscent;
- HBUINT16 usWinDescent;
- OS2V1Tail v1X;
- OS2V2Tail v2X;
- OS2V5Tail v5X;
+ UINT16 fsSelection;
+ UINT16 usFirstCharIndex;
+ UINT16 usLastCharIndex;
+ INT16 sTypoAscender;
+ INT16 sTypoDescender;
+ INT16 sTypoLineGap;
+ UINT16 usWinAscent;
+ UINT16 usWinDescent;
+
+ /* Version 1 */
+ //UINT32 ulCodePageRange1;
+ //UINT32 ulCodePageRange2;
+
+ /* Version 2 */
+ //INT16 sxHeight;
+ //INT16 sCapHeight;
+ //UINT16 usDefaultChar;
+ //UINT16 usBreakChar;
+ //UINT16 usMaxContext;
+
+ /* Version 5 */
+ //UINT16 usLowerOpticalPointSize;
+ //UINT16 usUpperOpticalPointSize;
+
public:
- DEFINE_SIZE_MIN (78);
+ DEFINE_SIZE_STATIC (78);
};
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh
deleted file mode 100644
index 01e6a46e63d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-unicode-ranges.hh
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger
- */
-
-#ifndef HB_OT_OS2_UNICODE_RANGES_HH
-#define HB_OT_OS2_UNICODE_RANGES_HH
-
-#include "hb.hh"
-
-namespace OT {
-
-struct OS2Range
-{
- int cmp (hb_codepoint_t key) const
- { return (key < first) ? -1 : key <= last ? 0 : +1; }
-
- hb_codepoint_t first;
- hb_codepoint_t last;
- unsigned int bit;
-};
-
-/* Note: The contents of this array was generated using gen-os2-unicode-ranges.py. */
-static const OS2Range _hb_os2_unicode_ranges[] =
-{
- { 0x0, 0x7F, 0}, // Basic Latin
- { 0x80, 0xFF, 1}, // Latin-1 Supplement
- { 0x100, 0x17F, 2}, // Latin Extended-A
- { 0x180, 0x24F, 3}, // Latin Extended-B
- { 0x250, 0x2AF, 4}, // IPA Extensions
- { 0x2B0, 0x2FF, 5}, // Spacing Modifier Letters
- { 0x300, 0x36F, 6}, // Combining Diacritical Marks
- { 0x370, 0x3FF, 7}, // Greek and Coptic
- { 0x400, 0x4FF, 9}, // Cyrillic
- { 0x500, 0x52F, 9}, // Cyrillic Supplement
- { 0x530, 0x58F, 10}, // Armenian
- { 0x590, 0x5FF, 11}, // Hebrew
- { 0x600, 0x6FF, 13}, // Arabic
- { 0x700, 0x74F, 71}, // Syriac
- { 0x750, 0x77F, 13}, // Arabic Supplement
- { 0x780, 0x7BF, 72}, // Thaana
- { 0x7C0, 0x7FF, 14}, // NKo
- { 0x900, 0x97F, 15}, // Devanagari
- { 0x980, 0x9FF, 16}, // Bengali
- { 0xA00, 0xA7F, 17}, // Gurmukhi
- { 0xA80, 0xAFF, 18}, // Gujarati
- { 0xB00, 0xB7F, 19}, // Oriya
- { 0xB80, 0xBFF, 20}, // Tamil
- { 0xC00, 0xC7F, 21}, // Telugu
- { 0xC80, 0xCFF, 22}, // Kannada
- { 0xD00, 0xD7F, 23}, // Malayalam
- { 0xD80, 0xDFF, 73}, // Sinhala
- { 0xE00, 0xE7F, 24}, // Thai
- { 0xE80, 0xEFF, 25}, // Lao
- { 0xF00, 0xFFF, 70}, // Tibetan
- { 0x1000, 0x109F, 74}, // Myanmar
- { 0x10A0, 0x10FF, 26}, // Georgian
- { 0x1100, 0x11FF, 28}, // Hangul Jamo
- { 0x1200, 0x137F, 75}, // Ethiopic
- { 0x1380, 0x139F, 75}, // Ethiopic Supplement
- { 0x13A0, 0x13FF, 76}, // Cherokee
- { 0x1400, 0x167F, 77}, // Unified Canadian Aboriginal Syllabics
- { 0x1680, 0x169F, 78}, // Ogham
- { 0x16A0, 0x16FF, 79}, // Runic
- { 0x1700, 0x171F, 84}, // Tagalog
- { 0x1720, 0x173F, 84}, // Hanunoo
- { 0x1740, 0x175F, 84}, // Buhid
- { 0x1760, 0x177F, 84}, // Tagbanwa
- { 0x1780, 0x17FF, 80}, // Khmer
- { 0x1800, 0x18AF, 81}, // Mongolian
- { 0x1900, 0x194F, 93}, // Limbu
- { 0x1950, 0x197F, 94}, // Tai Le
- { 0x1980, 0x19DF, 95}, // New Tai Lue
- { 0x19E0, 0x19FF, 80}, // Khmer Symbols
- { 0x1A00, 0x1A1F, 96}, // Buginese
- { 0x1B00, 0x1B7F, 27}, // Balinese
- { 0x1B80, 0x1BBF, 112}, // Sundanese
- { 0x1C00, 0x1C4F, 113}, // Lepcha
- { 0x1C50, 0x1C7F, 114}, // Ol Chiki
- { 0x1D00, 0x1D7F, 4}, // Phonetic Extensions
- { 0x1D80, 0x1DBF, 4}, // Phonetic Extensions Supplement
- { 0x1DC0, 0x1DFF, 6}, // Combining Diacritical Marks Supplement
- { 0x1E00, 0x1EFF, 29}, // Latin Extended Additional
- { 0x1F00, 0x1FFF, 30}, // Greek Extended
- { 0x2000, 0x206F, 31}, // General Punctuation
- { 0x2070, 0x209F, 32}, // Superscripts And Subscripts
- { 0x20A0, 0x20CF, 33}, // Currency Symbols
- { 0x20D0, 0x20FF, 34}, // Combining Diacritical Marks For Symbols
- { 0x2100, 0x214F, 35}, // Letterlike Symbols
- { 0x2150, 0x218F, 36}, // Number Forms
- { 0x2190, 0x21FF, 37}, // Arrows
- { 0x2200, 0x22FF, 38}, // Mathematical Operators
- { 0x2300, 0x23FF, 39}, // Miscellaneous Technical
- { 0x2400, 0x243F, 40}, // Control Pictures
- { 0x2440, 0x245F, 41}, // Optical Character Recognition
- { 0x2460, 0x24FF, 42}, // Enclosed Alphanumerics
- { 0x2500, 0x257F, 43}, // Box Drawing
- { 0x2580, 0x259F, 44}, // Block Elements
- { 0x25A0, 0x25FF, 45}, // Geometric Shapes
- { 0x2600, 0x26FF, 46}, // Miscellaneous Symbols
- { 0x2700, 0x27BF, 47}, // Dingbats
- { 0x27C0, 0x27EF, 38}, // Miscellaneous Mathematical Symbols-A
- { 0x27F0, 0x27FF, 37}, // Supplemental Arrows-A
- { 0x2800, 0x28FF, 82}, // Braille Patterns
- { 0x2900, 0x297F, 37}, // Supplemental Arrows-B
- { 0x2980, 0x29FF, 38}, // Miscellaneous Mathematical Symbols-B
- { 0x2A00, 0x2AFF, 38}, // Supplemental Mathematical Operators
- { 0x2B00, 0x2BFF, 37}, // Miscellaneous Symbols and Arrows
- { 0x2C00, 0x2C5F, 97}, // Glagolitic
- { 0x2C60, 0x2C7F, 29}, // Latin Extended-C
- { 0x2C80, 0x2CFF, 8}, // Coptic
- { 0x2D00, 0x2D2F, 26}, // Georgian Supplement
- { 0x2D30, 0x2D7F, 98}, // Tifinagh
- { 0x2D80, 0x2DDF, 75}, // Ethiopic Extended
- { 0x2DE0, 0x2DFF, 9}, // Cyrillic Extended-A
- { 0x2E00, 0x2E7F, 31}, // Supplemental Punctuation
- { 0x2E80, 0x2EFF, 59}, // CJK Radicals Supplement
- { 0x2F00, 0x2FDF, 59}, // Kangxi Radicals
- { 0x2FF0, 0x2FFF, 59}, // Ideographic Description Characters
- { 0x3000, 0x303F, 48}, // CJK Symbols And Punctuation
- { 0x3040, 0x309F, 49}, // Hiragana
- { 0x30A0, 0x30FF, 50}, // Katakana
- { 0x3100, 0x312F, 51}, // Bopomofo
- { 0x3130, 0x318F, 52}, // Hangul Compatibility Jamo
- { 0x3190, 0x319F, 59}, // Kanbun
- { 0x31A0, 0x31BF, 51}, // Bopomofo Extended
- { 0x31C0, 0x31EF, 61}, // CJK Strokes
- { 0x31F0, 0x31FF, 50}, // Katakana Phonetic Extensions
- { 0x3200, 0x32FF, 54}, // Enclosed CJK Letters And Months
- { 0x3300, 0x33FF, 55}, // CJK Compatibility
- { 0x3400, 0x4DBF, 59}, // CJK Unified Ideographs Extension A
- { 0x4DC0, 0x4DFF, 99}, // Yijing Hexagram Symbols
- { 0x4E00, 0x9FFF, 59}, // CJK Unified Ideographs
- { 0xA000, 0xA48F, 83}, // Yi Syllables
- { 0xA490, 0xA4CF, 83}, // Yi Radicals
- { 0xA500, 0xA63F, 12}, // Vai
- { 0xA640, 0xA69F, 9}, // Cyrillic Extended-B
- { 0xA700, 0xA71F, 5}, // Modifier Tone Letters
- { 0xA720, 0xA7FF, 29}, // Latin Extended-D
- { 0xA800, 0xA82F, 100}, // Syloti Nagri
- { 0xA840, 0xA87F, 53}, // Phags-pa
- { 0xA880, 0xA8DF, 115}, // Saurashtra
- { 0xA900, 0xA92F, 116}, // Kayah Li
- { 0xA930, 0xA95F, 117}, // Rejang
- { 0xAA00, 0xAA5F, 118}, // Cham
- { 0xAC00, 0xD7AF, 56}, // Hangul Syllables
- { 0xD800, 0xDFFF, 57}, // Non-Plane 0 *
- { 0xE000, 0xF8FF, 60}, // Private Use Area (plane 0)
- { 0xF900, 0xFAFF, 61}, // CJK Compatibility Ideographs
- { 0xFB00, 0xFB4F, 62}, // Alphabetic Presentation Forms
- { 0xFB50, 0xFDFF, 63}, // Arabic Presentation Forms-A
- { 0xFE00, 0xFE0F, 91}, // Variation Selectors
- { 0xFE10, 0xFE1F, 65}, // Vertical Forms
- { 0xFE20, 0xFE2F, 64}, // Combining Half Marks
- { 0xFE30, 0xFE4F, 65}, // CJK Compatibility Forms
- { 0xFE50, 0xFE6F, 66}, // Small Form Variants
- { 0xFE70, 0xFEFF, 67}, // Arabic Presentation Forms-B
- { 0xFF00, 0xFFEF, 68}, // Halfwidth And Fullwidth Forms
- { 0xFFF0, 0xFFFF, 69}, // Specials
- { 0x10000, 0x1007F, 101}, // Linear B Syllabary
- { 0x10080, 0x100FF, 101}, // Linear B Ideograms
- { 0x10100, 0x1013F, 101}, // Aegean Numbers
- { 0x10140, 0x1018F, 102}, // Ancient Greek Numbers
- { 0x10190, 0x101CF, 119}, // Ancient Symbols
- { 0x101D0, 0x101FF, 120}, // Phaistos Disc
- { 0x10280, 0x1029F, 121}, // Lycian
- { 0x102A0, 0x102DF, 121}, // Carian
- { 0x10300, 0x1032F, 85}, // Old Italic
- { 0x10330, 0x1034F, 86}, // Gothic
- { 0x10380, 0x1039F, 103}, // Ugaritic
- { 0x103A0, 0x103DF, 104}, // Old Persian
- { 0x10400, 0x1044F, 87}, // Deseret
- { 0x10450, 0x1047F, 105}, // Shavian
- { 0x10480, 0x104AF, 106}, // Osmanya
- { 0x10800, 0x1083F, 107}, // Cypriot Syllabary
- { 0x10900, 0x1091F, 58}, // Phoenician
- { 0x10920, 0x1093F, 121}, // Lydian
- { 0x10A00, 0x10A5F, 108}, // Kharoshthi
- { 0x12000, 0x123FF, 110}, // Cuneiform
- { 0x12400, 0x1247F, 110}, // Cuneiform Numbers and Punctuation
- { 0x1D000, 0x1D0FF, 88}, // Byzantine Musical Symbols
- { 0x1D100, 0x1D1FF, 88}, // Musical Symbols
- { 0x1D200, 0x1D24F, 88}, // Ancient Greek Musical Notation
- { 0x1D300, 0x1D35F, 109}, // Tai Xuan Jing Symbols
- { 0x1D360, 0x1D37F, 111}, // Counting Rod Numerals
- { 0x1D400, 0x1D7FF, 89}, // Mathematical Alphanumeric Symbols
- { 0x1F000, 0x1F02F, 122}, // Mahjong Tiles
- { 0x1F030, 0x1F09F, 122}, // Domino Tiles
- { 0x20000, 0x2A6DF, 59}, // CJK Unified Ideographs Extension B
- { 0x2F800, 0x2FA1F, 61}, // CJK Compatibility Ideographs Supplement
- { 0xE0000, 0xE007F, 92}, // Tags
- { 0xE0100, 0xE01EF, 91}, // Variation Selectors Supplement
- { 0xF0000, 0xFFFFD, 90}, // Private Use (plane 15)
- {0x100000, 0x10FFFD, 90}, // Private Use (plane 16)
-};
-
-/**
- * _hb_ot_os2_get_unicode_range_bit:
- * Returns the bit to be set in os/2 ulUnicodeOS2Range for a given codepoint.
- **/
-static unsigned int
-_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
-{
- auto *range = hb_sorted_array (_hb_os2_unicode_ranges).bsearch (cp);
- return range ? range->bit : (unsigned) -1;
-}
-
-} /* namespace OT */
-
-#endif /* HB_OT_OS2_UNICODE_RANGES_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
index b4df8aaeeab..dbbb97e5a9f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
@@ -27,7 +27,7 @@
#ifndef HB_OT_POST_MACROMAN_HH
#if 0 /* Make checks happy. */
#define HB_OT_POST_MACROMAN_HH
-#include "hb.hh"
+#include "hb-private.hh"
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table-v2subset.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table-v2subset.hh
deleted file mode 100644
index 951e6395d6d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table-v2subset.hh
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright © 2021 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.
- *
- */
-
-#ifndef HB_OT_POST_TABLE_V2SUBSET_HH
-#define HB_OT_POST_TABLE_V2SUBSET_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-post-table.hh"
-
-/*
- * post -- PostScript
- * https://docs.microsoft.com/en-us/typography/opentype/spec/post
- */
-
-namespace OT {
-template<typename Iterator>
-HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c,
- Iterator it,
- const void* _post) const
-{
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!c->check_success (out))) return_trace (false);
- if (!out->glyphNameIndex.serialize (c, + it
- | hb_map (hb_second)))
- return_trace (false);
-
- hb_set_t copied_indices;
- for (const auto& _ : + it )
- {
- unsigned glyph_id = _.first;
- unsigned new_index = _.second;
-
- if (new_index < 258) continue;
- if (copied_indices.has (new_index)) continue;
- copied_indices.add (new_index);
-
- hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id);
- HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1));
- if (unlikely (!o)) return_trace (false);
- if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
- hb_memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length);
- }
-
- return_trace (true);
-}
-
-HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
-{
- TRACE_SUBSET (this);
-
- const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
- unsigned num_glyphs = c->plan->num_output_glyphs ();
- hb_map_t old_new_index_map, old_gid_new_index_map;
- unsigned i = 0;
-
- post::accelerator_t _post (c->plan->source);
-
- hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index;
- for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
- {
- hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
- unsigned old_index = glyphNameIndex[old_gid];
-
- unsigned new_index;
- const uint32_t *new_index2;
- if (old_index <= 257) new_index = old_index;
- else if (old_new_index_map.has (old_index, &new_index2))
- {
- new_index = *new_index2;
- } else {
- hb_bytes_t s = _post.find_glyph_name (old_gid);
- new_index = glyph_name_to_new_index.get (s);
- if (new_index == (unsigned)-1)
- {
- int standard_glyph_index = -1;
- for (unsigned i = 0; i < format1_names_length; i++)
- {
- if (s == format1_names (i))
- {
- standard_glyph_index = i;
- break;
- }
- }
-
- if (standard_glyph_index == -1)
- {
- new_index = 258 + i;
- i++;
- }
- else
- { new_index = standard_glyph_index; }
- glyph_name_to_new_index.set (s, new_index);
- }
- old_new_index_map.set (old_index, new_index);
- }
- old_gid_new_index_map.set (old_gid, new_index);
- }
-
- auto index_iter =
- + hb_range (num_glyphs)
- | hb_map (reverse_glyph_map)
- | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
- {
- unsigned new_index = old_gid_new_index_map.get (old_gid);
- return hb_pair_t<unsigned, unsigned> (old_gid, new_index);
- })
- ;
-
- return_trace (serialize (c->serializer, index_iter, &_post));
-}
-
-} /* namespace OT */
-#endif /* HB_OT_POST_TABLE_V2SUBSET_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 042fa611adf..7f1c2c420f1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh
@@ -27,8 +27,8 @@
#ifndef HB_OT_POST_TABLE_HH
#define HB_OT_POST_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-var-mvar-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"
@@ -36,172 +36,134 @@
#undef HB_STRING_ARRAY_LIST
#undef HB_STRING_ARRAY_NAME
+#define NUM_FORMAT1_NAMES 258
+
+namespace OT {
+
+
/*
* post -- PostScript
- * https://docs.microsoft.com/en-us/typography/opentype/spec/post
*/
-#define HB_OT_TAG_post HB_TAG('p','o','s','t')
-
-namespace OT {
+#define HB_OT_TAG_post HB_TAG('p','o','s','t')
struct postV2Tail
{
- friend struct post;
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (glyphNameIndex.sanitize (c));
}
- template<typename Iterator>
- bool serialize (hb_serialize_context_t *c,
- Iterator it,
- const void* _post) const;
-
- bool subset (hb_subset_context_t *c) const;
-
- protected:
- Array16Of<HBUINT16> glyphNameIndex; /* 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. */
-/*UnsizedArrayOf<HBUINT8>
- namesX;*/ /* Glyph names with length bytes [variable]
+ UINT8 namesX[VAR]; /* Glyph names with length bytes [variable]
* (a Pascal string). */
- public:
- DEFINE_SIZE_ARRAY (2, glyphNameIndex);
+ DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
};
struct post
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
-
- bool serialize (hb_serialize_context_t *c, bool glyph_names) const
- {
- TRACE_SERIALIZE (this);
- post *post_prime = c->allocate_min<post> ();
- if (unlikely (!post_prime)) return_trace (false);
-
- hb_memcpy (post_prime, this, post::min_size);
- if (!glyph_names)
- return_trace (c->check_assign (post_prime->version.major, 3,
- HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names.
+ static const hb_tag_t tableTag = HB_OT_TAG_post;
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
- TRACE_SUBSET (this);
- post *post_prime = c->serializer->start_embed<post> ();
- if (unlikely (!post_prime)) return_trace (false);
-
- bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
- if (!serialize (c->serializer, glyph_names))
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this)))
return_trace (false);
-
-#ifndef HB_NO_VAR
- if (c->plan->normalized_coords)
- {
- auto &MVAR = *c->plan->source->table.MVAR;
- auto *table = post_prime;
-
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_UNDERLINE_SIZE, underlineThickness);
- HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_UNDERLINE_OFFSET, underlinePosition);
- }
-#endif
-
- if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
- !c->plan->pinned_at_default)
+ if (version.to_int () == 0x00020000)
{
- float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t'));
- italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f));
- post_prime->italicAngle.set_float (italic_angle);
+ const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
+ return_trace (v2.sanitize (c));
}
-
- if (glyph_names && version.major == 2)
- return_trace (v2X.subset (c));
-
return_trace (true);
}
struct accelerator_t
{
- friend struct postV2Tail;
-
- accelerator_t (hb_face_t *face)
+ inline void init (hb_face_t *face)
{
- table = hb_sanitize_context_t ().reference_table<post> (face);
- unsigned int table_length = table.get_length ();
+ 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 ();
- if (version != 0x00020000) return;
+ index_to_offset.init ();
+ if (version != 0x00020000)
+ return;
- const postV2Tail &v2 = table->v2X;
+ const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
glyphNameIndex = &v2.glyphNameIndex;
pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
- const uint8_t *end = (const uint8_t *) (const void *) table + table_length;
- index_to_offset.alloc (hb_min (face->get_num_glyphs (), table_length / 8));
- for (const uint8_t *data = pool;
- index_to_offset.length < 65535 && data < end && data + *data < end;
- data += 1 + *data)
- index_to_offset.push (data - pool);
+ 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;
+ }
}
- ~accelerator_t ()
+ inline void fini (void)
{
- hb_free (gids_sorted_by_name.get_acquire ());
- table.destroy ();
+ index_to_offset.finish ();
+ free (gids_sorted_by_name);
}
- bool get_glyph_name (hb_codepoint_t glyph,
- char *buf, unsigned int buf_len) const
+ inline bool get_glyph_name (hb_codepoint_t glyph,
+ char *buf, unsigned int buf_len) const
{
- hb_bytes_t s = find_glyph_name (glyph);
- if (!s.length) return false;
- if (!buf_len) return true;
- unsigned int len = hb_min (buf_len - 1, s.length);
- strncpy (buf, s.arrayZ, len);
- buf[len] = '\0';
+ 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;
}
- bool get_glyph_from_name (const char *name, int len,
- hb_codepoint_t *glyph) const
+ 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 (unlikely (!count))
+ return false;
- if (len < 0) len = strlen (name);
+ if (len < 0)
+ len = strlen (name);
- if (unlikely (!len)) return false;
+ if (unlikely (!len))
+ return false;
retry:
- uint16_t *gids = gids_sorted_by_name.get_acquire ();
+ uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name);
if (unlikely (!gids))
{
- gids = (uint16_t *) hb_malloc (count * sizeof (gids[0]));
+ 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_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
+ hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
- if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids)))
- {
- hb_free (gids);
+ if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) {
+ free (gids);
goto retry;
}
}
- hb_bytes_t st (name, len);
- auto* gid = hb_bsearch (st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
+ 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;
@@ -211,22 +173,20 @@ struct post
return false;
}
- hb_blob_ptr_t<post> table;
-
protected:
- unsigned int get_glyph_count () const
+ inline unsigned int get_glyph_count (void) const
{
if (version == 0x00010000)
- return format1_names_length;
+ return NUM_FORMAT1_NAMES;
if (version == 0x00020000)
- return glyphNameIndex->len;
+ return glyphNameIndex->len;
return 0;
}
- static int cmp_gids (const void *pa, const void *pb, void *arg)
+ 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;
@@ -234,68 +194,58 @@ struct post
return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
}
- static int cmp_key (const void *pk, const void *po, void *arg)
+ static inline int cmp_key (const void *pk, const void *po, void *arg)
{
const accelerator_t *thiz = (const accelerator_t *) arg;
- const hb_bytes_t *key = (const hb_bytes_t *) pk;
+ 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);
}
- hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const
+ inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
{
if (version == 0x00010000)
{
- if (glyph >= format1_names_length)
- return hb_bytes_t ();
+ if (glyph >= NUM_FORMAT1_NAMES)
+ return hb_string_t ();
return format1_names (glyph);
}
if (version != 0x00020000 || glyph >= glyphNameIndex->len)
- return hb_bytes_t ();
+ return hb_string_t ();
- unsigned int index = glyphNameIndex->arrayZ[glyph];
- if (index < format1_names_length)
+ unsigned int index = glyphNameIndex->array[glyph];
+ if (index < NUM_FORMAT1_NAMES)
return format1_names (index);
- index -= format1_names_length;
+ index -= NUM_FORMAT1_NAMES;
- if (index >= index_to_offset.length)
- return hb_bytes_t ();
- unsigned int offset = index_to_offset[index];
+ 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_bytes_t ((const char *) data, name_length);
+ return hb_string_t ((const char *) data, name_length);
}
private:
+ hb_blob_t *blob;
uint32_t version;
- const Array16Of<HBUINT16> *glyphNameIndex = nullptr;
- hb_vector_t<uint32_t> index_to_offset;
- const uint8_t *pool = nullptr;
- hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
+ 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;
};
- bool has_data () const { return version.to_int (); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- (version.to_int () == 0x00010000 ||
- (version.to_int () == 0x00020000 && v2X.sanitize (c)) ||
- version.to_int () == 0x00030000));
- }
-
public:
FixedVersion<>version; /* 0x00010000 for version 1.0
* 0x00020000 for version 2.0
* 0x00025000 for version 2.5 (deprecated)
* 0x00030000 for version 3.0 */
- F16DOT16 italicAngle; /* Italic angle in counter-clockwise degrees
+ Fixed italicAngle; /* Italic angle in counter-clockwise degrees
* from the vertical. Zero for upright text,
* negative for text that leans to the right
* (forward). */
@@ -311,26 +261,21 @@ struct post
* from the value of this field. */
FWORD underlineThickness; /* Suggested values for the underline
thickness. */
- HBUINT32 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). */
- HBUINT32 minMemType42; /* Minimum memory usage when an OpenType font
+ UINT32 minMemType42; /* Minimum memory usage when an OpenType font
* is downloaded. */
- HBUINT32 maxMemType42; /* Maximum memory usage when an OpenType font
+ UINT32 maxMemType42; /* Maximum memory usage when an OpenType font
* is downloaded. */
- HBUINT32 minMemType1; /* Minimum memory usage when an OpenType font
+ UINT32 minMemType1; /* Minimum memory usage when an OpenType font
* is downloaded as a Type 1 font. */
- HBUINT32 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 v2X;
- DEFINE_SIZE_MIN (32);
+/*postV2Tail v2[VAR];*/
+ DEFINE_SIZE_STATIC (32);
};
-struct post_accelerator_t : post::accelerator_t {
- post_accelerator_t (hb_face_t *face) : post::accelerator_t (face) {}
-};
-
-
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-fallback.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
index e7a69008b72..d98cde121c4 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-fallback.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -24,21 +24,17 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPER_ARABIC_FALLBACK_HH
-#define HB_OT_SHAPER_ARABIC_FALLBACK_HH
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-ot-shape.hh"
+#include "hb-ot-shape-private.hh"
#include "hb-ot-layout-gsub-table.hh"
/* Features ordered the same as the entries in shaping_table rows,
- * followed by rlig. Don't change.
- *
- * We currently support one subtable per lookup, and one lookup
- * per feature. But we allow duplicate features, so we use that!
- */
+ * followed by rlig. Don't change. */
static const hb_tag_t arabic_fallback_features[] =
{
HB_TAG('i','n','i','t'),
@@ -46,8 +42,6 @@ static const hb_tag_t arabic_fallback_features[] =
HB_TAG('f','i','n','a'),
HB_TAG('i','s','o','l'),
HB_TAG('r','l','i','g'),
- HB_TAG('r','l','i','g'),
- HB_TAG('r','l','i','g'),
};
static OT::SubstLookup *
@@ -55,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
hb_font_t *font,
unsigned int feature_index)
{
- OT::HBGlyphID16 glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
- OT::HBGlyphID16 substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+ OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+ OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
unsigned int num_glyphs = 0;
/* Populate arrays */
@@ -72,8 +66,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
continue;
- glyphs[num_glyphs] = u_glyph;
- substitutes[num_glyphs] = s_glyph;
+ glyphs[num_glyphs].set (u_glyph);
+ substitutes[num_glyphs].set (s_glyph);
num_glyphs++;
}
@@ -83,43 +77,40 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
/* 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,
- (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::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);
/* Each glyph takes four bytes max, and there's some overhead. */
char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
- hb_serialize_context_t c (buf, sizeof (buf));
+ OT::hb_serialize_context_t c (buf, sizeof (buf));
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
bool ret = lookup->serialize_single (&c,
OT::LookupFlag::IgnoreMarks,
- hb_sorted_array (glyphs, num_glyphs),
- hb_array (substitutes, num_glyphs));
+ glyphs_supplier,
+ substitutes_supplier,
+ num_glyphs);
c.end_serialize ();
+ /* TODO sanitize the results? */
- return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr;
+ return ret ? c.copy<OT::SubstLookup> () : nullptr;
}
-template <typename T>
static OT::SubstLookup *
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font,
- const T &ligature_table,
- unsigned lookup_flags)
+ hb_font_t *font)
{
- OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
+ OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
unsigned int num_first_glyphs = 0;
- /* We know that all our ligatures have the same number of components. */
- OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
+ /* We know that all our ligatures are 2-component */
+ OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
- OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) *
- ARRAY_LENGTH_CONST (ligature_table[0].ligatures[0].components)];
+ OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
unsigned int num_ligatures = 0;
- unsigned int num_components = 0;
/* Populate arrays */
@@ -130,52 +121,33 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
hb_codepoint_t first_glyph;
if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
continue;
- first_glyphs[num_first_glyphs] = first_glyph;
+ first_glyphs[num_first_glyphs].set (first_glyph);
ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
num_first_glyphs++;
}
- hb_stable_sort (&first_glyphs[0], num_first_glyphs,
- (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::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++)
{
unsigned int first_glyph_idx = first_glyphs_indirection[i];
- for (unsigned int ligature_idx = 0; ligature_idx < ARRAY_LENGTH (ligature_table[0].ligatures); ligature_idx++)
+ for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
{
- hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].ligature;
- hb_codepoint_t ligature_glyph;
- if (!hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
+ hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
+ hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
+ hb_codepoint_t second_glyph, ligature_glyph;
+ if (!second_u ||
+ !hb_font_get_glyph (font, second_u, 0, &second_glyph) ||
+ !hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
continue;
- const auto &components = ligature_table[first_glyph_idx].ligatures[ligature_idx].components;
- unsigned component_count = ARRAY_LENGTH_CONST (components);
-
- bool matched = true;
- for (unsigned j = 0; j < component_count; j++)
- {
- hb_codepoint_t component_u = ligature_table[first_glyph_idx].ligatures[ligature_idx].components[j];
- hb_codepoint_t component_glyph;
- if (!component_u ||
- !hb_font_get_nominal_glyph (font, component_u, &component_glyph))
- {
- matched = false;
- break;
- }
-
- component_list[num_components++] = component_glyph;
- }
- if (!matched)
- continue;
-
- component_count_list[num_ligatures] = 1 + component_count;
- ligature_list[num_ligatures] = ligature_glyph;
-
ligature_per_first_glyph_count_list[i]++;
+ ligature_list[num_ligatures].set (ligature_glyph);
+ component_count_list[num_ligatures] = 2;
+ component_list[num_ligatures].set (second_glyph);
num_ligatures++;
}
}
@@ -183,21 +155,29 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
if (!num_ligatures)
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);
+ OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
+ OT::Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
+ OT::Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
/* 16 bytes per ligature ought to be enough... */
char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
- hb_serialize_context_t c (buf, sizeof (buf));
+ OT::hb_serialize_context_t c (buf, sizeof (buf));
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
bool ret = lookup->serialize_ligature (&c,
- lookup_flags,
- hb_sorted_array (first_glyphs, num_first_glyphs),
- hb_array (ligature_per_first_glyph_count_list, num_first_glyphs),
- hb_array (ligature_list, num_ligatures),
- hb_array (component_count_list, num_ligatures),
- hb_array (component_list, num_components));
+ OT::LookupFlag::IgnoreMarks,
+ first_glyphs_supplier,
+ ligature_per_first_glyph_count_supplier,
+ num_first_glyphs,
+ ligatures_supplier,
+ component_count_supplier,
+ component_supplier);
+
c.end_serialize ();
+ /* TODO sanitize the results? */
- return ret && !c.in_error () ? c.copy<OT::SubstLookup> () : nullptr;
+ return ret ? c.copy<OT::SubstLookup> () : nullptr;
}
static OT::SubstLookup *
@@ -208,51 +188,43 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
if (feature_index < 4)
return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
else
- {
- switch (feature_index) {
- case 4: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_3_table, OT::LookupFlag::IgnoreMarks);
- case 5: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_table, OT::LookupFlag::IgnoreMarks);
- case 6: return arabic_fallback_synthesize_lookup_ligature (plan, font, ligature_mark_table, 0);
- }
- }
- assert (false);
- return nullptr;
+ return arabic_fallback_synthesize_lookup_ligature (plan, font);
}
-#define ARABIC_FALLBACK_MAX_LOOKUPS ARRAY_LENGTH_CONST (arabic_fallback_features)
+#define ARABIC_FALLBACK_MAX_LOOKUPS 5
struct arabic_fallback_plan_t
{
+ ASSERT_POD ();
+
unsigned int num_lookups;
bool free_lookups;
hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
- OT::hb_ot_layout_lookup_accelerator_t *accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+ hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
};
-#if defined(_WIN32) && !defined(HB_NO_WIN1256)
+static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
#define HB_WITH_WIN1256
#endif
#ifdef HB_WITH_WIN1256
-#include "hb-ot-shaper-arabic-win1256.hh"
+#include "hb-ot-shape-complex-arabic-win1256.hh"
#endif
-struct ManifestLookup
-{
- public:
+struct ManifestLookup {
OT::Tag tag;
- OT::Offset16To<OT::SubstLookup> lookupOffset;
- public:
- DEFINE_SIZE_STATIC (6);
+ OT::OffsetTo<OT::SubstLookup> lookupOffset;
};
-typedef OT::Array16Of<ManifestLookup> Manifest;
+typedef OT::ArrayOf<ManifestLookup> Manifest;
static bool
-arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUSED,
- const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED)
+arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
+ const hb_ot_shape_plan_t *plan,
+ hb_font_t *font)
{
#ifdef HB_WITH_WIN1256
/* Does this font look like it's Windows-1256-encoded? */
@@ -265,8 +237,9 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
return false;
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
- static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) <=
- ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
+ static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
+ <= ARABIC_FALLBACK_MAX_LOOKUPS, "");
+ /* TODO sanitize the table? */
unsigned j = 0;
unsigned int count = manifest.len;
@@ -278,7 +251,7 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest+manifest[i].lookupOffset));
if (fallback_plan->lookup_array[j])
{
- fallback_plan->accel_array[j] = OT::hb_ot_layout_lookup_accelerator_t::create (*fallback_plan->lookup_array[j]);
+ fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
j++;
}
}
@@ -298,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)
{
- static_assert ((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++)
{
@@ -308,7 +281,7 @@ arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
if (fallback_plan->lookup_array[j])
{
- fallback_plan->accel_array[j] = OT::hb_ot_layout_lookup_accelerator_t::create (*fallback_plan->lookup_array[j]);
+ fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
j++;
}
}
@@ -324,9 +297,9 @@ static arabic_fallback_plan_t *
arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
hb_font_t *font)
{
- arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_calloc (1, sizeof (arabic_fallback_plan_t));
+ arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
if (unlikely (!fallback_plan))
- return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t));
+ return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
fallback_plan->num_lookups = 0;
fallback_plan->free_lookups = false;
@@ -341,26 +314,25 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
return fallback_plan;
- assert (fallback_plan->num_lookups == 0);
- hb_free (fallback_plan);
- return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t));
+ free (fallback_plan);
+ return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
}
static void
arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
{
- if (!fallback_plan || fallback_plan->num_lookups == 0)
+ if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
return;
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
if (fallback_plan->lookup_array[i])
{
- hb_free (fallback_plan->accel_array[i]);
+ fallback_plan->accel_array[i].fini ();
if (fallback_plan->free_lookups)
- hb_free (fallback_plan->lookup_array[i]);
+ free (fallback_plan->lookup_array[i]);
}
- hb_free (fallback_plan);
+ free (fallback_plan);
}
static void
@@ -368,16 +340,15 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- OT::hb_ot_apply_context_t c (0, font, buffer);
+ OT::hb_apply_context_t c (0, font, buffer);
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
if (fallback_plan->lookup_array[i]) {
c.set_lookup_mask (fallback_plan->mask_array[i]);
- if (fallback_plan->accel_array[i])
- hb_ot_layout_substitute_lookup (&c,
- *fallback_plan->lookup_array[i],
- *fallback_plan->accel_array[i]);
+ hb_ot_layout_substitute_lookup (&c,
+ *fallback_plan->lookup_array[i],
+ fallback_plan->accel_array[i]);
}
}
-#endif /* HB_OT_SHAPER_ARABIC_FALLBACK_HH */
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh
index a025b1a399c..fcedc7d7420 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh
@@ -26,12 +26,12 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPER_ARABIC_HH
-#define HB_OT_SHAPER_ARABIC_HH
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-ot-shaper.hh"
+#include "hb-ot-shape-complex-private.hh"
struct arabic_shape_plan_t;
@@ -47,4 +47,4 @@ setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
hb_buffer_t *buffer,
hb_script_t script);
-#endif /* HB_OT_SHAPER_ARABIC_HH */
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
index d7670f2f958..cd6e4058b56 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
@@ -6,26 +6,26 @@
*
* on files with these headers:
*
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58: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.
*/
-#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH
-#define HB_OT_SHAPER_ARABIC_TABLE_HH
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#define X JOINING_TYPE_X
+#define R JOINING_TYPE_R
+#define T JOINING_TYPE_T
+#define U JOINING_TYPE_U
#define A JOINING_GROUP_ALAPH
#define DR JOINING_GROUP_DALATH_RISH
+#define L JOINING_TYPE_L
#define C JOINING_TYPE_C
#define D JOINING_TYPE_D
-#define L JOINING_TYPE_L
-#define R JOINING_TYPE_R
-#define T JOINING_TYPE_T
-#define U JOINING_TYPE_U
-#define X JOINING_TYPE_X
static const uint8_t joining_table[] =
{
@@ -45,7 +45,7 @@ static const uint8_t joining_table[] =
/* Syriac */
- /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,T,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
+ /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
/* 0720 */ D,D,D,D,D,D,D,D,R,D,DR,D,R,D,D,DR,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* 0740 */ X,X,X,X,X,X,X,X,X,X,X,X,X,R,D,D,
@@ -71,21 +71,17 @@ 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,R,R,R,X,X,X,X,X,X,X,
+ /* 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,
/* Syriac Supplement */
- /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X,
-
- /* Arabic Extended-B */
-
- /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,
- /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+ /* 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 */
- /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,D,D,D,D,R,D,D,D,D,D,D,
- /* 08C0 */ D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+ /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,X,X,
+ /* 08C0 */ 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,
/* 08E0 */ X,X,U,
#define joining_offset_0x1806u 739
@@ -95,7 +91,7 @@ static const uint8_t joining_table[] =
/* 1800 */ U,D,X,X,C,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* 1820 */ 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,
/* 1840 */ 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,
- /* 1860 */ 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,X,X,X,X,X,X,X,
+ /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,
/* 1880 */ U,U,U,U,U,T,T,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,
/* 18A0 */ D,D,D,D,D,D,D,D,D,X,D,
@@ -129,48 +125,15 @@ static const uint8_t joining_table[] =
/* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U,
-#define joining_offset_0x10d00u 1146
-
- /* Hanifi Rohingya */
-
- /* 10D00 */ L,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,
- /* 10D20 */ D,D,R,D,
-
-#define joining_offset_0x10f30u 1182
-
- /* Sogdian */
-
- /* 10F20 */ D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D,
- /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R,X,X,X,X,X,X,X,X,X,X,X,
- /* 10F60 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
-
- /* Old Uyghur */
-
- /* 10F60 */ D,D,D,D,R,R,D,D,D,D,D,D,D,D,D,D,
- /* 10F80 */ D,D,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,
- /* 10FA0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
-
- /* Chorasmian */
-
- /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D,
- /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L,
-
-#define joining_offset_0x110bdu 1338
-
- /* Kaithi */
-
- /* 110A0 */ U,X,X,
- /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U,
-
-#define joining_offset_0x1e900u 1355
+#define joining_offset_0x1e900u 1146
/* Adlam */
/* 1E900 */ 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,
/* 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,X,X,X,X,X,X,X,T,
+ /* 1E940 */ D,D,D,D,
-}; /* Table items: 1431; occupancy: 57% */
+}; /* Table items: 1214; occupancy: 55% */
static unsigned int
@@ -197,16 +160,10 @@ joining_type (hb_codepoint_t u)
case 0x10u:
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];
- if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u];
- if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u];
- break;
-
- case 0x11u:
- if (hb_in_range<hb_codepoint_t> (u, 0x110BDu, 0x110CDu)) return joining_table[u - 0x110BDu + joining_offset_0x110bdu];
break;
case 0x1Eu:
- if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E94Bu)) 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:
@@ -215,15 +172,15 @@ joining_type (hb_codepoint_t u)
return X;
}
+#undef X
+#undef R
+#undef T
+#undef U
#undef A
#undef DR
+#undef L
#undef C
#undef D
-#undef L
-#undef R
-#undef T
-#undef U
-#undef X
static const uint16_t shaping_table[][4] =
@@ -416,141 +373,26 @@ static const uint16_t shaping_table[][4] =
static const struct ligature_set_t {
uint16_t first;
struct ligature_pairs_t {
- uint16_t components[1];
+ uint16_t second;
uint16_t ligature;
- } ligatures[14];
+ } ligatures[4];
} ligature_table[] =
{
- { 0xFE91u, {
- { {0xFEE2u}, 0xFC08u }, /* ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM */
- { {0xFEE4u}, 0xFC9Fu }, /* ARABIC LIGATURE BEH WITH MEEM INITIAL FORM */
- { {0xFEA0u}, 0xFC9Cu }, /* ARABIC LIGATURE BEH WITH JEEM INITIAL FORM */
- { {0xFEA4u}, 0xFC9Du }, /* ARABIC LIGATURE BEH WITH HAH INITIAL FORM */
- { {0xFEA8u}, 0xFC9Eu }, /* ARABIC LIGATURE BEH WITH KHAH INITIAL FORM */
- }},
- { 0xFE92u, {
- { {0xFEAEu}, 0xFC6Au }, /* ARABIC LIGATURE BEH WITH REH FINAL FORM */
- { {0xFEE6u}, 0xFC6Du }, /* ARABIC LIGATURE BEH WITH NOON FINAL FORM */
- { {0xFEF2u}, 0xFC6Fu }, /* ARABIC LIGATURE BEH WITH YEH FINAL FORM */
- }},
- { 0xFE97u, {
- { {0xFEE2u}, 0xFC0Eu }, /* ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM */
- { {0xFEE4u}, 0xFCA4u }, /* ARABIC LIGATURE TEH WITH MEEM INITIAL FORM */
- { {0xFEA0u}, 0xFCA1u }, /* ARABIC LIGATURE TEH WITH JEEM INITIAL FORM */
- { {0xFEA4u}, 0xFCA2u }, /* ARABIC LIGATURE TEH WITH HAH INITIAL FORM */
- { {0xFEA8u}, 0xFCA3u }, /* ARABIC LIGATURE TEH WITH KHAH INITIAL FORM */
- }},
- { 0xFE98u, {
- { {0xFEAEu}, 0xFC70u }, /* ARABIC LIGATURE TEH WITH REH FINAL FORM */
- { {0xFEE6u}, 0xFC73u }, /* ARABIC LIGATURE TEH WITH NOON FINAL FORM */
- { {0xFEF2u}, 0xFC75u }, /* ARABIC LIGATURE TEH WITH YEH FINAL FORM */
- }},
- { 0xFE9Bu, {
- { {0xFEE2u}, 0xFC12u }, /* ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM */
- }},
- { 0xFE9Fu, {
- { {0xFEE4u}, 0xFCA8u }, /* ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM */
- }},
- { 0xFEA3u, {
- { {0xFEE4u}, 0xFCAAu }, /* ARABIC LIGATURE HAH WITH MEEM INITIAL FORM */
- }},
- { 0xFEA7u, {
- { {0xFEE4u}, 0xFCACu }, /* ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM */
- }},
- { 0xFEB3u, {
- { {0xFEE4u}, 0xFCB0u }, /* ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM */
- }},
- { 0xFEB7u, {
- { {0xFEE4u}, 0xFD30u }, /* ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM */
- }},
- { 0xFED3u, {
- { {0xFEF2u}, 0xFC32u }, /* ARABIC LIGATURE FEH WITH YEH ISOLATED FORM */
- }},
{ 0xFEDFu, {
- { {0xFE9Eu}, 0xFC3Fu }, /* ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM */
- { {0xFEA0u}, 0xFCC9u }, /* ARABIC LIGATURE LAM WITH JEEM INITIAL FORM */
- { {0xFEA2u}, 0xFC40u }, /* ARABIC LIGATURE LAM WITH HAH ISOLATED FORM */
- { {0xFEA4u}, 0xFCCAu }, /* ARABIC LIGATURE LAM WITH HAH INITIAL FORM */
- { {0xFEA6u}, 0xFC41u }, /* ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM */
- { {0xFEA8u}, 0xFCCBu }, /* ARABIC LIGATURE LAM WITH KHAH INITIAL FORM */
- { {0xFEE2u}, 0xFC42u }, /* ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM */
- { {0xFEE4u}, 0xFCCCu }, /* ARABIC LIGATURE LAM WITH MEEM INITIAL FORM */
- { {0xFEF2u}, 0xFC44u }, /* ARABIC LIGATURE LAM WITH YEH ISOLATED FORM */
- { {0xFEECu}, 0xFCCDu }, /* ARABIC LIGATURE LAM WITH HEH INITIAL FORM */
- { {0xFE82u}, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
- { {0xFE84u}, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
- { {0xFE88u}, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
- { {0xFE8Eu}, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+ { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+ { 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+ { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+ { 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
}},
{ 0xFEE0u, {
- { {0xFEF0u}, 0xFC86u }, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM */
- { {0xFE82u}, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
- { {0xFE84u}, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
- { {0xFE88u}, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
- { {0xFE8Eu}, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
- }},
- { 0xFEE3u, {
- { {0xFEA0u}, 0xFCCEu }, /* ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM */
- { {0xFEA4u}, 0xFCCFu }, /* ARABIC LIGATURE MEEM WITH HAH INITIAL FORM */
- { {0xFEA8u}, 0xFCD0u }, /* ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM */
- { {0xFEE4u}, 0xFCD1u }, /* ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM */
- }},
- { 0xFEE7u, {
- { {0xFEE2u}, 0xFC4Eu }, /* ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM */
- { {0xFEE4u}, 0xFCD5u }, /* ARABIC LIGATURE NOON WITH MEEM INITIAL FORM */
- { {0xFEA0u}, 0xFCD2u }, /* ARABIC LIGATURE NOON WITH JEEM INITIAL FORM */
- { {0xFEA4u}, 0xFCD3u }, /* ARABIC LIGATURE NOON WITH HAH INITIAL FORM */
- }},
- { 0xFEE8u, {
- { {0xFEF2u}, 0xFC8Fu }, /* ARABIC LIGATURE NOON WITH YEH FINAL FORM */
- }},
- { 0xFEF3u, {
- { {0xFEA0u}, 0xFCDAu }, /* ARABIC LIGATURE YEH WITH JEEM INITIAL FORM */
- { {0xFEA4u}, 0xFCDBu }, /* ARABIC LIGATURE YEH WITH HAH INITIAL FORM */
- { {0xFEA8u}, 0xFCDCu }, /* ARABIC LIGATURE YEH WITH KHAH INITIAL FORM */
- { {0xFEE4u}, 0xFCDDu }, /* ARABIC LIGATURE YEH WITH MEEM INITIAL FORM */
- }},
- { 0xFEF4u, {
- { {0xFEAEu}, 0xFC91u }, /* ARABIC LIGATURE YEH WITH REH FINAL FORM */
- { {0xFEE6u}, 0xFC94u }, /* ARABIC LIGATURE YEH WITH NOON FINAL FORM */
- }},
-};
-
-
-static const struct ligature_mark_set_t {
- uint16_t first;
- struct ligature_pairs_t {
- uint16_t components[1];
- uint16_t ligature;
- } ligatures[5];
-} ligature_mark_table[] =
-{
- { 0x0651u, {
- { {0x064Cu}, 0xFC5Eu }, /* ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM */
- { {0x064Eu}, 0xFC60u }, /* ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM */
- { {0x064Fu}, 0xFC61u }, /* ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM */
- { {0x0650u}, 0xFC62u }, /* ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM */
- { {0x064Bu}, 0xF2EEu }, /* PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM */
- }},
-};
-
-
-static const struct ligature_3_set_t {
- uint16_t first;
- struct ligature_triplets_t {
- uint16_t components[2];
- uint16_t ligature;
- } ligatures[3];
-} ligature_3_table[] =
-{
- { 0xFEDFu, {
- { {0xFEE4u, 0xFEA4u}, 0xFD88u}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM */
- { {0xFEE0u, 0xFEEAu}, 0xF201u}, /* PUA ARABIC LIGATURE LELLAH ISOLATED FORM */
- { {0xFEE4u, 0xFEA0u}, 0xF211u}, /* PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM */
+ { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+ { 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+ { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+ { 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
}},
};
-#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-win1256.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh
index b8d481c8134..54c6cdc24f1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-win1256.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPER_ARABIC_WIN1256_HH
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
/*
@@ -87,8 +87,6 @@
#define OT_GLYPHID /* GlyphID */ \
OT_UINT16
-/* Shorthand. */
-#define G OT_GLYPHID
#define OT_UARRAY(Name, Items) \
OT_LABEL_START(Name) \
@@ -144,7 +142,7 @@
OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
) \
OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
- /* static_assert_expr (len(FromGlyphs) == len(ToGlyphs)) */
+ /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */
#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
OT_SUBLOOKUP(Name, 1, \
@@ -153,7 +151,7 @@
OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
) \
OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
- /* static_assert_expr (len(FirstGlyphs) == len(LigatureSetOffsets)) */
+ /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */
#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))
@@ -185,6 +183,8 @@
Tag \
OT_OFFSET(manifest, Name)
+/* Shorthand. */
+#define G OT_GLYPHID
/*
* Table Start
@@ -300,50 +300,24 @@ OT_TABLE_END
/*
* Clean up
*/
-
-#undef MANIFEST
-#undef MANIFEST_LOOKUP
-
#undef OT_TABLE_START
#undef OT_TABLE_END
#undef OT_LABEL_START
#undef OT_LABEL_END
#undef OT_UINT8
#undef OT_UINT16
-#undef OT_COUNT
#undef OT_DISTANCE
-
-#undef OT_LABEL
-#undef OT_LIST
-
-#undef OT_TAG
-#undef OT_OFFSET
-#undef OT_GLYPHID
-#undef G
-#undef OT_UARRAY
-#undef OT_UHEADLESSARRAY
-
-#undef OT_LOOKUP_FLAG_IGNORE_MARKS
-#undef OT_LOOKUP
-#undef OT_SUBLOOKUP
-#undef OT_COVERAGE1
-#undef OT_LOOKUP_TYPE_SUBST_SINGLE
-#undef OT_LOOKUP_TYPE_SUBST_LIGATURE
-#undef OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2
-#undef OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1
-#undef OT_LIGATURE_SET
-#undef OT_LIGATURE
-
+#undef OT_COUNT
/*
* Include a second time to get the table data...
*/
#if 0
-#include "hb.hh" /* Make check-includes.sh happy. */
+#include "hb-private.hh" /* Make check-includes.sh happy. */
#endif
#ifdef OT_MEASURE
-#include "hb-ot-shaper-arabic-win1256.hh"
+#include "hb-ot-shape-complex-arabic-win1256.hh"
#endif
-#define HB_OT_SHAPER_ARABIC_WIN1256_HH
-#endif /* HB_OT_SHAPER_ARABIC_WIN1256_HH */
+#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index 256f8f1d14e..eb9d36ff1d5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -24,18 +24,16 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-arabic.hh"
-#include "hb-ot-shape.hh"
+#include "hb-private.hh"
+#include "hb-debug.hh"
+#include "hb-ot-shape-complex-arabic-private.hh"
+#include "hb-ot-shape-private.hh"
/* buffer var allocations */
-#define arabic_shaping_action() ot_shaper_var_u8_auxiliary() /* arabic shaping action */
+#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
-#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_SHAPER0
+#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
/* See:
* https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
@@ -81,7 +79,7 @@ enum hb_arabic_joining_type_t {
JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */
};
-#include "hb-ot-shaper-arabic-table.hh"
+#include "hb-ot-shape-complex-arabic-table.hh"
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
{
@@ -161,25 +159,21 @@ static const struct arabic_state_table_entry {
};
-static bool
+static void
+nuke_joiners (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static bool
+static void
record_stch (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
-static bool
-deallocate_buffer_var (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
- return false;
-}
-
static void
collect_features_arabic (hb_ot_shape_planner_t *plan)
{
@@ -202,44 +196,36 @@ 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);
- map->enable_feature (HB_TAG('s','t','c','h'));
+ map->add_global_bool_feature (HB_TAG('s','t','c','h'));
map->add_gsub_pause (record_stch);
- map->enable_feature (HB_TAG('c','c','m','p'), F_MANUAL_ZWJ);
- map->enable_feature (HB_TAG('l','o','c','l'), F_MANUAL_ZWJ);
+ 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 (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], F_MANUAL_ZWJ | (has_fallback ? F_HAS_FALLBACK : F_NONE));
+ map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
map->add_gsub_pause (nullptr);
}
- map->add_gsub_pause (deallocate_buffer_var);
-
- /* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script
- * however, it says a ZWJ should also mean "don't ligate". So we run
- * the main ligating features as MANUAL_ZWJ. */
-
- map->enable_feature (HB_TAG('r','l','i','g'), F_MANUAL_ZWJ | F_HAS_FALLBACK);
+ 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);
- map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ);
- /* https://github.com/harfbuzz/harfbuzz/issues/1573 */
- if (!map->has_feature (HB_TAG('r','c','l','t')))
- {
- map->add_gsub_pause (nullptr);
- map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ);
- }
-
- map->enable_feature (HB_TAG('l','i','g','a'), F_MANUAL_ZWJ);
- map->enable_feature (HB_TAG('c','l','i','g'), F_MANUAL_ZWJ);
+ /* 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
@@ -249,21 +235,23 @@ 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->enable_feature (HB_TAG('c','s','w','h'), F_MANUAL_ZWJ);
- map->enable_feature (HB_TAG('m','s','e','t'), F_MANUAL_ZWJ);
+ //map->add_global_bool_feature (HB_TAG('c','s','w','h'));
+ map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
-#include "hb-ot-shaper-arabic-fallback.hh"
+#include "hb-ot-shape-complex-arabic-fallback.hh"
struct arabic_shape_plan_t
{
+ ASSERT_POD ();
+
/* The "+ 1" in the next array is to accommodate for the "NONE" command,
* which is not an OpenType feature, but this simplifies the code by not
* having to do a "if (... < NONE) ..." and just rely on the fact that
* mask_array[NONE] == 0. */
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
- hb_atomic_ptr_t<arabic_fallback_plan_t> fallback_plan;
+ arabic_fallback_plan_t *fallback_plan;
unsigned int do_fallback : 1;
unsigned int has_stch : 1;
@@ -272,7 +260,7 @@ struct arabic_shape_plan_t
void *
data_create_arabic (const hb_ot_shape_plan_t *plan)
{
- arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) hb_calloc (1, sizeof (arabic_shape_plan_t));
+ arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
if (unlikely (!arabic_plan))
return nullptr;
@@ -282,7 +270,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan)
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
arabic_plan->do_fallback = arabic_plan->do_fallback &&
(FEATURE_IS_SYRIAC (arabic_features[i]) ||
- plan->map.needs_fallback (arabic_features[i]));
+ plan->map.needs_fallback (arabic_features[i]));
}
return arabic_plan;
@@ -295,7 +283,7 @@ data_destroy_arabic (void *data)
arabic_fallback_plan_destroy (arabic_plan->fallback_plan);
- hb_free (data);
+ free (data);
}
static void
@@ -303,7 +291,7 @@ arabic_joining (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
- unsigned int prev = UINT_MAX, state = 0;
+ unsigned int prev = (unsigned int) -1, state = 0;
/* Check pre-context */
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
@@ -329,24 +317,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 != UINT_MAX)
+ if (entry->prev_action != NONE && prev != (unsigned int) -1)
{
info[prev].arabic_shaping_action() = entry->prev_action;
- buffer->safe_to_insert_tatweel (prev, i + 1);
- }
- else
- {
- if (prev == UINT_MAX)
- {
- if (this_type >= JOINING_TYPE_R)
- buffer->unsafe_to_concat_from_outbuffer (0, i + 1);
- }
- else
- {
- if (this_type >= JOINING_TYPE_R ||
- (2 <= state && state <= 5) /* States that have a possible prev_action. */)
- buffer->unsafe_to_concat (prev, i + 1);
- }
+ buffer->unsafe_to_break (prev, i + 1);
}
info[i].arabic_shaping_action() = entry->curr_action;
@@ -363,15 +337,8 @@ arabic_joining (hb_buffer_t *buffer)
continue;
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
- if (entry->prev_action != NONE && prev != UINT_MAX)
- {
+ if (entry->prev_action != NONE && prev != (unsigned int) -1)
info[prev].arabic_shaping_action() = entry->prev_action;
- buffer->safe_to_insert_tatweel (prev, buffer->len);
- }
- else if (2 <= state && state <= 5) /* States that have a possible prev_action. */
- {
- buffer->unsafe_to_concat (prev, buffer->len);
- }
break;
}
}
@@ -383,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_ranges<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu)))
+ if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du)))
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
}
@@ -413,53 +380,60 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
}
-static bool
+
+static void
+nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ if (_hb_glyph_info_is_zwj (&info[i]))
+ _hb_glyph_info_flip_joiners (&info[i]);
+}
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
-#ifdef HB_NO_OT_SHAPER_ARABIC_FALLBACK
- return false;
-#endif
-
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->do_fallback)
- return false;
+ return;
retry:
- arabic_fallback_plan_t *fallback_plan = arabic_plan->fallback_plan;
+ arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
if (unlikely (!fallback_plan))
{
/* This sucks. We need a font to build the fallback plan... */
fallback_plan = arabic_fallback_plan_create (plan, font);
- if (unlikely (!arabic_plan->fallback_plan.cmpexch (nullptr, 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;
}
}
arabic_fallback_plan_shape (fallback_plan, font, buffer);
- return true;
}
/*
* Stretch feature: "stch".
* See example here:
- * https://docs.microsoft.com/en-us/typography/script-development/syriac
+ * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm
* We implement this in a generic way, such that the Arabic subtending
* marks can use it as well.
*/
-static bool
+static void
record_stch (const hb_ot_shape_plan_t *plan,
- hb_font_t *font HB_UNUSED,
+ hb_font_t *font,
hb_buffer_t *buffer)
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
if (!arabic_plan->has_stch)
- return false;
+ return;
/* 'stch' feature was just applied. Look for anything that multiplied,
* and record it for stch treatment later. Note that rtlm, frac, etc
@@ -475,11 +449,10 @@ record_stch (const hb_ot_shape_plan_t *plan,
info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
}
- return false;
}
static void
-apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
+apply_stch (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
@@ -497,9 +470,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
int sign = font->x_scale < 0 ? -1 : +1;
unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
- enum { MEASURE, CUT } /* step_t */;
+ typedef enum { MEASURE, CUT } step_t;
- for (unsigned int step = MEASURE; step <= CUT; step = step + 1)
+ for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1))
{
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
@@ -508,15 +481,15 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int j = new_len;
for (unsigned int i = count; i; i--)
{
- if (!hb_in_range<uint8_t> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
+ if (!hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
{
- if (step == CUT)
+ if (step == CUT)
{
--j;
info[j] = info[i - 1];
pos[j] = pos[i - 1];
}
- continue;
+ continue;
}
/* Yay, justification! */
@@ -529,7 +502,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int end = i;
while (i &&
- hb_in_range<uint8_t> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
+ hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
{
i--;
hb_position_t width = font->get_glyph_h_advance (info[i].codepoint);
@@ -547,7 +520,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int start = i;
unsigned int context = i;
while (context &&
- !hb_in_range<uint8_t> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) &&
+ !hb_in_range<unsigned> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) &&
(_hb_glyph_info_is_default_ignorable (&info[context - 1]) ||
HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_category (&info[context - 1]))))
{
@@ -556,9 +529,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
i++; // Don't touch i again.
- DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)",
+ DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%d,%d,%d)",
step == MEASURE ? "measuring" : "cutting", context, start, end);
- DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%u width %d", start - context, w_total);
+ 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);
@@ -574,10 +547,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
if (shortfall > 0 && n_repeating > 0)
{
- ++n_copies;
- hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
- if (excess > 0)
- extra_repeat_overlap = excess / (n_copies * n_repeating);
+ ++n_copies;
+ hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
+ if (excess > 0)
+ extra_repeat_overlap = excess / (n_copies * n_repeating);
}
if (step == MEASURE)
@@ -597,7 +570,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (info[k - 1].arabic_shaping_action() == STCH_REPEATING)
repeat += n_copies;
- DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u",
+ 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++)
{
@@ -617,7 +590,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (step == MEASURE)
{
if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
- break;
+ break;
}
else
{
@@ -634,9 +607,11 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
hb_font_t *font)
{
apply_stch (plan, buffer, font);
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
-/* https://www.unicode.org/reports/tr53/ */
+/* http://www.unicode.org/reports/tr53/tr53-1.pdf */
static hb_codepoint_t
modifier_combining_marks[] =
@@ -648,12 +623,6 @@ modifier_combining_marks[] =
0x06E3u, /* ARABIC SMALL LOW SEEN */
0x06E7u, /* ARABIC SMALL HIGH YEH */
0x06E8u, /* ARABIC SMALL HIGH NOON */
- 0x08CAu, /* ARABIC SMALL HIGH FARSI YEH */
- 0x08CBu, /* ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW */
- 0x08CDu, /* ARABIC SMALL HIGH ZAH */
- 0x08CEu, /* ARABIC LARGE ROUND DOT ABOVE */
- 0x08CFu, /* ARABIC LARGE ROUND DOT BELOW */
- 0x08D3u, /* ARABIC SMALL LOW WAW */
0x08F3u, /* ARABIC SMALL HIGH WAW */
};
@@ -668,22 +637,20 @@ info_is_mcm (const hb_glyph_info_t &info)
}
static void
-reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+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;
- DEBUG_MSG (ARABIC, buffer, "Reordering marks from %u to %u", start, end);
-
unsigned int i = start;
for (unsigned int cc = 220; cc <= 230; cc += 10)
{
- DEBUG_MSG (ARABIC, buffer, "Looking for %u's starting at %u", cc, i);
+ 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 %u's stopped at %u", cc, i);
+ DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
if (i == end)
break;
@@ -691,49 +658,34 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan HB_UNUSED,
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_cc(info[j]) == cc && info_is_mcm (info[j]))
+ 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;
- DEBUG_MSG (ARABIC, buffer, "Found %u's from %u to %u", cc, i, j);
-
/* Shift it! */
- DEBUG_MSG (ARABIC, buffer, "Shifting %u's: %u %u", cc, i, j);
- hb_glyph_info_t temp[HB_OT_SHAPE_MAX_COMBINING_MARKS];
+ 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));
- /* Renumber CC such that the reordered sequence is still sorted.
- * 22 and 26 are chosen because they are smaller than all Arabic categories,
- * and are folded back to 220/230 respectively during fallback mark positioning.
- *
- * We do this because the CGJ-handling logic in the normalizer relies on
- * mark sequences having an increasing order even after this reordering.
- * https://github.com/harfbuzz/harfbuzz/issues/554
- * This, however, does break some obscure sequences, where the normalizer
- * might compose a sequence that it should not. For example, in the seequence
- * ALEF, HAMZAH, MADDAH, we should NOT try to compose ALEF+MADDAH, but with this
- * renumbering, we will.
- */
- unsigned int new_start = start + j - i;
- unsigned int new_cc = cc == 220 ? HB_MODIFIED_COMBINING_CLASS_CCC22 : HB_MODIFIED_COMBINING_CLASS_CCC26;
- while (start < new_start)
- {
- _hb_glyph_info_set_modified_combining_class (&info[start], new_cc);
- start++;
- }
+ start += j - i;
i = j;
}
}
-const hb_ot_shaper_t _hb_ot_shaper_arabic =
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
{
collect_features_arabic,
nullptr, /* override_features */
@@ -741,15 +693,12 @@ const hb_ot_shaper_t _hb_ot_shaper_arabic =
data_destroy_arabic,
nullptr, /* preprocess_text */
postprocess_glyphs_arabic,
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
nullptr, /* compose */
setup_masks_arabic,
+ nullptr, /* disable_otl */
reorder_marks_arabic,
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
index f0404a4d2c0..68a62a10d44 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-default.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
@@ -24,14 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-ot-shape-complex-private.hh"
-#ifndef HB_NO_OT_SHAPE
-#include "hb-ot-shaper.hh"
-
-
-const hb_ot_shaper_t _hb_ot_shaper_default =
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
{
nullptr, /* collect_features */
nullptr, /* override_features */
@@ -39,37 +35,12 @@ const hb_ot_shaper_t _hb_ot_shaper_default =
nullptr, /* data_destroy */
nullptr, /* preprocess_text */
nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
nullptr, /* compose */
nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
-
-#ifndef HB_NO_AAT_SHAPE
-/* Same as default but no mark advance zeroing / fallback positioning.
- * Dumbest shaper ever, basically. */
-const hb_ot_shaper_t _hb_ot_shaper_dumber =
-{
- nullptr, /* collect_features */
- nullptr, /* override_features */
- nullptr, /* data_create */
- nullptr, /* data_destroy */
- nullptr, /* preprocess_text */
- nullptr, /* postprocess_glyphs */
- nullptr, /* decompose */
- nullptr, /* compose */
- nullptr, /* setup_masks */
- nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
- false, /* fallback_position */
-};
-#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
index c90476bc468..7508c223c47 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hangul.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
@@ -24,11 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper.hh"
+#include "hb-ot-shape-complex-private.hh"
/* Hangul shaper */
@@ -60,7 +56,7 @@ collect_features_hangul (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
- map->add_feature (hangul_features[i]);
+ map->add_feature (hangul_features[i], 1, F_NONE);
}
static void
@@ -69,18 +65,20 @@ override_features_hangul (hb_ot_shape_planner_t *plan)
/* Uniscribe does not apply 'calt' for Hangul, and certain fonts
* (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
* in calt, which is not desirable. */
- plan->map.disable_feature (HB_TAG('c','a','l','t'));
+ plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
}
struct hangul_shape_plan_t
{
+ ASSERT_POD ();
+
hb_mask_t mask_array[HANGUL_FEATURE_COUNT];
};
static void *
data_create_hangul (const hb_ot_shape_plan_t *plan)
{
- hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) hb_calloc (1, sizeof (hangul_shape_plan_t));
+ hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
if (unlikely (!hangul_plan))
return nullptr;
@@ -93,7 +91,7 @@ data_create_hangul (const hb_ot_shape_plan_t *plan)
static void
data_destroy_hangul (void *data)
{
- hb_free (data);
+ free (data);
}
/* Constants for algorithmic hangul syllable [de]composition. */
@@ -119,7 +117,7 @@ data_destroy_hangul (void *data)
#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu))
/* buffer var allocations */
-#define hangul_shaping_feature() ot_shaper_var_u8_auxiliary() /* hangul jamo shaping feature */
+#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
static bool
is_zero_width_char (hb_font_t *font,
@@ -130,7 +128,7 @@ is_zero_width_char (hb_font_t *font,
}
static void
-preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
+preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
@@ -140,7 +138,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
*
* - LV can be precomposed, or decomposed. Lets call those
* <LV> and <L,V>,
- * - LVT can be fully precomposed, partially precomposed, or
+ * - LVT can be fully precomposed, partically precomposed, or
* fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
*
* The composition / decomposition is mechanical. However, not
@@ -153,8 +151,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
* - <V>: U+1160..11A7, U+D7B0..D7C7
* - <T>: U+11A8..11FF, U+D7CB..D7FB
*
- * - Only the <L,V> sequences for some of the U+11xx ranges combine.
- * - Only <LV,T> sequences for some of the Ts in U+11xx range combine.
+ * - Only the <L,V> sequences for the 11xx ranges combine.
+ * - Only <LV,T> sequences for T in U+11A8..11C3 combine.
*
* Here is what we want to accomplish in this shaper:
*
@@ -190,7 +188,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
*/
unsigned int count = buffer->len;
- for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
+ for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
{
hb_codepoint_t u = buffer->cur().codepoint;
@@ -204,8 +202,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
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);
- if (unlikely (!buffer->next_glyph ())) break;
+ buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
+ buffer->next_glyph ();
if (!is_zero_width_char (font, u))
{
buffer->merge_out_clusters (start, end + 1);
@@ -218,25 +216,22 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
else
{
/* No valid syllable as base for tone mark; try to insert dotted circle. */
- if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) &&
- font->has_glyph (0x25CCu))
+ if (font->has_glyph (0x25CCu))
{
hb_codepoint_t chars[2];
- if (!is_zero_width_char (font, u))
- {
+ if (!is_zero_width_char (font, u)) {
chars[0] = u;
chars[1] = 0x25CCu;
- } else
- {
+ } else {
chars[0] = 0x25CCu;
chars[1] = u;
}
- (void) buffer->replace_glyphs (1, 2, chars);
+ buffer->replace_glyphs (1, 2, chars);
}
else
{
/* No dotted circle available in the font; just leave tone mark untouched. */
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
}
start = end = buffer->out_len;
@@ -273,7 +268,9 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
if (font->has_glyph (s))
{
- (void) buffer->replace_glyphs (t ? 3 : 2, 1, &s);
+ buffer->replace_glyphs (t ? 3 : 2, 1, &s);
+ if (unlikely (buffer->in_error))
+ return;
end = start + 1;
continue;
}
@@ -285,19 +282,17 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
* Set jamo features on the individual glyphs, and advance past them.
*/
buffer->cur().hangul_shaping_feature() = LJMO;
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
buffer->cur().hangul_shaping_feature() = VJMO;
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
if (t)
{
buffer->cur().hangul_shaping_feature() = TJMO;
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
end = start + 3;
}
else
end = start + 2;
- if (unlikely (!buffer->successful))
- break;
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
buffer->merge_out_clusters (start, end);
continue;
@@ -323,7 +318,9 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t new_s = s + new_tindex;
if (font->has_glyph (new_s))
{
- (void) buffer->replace_glyphs (2, 1, &new_s);
+ buffer->replace_glyphs (2, 1, &new_s);
+ if (unlikely (buffer->in_error))
+ return;
end = start + 1;
continue;
}
@@ -347,31 +344,30 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
(!tindex || font->has_glyph (decomposed[2])))
{
unsigned int s_len = tindex ? 3 : 2;
- (void) buffer->replace_glyphs (1, s_len, decomposed);
+ buffer->replace_glyphs (1, s_len, decomposed);
+ if (unlikely (buffer->in_error))
+ return;
+
+ /* We decomposed S: apply jamo features to the individual glyphs
+ * that are now in buffer->out_info.
+ */
+ hb_glyph_info_t *info = buffer->out_info;
/* If we decomposed an LV because of a non-combining T following,
* we want to include this T in the syllable.
*/
if (has_glyph && !tindex)
{
- (void) buffer->next_glyph ();
- s_len++;
- }
- if (unlikely (!buffer->successful))
- break;
-
- /* We decomposed S: apply jamo features to the individual glyphs
- * that are now in buffer->out_info.
- */
- hb_glyph_info_t *info = buffer->out_info;
- end = start + s_len;
+ buffer->next_glyph ();
+ s_len++;
+ }
+ end = start + s_len;
unsigned int i = start;
info[i++].hangul_shaping_feature() = LJMO;
info[i++].hangul_shaping_feature() = VJMO;
if (i < end)
info[i++].hangul_shaping_feature() = TJMO;
-
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
buffer->merge_out_clusters (start, end);
continue;
@@ -382,17 +378,19 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (has_glyph)
{
- /* We didn't decompose the S, so just advance past it and fall through. */
+ /* We didn't decompose the S, so just advance past it. */
end = start + 1;
+ buffer->next_glyph ();
+ continue;
}
}
/* Didn't find a recognizable syllable, so we leave end <= start;
* this will prevent tone-mark reordering happening.
*/
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
- buffer->sync ();
+ buffer->swap_buffers ();
}
static void
@@ -414,7 +412,7 @@ setup_masks_hangul (const hb_ot_shape_plan_t *plan,
}
-const hb_ot_shaper_t _hb_ot_shaper_hangul =
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
{
collect_features_hangul,
override_features_hangul,
@@ -422,15 +420,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul =
data_destroy_hangul,
preprocess_text_hangul,
nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
nullptr, /* decompose */
nullptr, /* compose */
setup_masks_hangul,
+ nullptr, /* disable_otl */
nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hebrew.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
index e18edd6b3f2..34cf28b8e24 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-hebrew.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
@@ -24,11 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper.hh"
+#include "hb-ot-shape-complex-private.hh"
static bool
@@ -74,11 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
bool found = (bool) c->unicode->compose (a, b, ab);
-#ifdef HB_NO_OT_SHAPER_HEBREW_FALLBACK
- return found;
-#endif
-
- if (!found && !c->plan->has_gpos_mark)
+ if (!found && !c->plan->has_mark)
{
/* Special-case Hebrew presentation forms that are excluded from
* standard normalization, but wanted for old fonts. */
@@ -89,7 +81,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
found = true;
}
break;
- case 0x05B7u: /* PATAH */
+ case 0x05B7u: /* patah */
if (a == 0x05F2u) { /* YIDDISH YOD YOD */
*ab = 0xFB1Fu;
found = true;
@@ -162,34 +154,20 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
return found;
}
-static void
-reorder_marks_hebrew (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- unsigned int start,
- unsigned int end)
+static bool
+disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
{
- hb_glyph_info_t *info = buffer->info;
-
- for (unsigned i = start + 2; i < end; i++)
- {
- unsigned c0 = info_cc (info[i - 2]);
- unsigned c1 = info_cc (info[i - 1]);
- unsigned c2 = info_cc (info[i - 0]);
-
- if ((c0 == HB_MODIFIED_COMBINING_CLASS_CCC17 || c0 == HB_MODIFIED_COMBINING_CLASS_CCC18) /* patach or qamats */ &&
- (c1 == HB_MODIFIED_COMBINING_CLASS_CCC10 || c1 == HB_MODIFIED_COMBINING_CLASS_CCC14) /* sheva or hiriq */ &&
- (c2 == HB_MODIFIED_COMBINING_CLASS_CCC22 || c2 == HB_UNICODE_COMBINING_CLASS_BELOW) /* meteg or below */)
- {
- buffer->merge_clusters (i - 1, i + 1);
- hb_swap (info[i - 1], info[i]);
- break;
- }
- }
-
-
+ /* For Hebrew shaper, use fallback if GPOS does not have 'hebr'
+ * 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/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
+ */
+ return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r');
}
-const hb_ot_shaper_t _hb_ot_shaper_hebrew =
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
{
nullptr, /* collect_features */
nullptr, /* override_features */
@@ -197,15 +175,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hebrew =
nullptr, /* data_destroy */
nullptr, /* preprocess_text */
nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
compose_hebrew,
nullptr, /* setup_masks */
- reorder_marks_hebrew,
- HB_TAG ('h','e','b','r'), /* gpos_tag. https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+ disable_otl_hebrew,
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
-
-
-#endif
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
new file mode 100644
index 00000000000..7eaba4e4e7b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
@@ -0,0 +1,1566 @@
+
+#line 1 "hb-ot-shape-complex-indic-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-indic-machine.hh"
+static const unsigned char _indic_syllable_machine_trans_keys[] = {
+ 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
+ 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u,
+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u,
+ 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u,
+ 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
+ 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u,
+ 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
+ 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u,
+ 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
+ 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u,
+ 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
+ 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 5u, 8u, 4u, 14u, 4u, 14u, 5u, 8u,
+ 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, 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,
+ 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 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, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 17u, 3u, 17u, 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, 3u, 10u,
+ 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 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, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 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, 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, 3u, 10u, 5u, 10u, 3u, 10u,
+ 3u, 13u, 3u, 14u, 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, 14u, 1u, 16u,
+ 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
+ 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 3u, 17u, 4u, 14u,
+ 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, 3u, 10u, 5u, 10u, 3u, 10u,
+ 3u, 13u, 3u, 14u, 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, 14u, 1u, 16u,
+ 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
+ 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u,
+ 1u, 17u, 4u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u,
+ 5u, 10u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 3u, 17u, 3u, 17u, 1u, 16u,
+ 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, 1u, 16u, 0
+};
+
+static const char _indic_syllable_machine_key_spans[] = {
+ 1, 16, 6, 4, 3, 1, 4, 3,
+ 1, 4, 3, 1, 4, 3, 1, 5,
+ 1, 1, 5, 1, 1, 5, 1, 1,
+ 5, 1, 1, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 1, 16, 6,
+ 4, 3, 1, 4, 3, 1, 4, 3,
+ 1, 4, 3, 1, 5, 1, 1, 5,
+ 1, 1, 5, 1, 1, 5, 1, 1,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 1, 16, 6, 4, 3, 1,
+ 4, 3, 1, 4, 3, 1, 4, 3,
+ 1, 5, 1, 1, 5, 1, 1, 5,
+ 1, 1, 5, 1, 1, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 1, 16,
+ 6, 4, 3, 1, 4, 3, 1, 4,
+ 3, 1, 4, 3, 1, 5, 1, 1,
+ 5, 1, 1, 5, 1, 1, 5, 1,
+ 1, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 4, 11, 11, 4,
+ 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, 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,
+ 8, 6, 8, 11, 12, 12, 11, 10,
+ 12, 11, 10, 12, 11, 10, 12, 11,
+ 10, 12, 16, 11, 15, 15, 16, 16,
+ 16, 16, 16, 15, 15, 16, 16, 16,
+ 16, 16, 15, 15, 16, 16, 16, 16,
+ 16, 15, 15, 16, 16, 16, 16, 16,
+ 15, 15, 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, 8,
+ 6, 8, 11, 12, 12, 11, 10, 12,
+ 11, 10, 12, 11, 10, 12, 11, 10,
+ 12, 16, 11, 15, 15, 16, 16, 16,
+ 16, 16, 15, 15, 16, 16, 16, 16,
+ 16, 15, 15, 16, 16, 16, 16, 16,
+ 15, 15, 16, 16, 16, 16, 11, 16,
+ 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, 8, 6, 8,
+ 11, 12, 12, 11, 10, 12, 11, 10,
+ 12, 11, 10, 12, 11, 10, 12, 16,
+ 11, 15, 15, 16, 16, 16, 16, 16,
+ 15, 15, 16, 16, 16, 16, 16, 15,
+ 15, 16, 16, 16, 16, 16, 15, 15,
+ 16, 16, 16, 16, 16, 11, 15, 11,
+ 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, 8, 6, 8,
+ 11, 12, 12, 11, 10, 12, 11, 10,
+ 12, 11, 10, 12, 11, 10, 12, 16,
+ 11, 15, 15, 16, 16, 16, 16, 16,
+ 15, 15, 16, 16, 16, 16, 16, 15,
+ 15, 16, 16, 16, 16, 16, 15, 15,
+ 16, 16, 16, 16, 16, 15, 17, 15,
+ 17, 11, 6, 2, 1, 2, 2, 1,
+ 6, 16, 15, 15, 14, 15, 15, 16,
+ 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, 16
+};
+
+static const short _indic_syllable_machine_index_offsets[] = {
+ 0, 2, 19, 26, 31, 35, 37, 42,
+ 46, 48, 53, 57, 59, 64, 68, 70,
+ 76, 78, 80, 86, 88, 90, 96, 98,
+ 100, 106, 108, 110, 122, 134, 146, 158,
+ 170, 182, 194, 206, 218, 230, 232, 249,
+ 256, 261, 265, 267, 272, 276, 278, 283,
+ 287, 289, 294, 298, 300, 306, 308, 310,
+ 316, 318, 320, 326, 328, 330, 336, 338,
+ 340, 352, 364, 376, 388, 400, 412, 424,
+ 436, 448, 460, 462, 479, 486, 491, 495,
+ 497, 502, 506, 508, 513, 517, 519, 524,
+ 528, 530, 536, 538, 540, 546, 548, 550,
+ 556, 558, 560, 566, 568, 570, 582, 594,
+ 606, 618, 630, 642, 654, 666, 678, 680,
+ 697, 704, 709, 713, 715, 720, 724, 726,
+ 731, 735, 737, 742, 746, 748, 754, 756,
+ 758, 764, 766, 768, 774, 776, 778, 784,
+ 786, 788, 800, 812, 824, 836, 848, 860,
+ 872, 884, 896, 908, 920, 925, 937, 949,
+ 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, 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[] = {
+ 1, 0, 2, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 0, 1, 0, 0, 0, 0,
+ 4, 0, 5, 5, 6, 1, 0, 7,
+ 7, 6, 0, 6, 0, 8, 8, 9,
+ 1, 0, 10, 10, 9, 0, 9, 0,
+ 11, 11, 12, 1, 0, 13, 13, 12,
+ 0, 12, 0, 14, 14, 15, 1, 0,
+ 16, 16, 15, 0, 15, 0, 17, 0,
+ 0, 0, 1, 0, 18, 0, 19, 0,
+ 20, 14, 14, 15, 1, 0, 21, 0,
+ 22, 0, 23, 11, 11, 12, 1, 0,
+ 24, 0, 25, 0, 26, 8, 8, 9,
+ 1, 0, 27, 0, 28, 0, 29, 5,
+ 5, 6, 1, 0, 0, 0, 0, 0,
+ 29, 0, 29, 5, 5, 6, 1, 0,
+ 0, 0, 0, 30, 29, 0, 31, 5,
+ 5, 6, 1, 0, 0, 0, 0, 0,
+ 31, 0, 31, 5, 5, 6, 1, 0,
+ 0, 0, 0, 32, 31, 0, 33, 5,
+ 5, 6, 1, 0, 0, 0, 0, 0,
+ 33, 0, 33, 5, 5, 6, 1, 0,
+ 0, 0, 0, 34, 33, 0, 35, 5,
+ 5, 6, 1, 0, 0, 0, 0, 0,
+ 35, 0, 35, 5, 5, 6, 1, 0,
+ 0, 0, 0, 36, 35, 0, 37, 5,
+ 5, 6, 1, 0, 0, 0, 0, 0,
+ 37, 0, 37, 5, 5, 6, 1, 0,
+ 0, 0, 0, 38, 37, 0, 40, 39,
+ 41, 42, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 41,
+ 39, 40, 39, 39, 39, 39, 43, 39,
+ 44, 44, 45, 40, 39, 46, 46, 45,
+ 39, 45, 39, 47, 47, 48, 40, 39,
+ 49, 49, 48, 39, 48, 39, 50, 50,
+ 51, 40, 39, 52, 52, 51, 39, 51,
+ 39, 53, 53, 54, 40, 39, 55, 55,
+ 54, 39, 54, 39, 56, 39, 39, 39,
+ 40, 39, 57, 39, 58, 39, 59, 53,
+ 53, 54, 40, 39, 60, 39, 61, 39,
+ 62, 50, 50, 51, 40, 39, 63, 39,
+ 64, 39, 65, 47, 47, 48, 40, 39,
+ 66, 39, 67, 39, 68, 44, 44, 45,
+ 40, 39, 39, 39, 39, 39, 68, 39,
+ 68, 44, 44, 45, 40, 39, 39, 39,
+ 39, 69, 68, 39, 70, 44, 44, 45,
+ 40, 39, 39, 39, 39, 39, 70, 39,
+ 70, 44, 44, 45, 40, 39, 39, 39,
+ 39, 71, 70, 39, 72, 44, 44, 45,
+ 40, 39, 39, 39, 39, 39, 72, 39,
+ 72, 44, 44, 45, 40, 39, 39, 39,
+ 39, 73, 72, 39, 74, 44, 44, 45,
+ 40, 39, 39, 39, 39, 39, 74, 39,
+ 74, 44, 44, 45, 40, 39, 39, 39,
+ 39, 75, 74, 39, 76, 44, 44, 45,
+ 40, 39, 39, 39, 39, 39, 76, 39,
+ 76, 44, 44, 45, 40, 39, 39, 39,
+ 39, 77, 76, 39, 79, 78, 80, 81,
+ 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 80, 78, 79,
+ 78, 78, 78, 78, 82, 78, 83, 83,
+ 84, 79, 78, 86, 86, 84, 85, 84,
+ 85, 87, 87, 88, 79, 78, 89, 89,
+ 88, 78, 88, 78, 90, 90, 91, 79,
+ 78, 92, 92, 91, 78, 91, 78, 93,
+ 93, 94, 79, 78, 95, 95, 94, 78,
+ 94, 78, 96, 78, 78, 78, 79, 78,
+ 97, 78, 98, 78, 99, 93, 93, 94,
+ 79, 78, 100, 78, 101, 78, 102, 90,
+ 90, 91, 79, 78, 103, 78, 104, 78,
+ 105, 87, 87, 88, 79, 78, 106, 78,
+ 107, 78, 108, 83, 83, 84, 79, 78,
+ 78, 78, 78, 78, 108, 78, 108, 83,
+ 83, 84, 79, 78, 78, 78, 78, 109,
+ 108, 78, 110, 83, 83, 84, 79, 78,
+ 78, 78, 78, 78, 110, 78, 110, 83,
+ 83, 84, 79, 78, 78, 78, 78, 111,
+ 110, 78, 112, 83, 83, 84, 79, 78,
+ 78, 78, 78, 78, 112, 78, 112, 83,
+ 83, 84, 79, 78, 78, 78, 78, 113,
+ 112, 78, 114, 83, 83, 84, 79, 78,
+ 78, 78, 78, 78, 114, 78, 114, 83,
+ 83, 84, 79, 78, 78, 78, 78, 115,
+ 114, 78, 116, 83, 83, 84, 79, 78,
+ 78, 78, 78, 78, 116, 78, 118, 117,
+ 119, 120, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 119,
+ 117, 118, 117, 117, 117, 117, 121, 117,
+ 122, 122, 123, 118, 117, 124, 124, 123,
+ 117, 123, 117, 125, 125, 126, 118, 117,
+ 127, 127, 126, 117, 126, 117, 128, 128,
+ 129, 118, 117, 130, 130, 129, 117, 129,
+ 117, 131, 131, 132, 118, 117, 133, 133,
+ 132, 117, 132, 117, 134, 117, 117, 117,
+ 118, 117, 135, 117, 136, 117, 137, 131,
+ 131, 132, 118, 117, 138, 117, 139, 117,
+ 140, 128, 128, 129, 118, 117, 141, 117,
+ 142, 117, 143, 125, 125, 126, 118, 117,
+ 144, 117, 145, 117, 146, 122, 122, 123,
+ 118, 117, 117, 117, 117, 117, 146, 117,
+ 146, 122, 122, 123, 118, 117, 117, 117,
+ 117, 147, 146, 117, 148, 122, 122, 123,
+ 118, 117, 117, 117, 117, 117, 148, 117,
+ 148, 122, 122, 123, 118, 117, 117, 117,
+ 117, 149, 148, 117, 150, 122, 122, 123,
+ 118, 117, 117, 117, 117, 117, 150, 117,
+ 150, 122, 122, 123, 118, 117, 117, 117,
+ 117, 151, 150, 117, 152, 122, 122, 123,
+ 118, 117, 117, 117, 117, 117, 152, 117,
+ 152, 122, 122, 123, 118, 117, 117, 117,
+ 117, 153, 152, 117, 154, 122, 122, 123,
+ 118, 117, 117, 117, 117, 117, 154, 117,
+ 154, 122, 122, 123, 118, 117, 117, 117,
+ 117, 155, 154, 117, 116, 83, 83, 84,
+ 79, 78, 78, 78, 78, 156, 116, 78,
+ 86, 86, 84, 1, 0, 114, 83, 83,
+ 84, 157, 0, 0, 0, 0, 0, 114,
+ 0, 114, 83, 83, 84, 157, 0, 0,
+ 0, 0, 158, 114, 0, 159, 159, 160,
+ 1, 0, 7, 7, 160, 0, 161, 161,
+ 162, 157, 0, 163, 163, 162, 0, 162,
+ 0, 164, 164, 165, 157, 0, 166, 166,
+ 165, 0, 165, 0, 167, 167, 168, 157,
+ 0, 169, 169, 168, 0, 168, 0, 157,
+ 0, 170, 171, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 170, 0, 157, 0, 0, 0, 0, 172,
+ 0, 173, 0, 0, 0, 157, 0, 174,
+ 0, 175, 0, 176, 167, 167, 168, 157,
+ 0, 177, 0, 178, 0, 179, 164, 164,
+ 165, 157, 0, 180, 0, 181, 0, 182,
+ 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, 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[] = {
+ 178, 200, 207, 209, 210, 4, 213, 5,
+ 7, 216, 8, 10, 219, 11, 13, 222,
+ 14, 16, 17, 199, 19, 20, 221, 22,
+ 23, 218, 25, 26, 215, 224, 228, 232,
+ 235, 239, 242, 246, 249, 253, 256, 178,
+ 279, 286, 288, 289, 41, 292, 42, 44,
+ 295, 45, 47, 298, 48, 50, 301, 51,
+ 53, 54, 278, 56, 57, 300, 59, 60,
+ 297, 62, 63, 294, 303, 307, 311, 314,
+ 318, 321, 325, 328, 332, 336, 178, 357,
+ 364, 366, 367, 78, 370, 178, 79, 81,
+ 373, 82, 84, 376, 85, 87, 379, 88,
+ 90, 91, 356, 93, 94, 378, 96, 97,
+ 375, 99, 100, 372, 381, 385, 389, 392,
+ 396, 399, 403, 406, 410, 178, 437, 444,
+ 446, 447, 114, 450, 115, 117, 453, 118,
+ 120, 456, 121, 123, 459, 124, 126, 127,
+ 436, 129, 130, 458, 132, 133, 455, 135,
+ 136, 452, 461, 465, 469, 472, 476, 479,
+ 483, 486, 490, 493, 414, 498, 509, 152,
+ 512, 154, 515, 155, 157, 518, 158, 160,
+ 521, 161, 524, 526, 527, 166, 167, 523,
+ 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, 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[] = {
+ 1, 0, 2, 2, 2, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 2,
+ 0, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 3,
+ 0, 2, 2, 2, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 4, 0,
+ 2, 2, 2, 0, 2, 5, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 2, 6, 2, 6,
+ 2, 6, 2, 6, 2, 7, 0, 2,
+ 2, 2, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 6, 0, 8, 0,
+ 2, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 2, 2, 2, 0, 0, 2,
+ 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, 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, 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, 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, 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
+};
+
+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, 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, 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, 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,
+ 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, 0, 0, 0, 0, 0,
+ 0, 0, 10, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+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, 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, 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, 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,
+ 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, 0, 0, 0, 0, 0,
+ 0, 0, 11, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+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, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 79, 79, 79, 79, 86, 86,
+ 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 79, 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, 1, 1, 1,
+ 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;
+static const int indic_syllable_machine_first_final = 178;
+static const int indic_syllable_machine_error = -1;
+
+static const int indic_syllable_machine_en_main = 178;
+
+
+#line 36 "hb-ot-shape-complex-indic-machine.rl"
+
+
+
+#line 97 "hb-ot-shape-complex-indic-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 1384 "hb-ot-shape-complex-indic-machine.hh"
+ {
+ cs = indic_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 118 "hb-ot-shape-complex-indic-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 1401 "hb-ot-shape-complex-indic-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const short *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _indic_syllable_machine_from_state_actions[cs] ) {
+ case 11:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 1415 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+ _keys = _indic_syllable_machine_trans_keys + (cs<<1);
+ _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
+
+ _slen = _indic_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
+ ( info[p].indic_category()) <= _keys[1] ?
+ ( info[p].indic_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _indic_syllable_machine_trans_targs[_trans];
+
+ if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _indic_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 15:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (consonant_syllable); }}
+ break;
+ case 17:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (vowel_syllable); }}
+ break;
+ case 22:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (standalone_cluster); }}
+ break;
+ case 24:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (symbol_cluster); }}
+ break;
+ case 19:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (broken_cluster); }}
+ break;
+ case 12:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (non_indic_cluster); }}
+ break;
+ case 14:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (consonant_syllable); }}
+ break;
+ case 16:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (vowel_syllable); }}
+ break;
+ case 21:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (standalone_cluster); }}
+ break;
+ case 23:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (symbol_cluster); }}
+ break;
+ case 18:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+ case 20:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (non_indic_cluster); }}
+ break;
+ case 1:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
+ break;
+ case 3:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
+ break;
+ case 7:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
+ break;
+ case 9:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (symbol_cluster); }}
+ break;
+ case 4:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
+ break;
+ case 5:
+#line 1 "NONE"
+ { switch( act ) {
+ case 1:
+ {{p = ((te))-1;} found_syllable (consonant_syllable); }
+ break;
+ case 5:
+ {{p = ((te))-1;} found_syllable (broken_cluster); }
+ break;
+ case 6:
+ {{p = ((te))-1;} found_syllable (non_indic_cluster); }
+ break;
+ }
+ }
+ break;
+ case 8:
+#line 1 "NONE"
+ {te = p+1;}
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 1;}
+ break;
+ case 6:
+#line 1 "NONE"
+ {te = p+1;}
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 5;}
+ break;
+ case 13:
+#line 1 "NONE"
+ {te = p+1;}
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 6;}
+ break;
+#line 1538 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+_again:
+ switch ( _indic_syllable_machine_to_state_actions[cs] ) {
+ case 10:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 1547 "hb-ot-shape-complex-indic-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _indic_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 127 "hb-ot-shape-complex-indic-machine.rl"
+
+}
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
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
new file mode 100644
index 00000000000..a1e0d5266b4
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -0,0 +1,190 @@
+/*
+ * 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_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh" /* XXX Remove */
+
+
+#define INDIC_TABLE_ELEMENT_TYPE uint16_t
+
+/* Cateories used in the OpenType spec:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum indic_category_t {
+ OT_X = 0,
+ OT_C = 1,
+ OT_V = 2,
+ OT_N = 3,
+ OT_H = 4,
+ OT_ZWNJ = 5,
+ OT_ZWJ = 6,
+ OT_M = 7,
+ OT_SM = 8,
+ OT_VD = 9,
+ OT_A = 10,
+ OT_PLACEHOLDER = 11,
+ OT_DOTTEDCIRCLE = 12,
+ OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
+ OT_Coeng = 14, /* Khmer-style Virama. */
+ 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_CS = 19
+};
+
+#define MEDIAL_FLAGS (FLAG (OT_CM))
+
+/* Note:
+ *
+ * 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_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))
+
+
+/* Visual positions in a syllable from left to right. */
+enum indic_position_t {
+ POS_START,
+
+ POS_RA_TO_BECOME_REPH,
+ POS_PRE_M,
+ POS_PRE_C,
+
+ POS_BASE_C,
+ POS_AFTER_MAIN,
+
+ POS_ABOVE_C,
+
+ POS_BEFORE_SUB,
+ POS_BELOW_C,
+ POS_AFTER_SUB,
+
+ POS_BEFORE_POST,
+ POS_POST_C,
+ POS_AFTER_POST,
+
+ POS_FINAL_C,
+ POS_SMVD,
+
+ POS_END
+};
+
+/* Categories used in IndicSyllabicCategory.txt from UCD. */
+enum indic_syllabic_category_t {
+ INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
+
+ INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol,
+ INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* Don't care. */
+ INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER = OT_M, /* U+17CD only. */
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha,
+ 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_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,
+ INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ,
+ INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
+ INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER,
+ 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_SM,
+ INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
+ INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
+ INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
+};
+
+/* Categories used in IndicSMatraCategory.txt from UCD */
+enum indic_matra_category_t {
+ INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
+
+ INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
+ INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
+ INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
+ INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
+
+ /* These should resolve to the position of the last part of the split sequence. */
+ INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+
+ INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
+ INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
+};
+
+#define INDIC_COMBINE_CATEGORIES(S,M) \
+ ( \
+ ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
+ ( S | \
+ ( \
+ ( \
+ S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \
+ S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \
+ S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \
+ S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \
+ S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \
+ S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \
+ false \
+ ? M : INDIC_MATRA_CATEGORY_NOT_APPLICABLE \
+ ) << 8 \
+ ) \
+ ) \
+ )
+
+HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u);
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
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
new file mode 100644
index 00000000000..bfd1c6d3429
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
@@ -0,0 +1,486 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # 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 /* 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 /* 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 /* 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 /* 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 /* 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 /* 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 /* 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 /* 34 chars; Visarga */
+#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
+#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 /* 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 /* 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 */
+#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */
+#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */
+#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */
+
+#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
+
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
+
+
+#define indic_offset_0x0028u 0
+
+
+ /* Basic Latin */
+
+ /* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), _(x,x),
+ /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x00b0u 24
+
+
+ /* Latin-1 Supplement */
+
+ /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x),
+
+#define indic_offset_0x0900u 64
+
+
+ /* Devanagari */
+
+ /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,B), _(A,x), _(M,R), _(M,L),
+ /* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
+ /* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
+ /* 0950 */ _(x,x), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(M,T), _(M,B), _(M,B),
+ /* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+
+ /* Bengali */
+
+ /* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
+ /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
+ /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
+ /* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
+ /* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
+ /* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
+ /* 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), _(Bi,x), _(x,x), _(x,x), _(x,x),
+
+ /* Gurmukhi */
+
+ /* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
+ /* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
+ /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L),
+ /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
+ /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
+ /* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
+ /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0A70 */ _(Bi,T), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,B), _(x,x), _(x,x),
+ /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Gujarati */
+
+ /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
+ /* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
+ /* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
+ /* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
+ /* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 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), _(Ca,T), _(Ca,T), _(Ca,T), _(N,T), _(N,T), _(N,T),
+
+ /* Oriya */
+
+ /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
+ /* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
+ /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
+ /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
+ /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR),
+ /* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
+ /* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Tamil */
+
+ /* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
+ /* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
+ /* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
+ /* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
+ /* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
+ /* 0BC0 */ _(M,T), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
+ /* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
+ /* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Telugu */
+
+ /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T),
+ /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
+ /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
+ /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
+ /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Kannada */
+
+ /* 0C80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
+ /* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
+ /* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
+ /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
+ /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
+ /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
+ /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
+ /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x),
+ /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+ /* Malayalam */
+
+ /* 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), _(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),
+ /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
+ /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
+
+ /* Sinhala */
+
+ /* 0D80 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
+ /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
+ /* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
+ /* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
+ /* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
+ /* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR),_(M,TLR), _(M,LR), _(M,R),
+ /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
+ /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x1000u 1336
+
+
+ /* Myanmar */
+
+ /* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
+ /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B),
+ /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x),
+ /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x),
+ /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
+ /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B),
+ /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R),
+ /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(C,x), _(C,x),
+ /* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
+ /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1080 */ _(C,x), _(C,x), _(CM,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R),
+ /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R),
+ /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x),
+
+#define indic_offset_0x1780u 1496
+
+
+ /* Khmer */
+
+ /* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
+ /* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
+ /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,T), _(Vs,R),
+ /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T),
+ /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(SM,T), _(x,x), _(x,x),
+ /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x1cd0u 1608
+
+
+ /* Vedic Extensions */
+
+ /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B),
+ /* 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), _(Ca,R),
+ /* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x2008u 1656
+
+
+ /* General Punctuation */
+
+ /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x),
+ /* 2010 */ _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0x2070u 1672
+
+
+ /* Superscripts and Subscripts */
+
+ /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x),
+ /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0xa8e0u 1696
+
+
+ /* Devanagari Extended */
+
+ /* 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), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
+
+#define indic_offset_0xa9e0u 1720
+
+
+ /* Myanmar Extended-B */
+
+ /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x),
+ /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+ /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
+
+#define indic_offset_0xaa60u 1752
+
+
+ /* Myanmar Extended-A */
+
+ /* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
+ /* 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: 70% */
+
+INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u)
+{
+ switch (u >> 12)
+ {
+ case 0x0u:
+ 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<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<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<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:
+ break;
+ }
+ return _(x,x);
+}
+
+#undef _
+
+#undef ISC_A
+#undef ISC_Bi
+#undef ISC_BJN
+#undef ISC_Ca
+#undef ISC_C
+#undef ISC_CD
+#undef ISC_CF
+#undef ISC_CHL
+#undef ISC_CK
+#undef ISC_CM
+#undef ISC_CP
+#undef ISC_CPR
+#undef ISC_CPrf
+#undef ISC_CS
+#undef ISC_CSR
+#undef ISC_CWS
+#undef ISC_GM
+#undef ISC_IS
+#undef ISC_ZWJ
+#undef ISC_ML
+#undef ISC_ZWNJ
+#undef ISC_N
+#undef ISC_Nd
+#undef ISC_NJ
+#undef ISC_x
+#undef ISC_PK
+#undef ISC_RS
+#undef ISC_SM
+#undef ISC_TL
+#undef ISC_TM
+#undef ISC_V
+#undef ISC_Vs
+#undef ISC_Vo
+#undef ISC_M
+#undef ISC_VI
+
+#undef IMC_B
+#undef IMC_BL
+#undef IMC_BR
+#undef IMC_L
+#undef IMC_LR
+#undef IMC_x
+#undef IMC_O
+#undef IMC_R
+#undef IMC_T
+#undef IMC_TB
+#undef IMC_TBR
+#undef IMC_TL
+#undef IMC_TLR
+#undef IMC_TR
+#undef IMC_VOL
+
+/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index f8c970fc3eb..97d6d38287a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -24,14 +24,12 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-ot-shape-complex-indic-private.hh"
+#include "hb-ot-layout-private.hh"
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-indic.hh"
-#include "hb-ot-shaper-indic-machine.hh"
-#include "hb-ot-shaper-vowel-constraints.hh"
-#include "hb-ot-layout.hh"
+/* buffer var allocations */
+#define indic_category() complex_var_u8_0() /* indic_category_t */
+#define indic_position() complex_var_u8_1() /* indic_position_t */
/*
@@ -39,16 +37,105 @@
*/
-static inline void
-set_indic_properties (hb_glyph_info_t &info)
+#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base))
+
+#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u))
+#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u))
+#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u))
+#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u))
+#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u))
+#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u))
+#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u))
+#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
+#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
+#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
+#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u))
+
+
+#define MATRA_POS_LEFT(u) POS_PRE_M
+#define MATRA_POS_RIGHT(u) ( \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_BENG(u) ? POS_AFTER_POST : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
+ IS_ORYA(u) ? POS_AFTER_POST : \
+ IS_TAML(u) ? POS_AFTER_POST : \
+ IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+ IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+ IS_MLYM(u) ? POS_AFTER_POST : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \
+ IS_GUJR(u) ? POS_AFTER_SUB : \
+ IS_ORYA(u) ? POS_AFTER_MAIN : \
+ IS_TAML(u) ? POS_AFTER_SUB : \
+ IS_TELU(u) ? POS_BEFORE_SUB : \
+ IS_KNDA(u) ? POS_BEFORE_SUB : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+#define MATRA_POS_BOTTOM(u) ( \
+ IS_DEVA(u) ? POS_AFTER_SUB : \
+ IS_BENG(u) ? POS_AFTER_SUB : \
+ IS_GURU(u) ? POS_AFTER_POST : \
+ IS_GUJR(u) ? POS_AFTER_POST : \
+ IS_ORYA(u) ? POS_AFTER_SUB : \
+ IS_TAML(u) ? POS_AFTER_POST : \
+ IS_TELU(u) ? POS_BEFORE_SUB : \
+ IS_KNDA(u) ? POS_BEFORE_SUB : \
+ IS_MLYM(u) ? POS_AFTER_POST : \
+ IS_SINH(u) ? POS_AFTER_SUB : \
+ IS_KHMR(u) ? POS_AFTER_POST : \
+ /*default*/ POS_AFTER_SUB \
+ )
+
+static inline indic_position_t
+matra_position (hb_codepoint_t u, indic_position_t side)
{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
-
- info.indic_category() = (indic_category_t) (type & 0xFFu);
- info.indic_position() = (indic_position_t) (type >> 8);
+ switch ((int) side)
+ {
+ case POS_PRE_C: return MATRA_POS_LEFT (u);
+ case POS_POST_C: return MATRA_POS_RIGHT (u);
+ case POS_ABOVE_C: return MATRA_POS_TOP (u);
+ case POS_BELOW_C: return MATRA_POS_BOTTOM (u);
+ };
+ return side;
}
+/* XXX
+ * This is a hack for now. We should move this data into the main Indic table.
+ * Or completely remove it and just check in the tables.
+ */
+static const hb_codepoint_t ra_chars[] = {
+ 0x0930u, /* Devanagari */
+ 0x09B0u, /* Bengali */
+ 0x09F0u, /* Bengali */
+ 0x0A30u, /* Gurmukhi */ /* No Reph */
+ 0x0AB0u, /* Gujarati */
+ 0x0B30u, /* Oriya */
+ 0x0BB0u, /* Tamil */ /* No Reph */
+ 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */
+ 0x0CB0u, /* Kannada */
+ 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
+
+ 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
+
+ 0x179Au, /* Khmer */ /* No Reph, Visual Repha */
+};
+
+static inline bool
+is_ra (hb_codepoint_t u)
+{
+ for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++)
+ if (u == ra_chars[i])
+ return true;
+ return false;
+}
static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
@@ -58,58 +145,121 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags)
return !!(FLAG_UNSAFE (info.indic_category()) & flags);
}
-/* Note:
- *
- * 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!
- *
- * Keep in sync with consonant_categories in the generator. */
-#define CONSONANT_FLAGS_INDIC (FLAG (I_Cat(C)) | FLAG (I_Cat(CS)) | FLAG (I_Cat(Ra)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(V)) | FLAG (I_Cat(PLACEHOLDER)) | FLAG (I_Cat(DOTTEDCIRCLE)))
-
static inline bool
-is_consonant (const hb_glyph_info_t &info)
+is_joiner (const hb_glyph_info_t &info)
{
- return is_one_of (info, CONSONANT_FLAGS_INDIC);
+ return is_one_of (info, JOINER_FLAGS);
}
-#define JOINER_FLAGS (FLAG (I_Cat(ZWJ)) | FLAG (I_Cat(ZWNJ)))
-
static inline bool
-is_joiner (const hb_glyph_info_t &info)
+is_consonant (const hb_glyph_info_t &info)
{
- return is_one_of (info, JOINER_FLAGS);
+ return is_one_of (info, CONSONANT_FLAGS);
}
static inline bool
-is_halant (const hb_glyph_info_t &info)
+is_halant_or_coeng (const hb_glyph_info_t &info)
{
- return is_one_of (info, FLAG (I_Cat(H)));
+ return is_one_of (info, HALANT_OR_COENG_FLAGS);
}
-struct hb_indic_would_substitute_feature_t
+static inline void
+set_indic_properties (hb_glyph_info_t &info)
{
- void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+ indic_category_t cat = (indic_category_t) (type & 0x7Fu);
+ indic_position_t pos = (indic_position_t) (type >> 8);
+
+
+ /*
+ * Re-assign category
+ */
+
+ /* The following act more like the Bindus. */
+ 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<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<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.
+ * For now, just treat them like tone marks. */
+ else if (unlikely (u == 0x1CEDu))
+ cat = OT_A;
+ /* The following take marks in standalone clusters, similar to Avagraha. */
+ else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u,
+ 0x1CE9u, 0x1CECu,
+ 0x1CEEu, 0x1CF1u)))
{
- zero_context = zero_context_;
- lookups = map->get_stage_lookups (0/*GSUB*/,
- map->get_feature_stage (0/*GSUB*/, feature_tag));
+ cat = 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;
}
- bool would_substitute (const hb_codepoint_t *glyphs,
- unsigned int glyphs_count,
- hb_face_t *face) const
+ /* 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<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
+ cat = OT_PLACEHOLDER;
+ else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
+
+
+ /*
+ * Re-assign position.
+ */
+
+ if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS))
{
- for (const auto &lookup : lookups)
- if (hb_ot_layout_lookup_would_substitute (face, lookup.index, glyphs, glyphs_count, zero_context))
- return true;
- return false;
+ pos = POS_BASE_C;
+ if (is_ra (u))
+ cat = OT_Ra;
+ }
+ else if (cat == OT_M)
+ {
+ pos = matra_position (u, pos);
+ }
+ else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
+ {
+ pos = POS_SMVD;
}
- private:
- hb_array_t<const hb_ot_map_t::lookup_map_t> lookups;
- bool zero_context;
-};
+ if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
+
+
+
+ info.indic_category() = cat;
+ info.indic_position() = pos;
+}
+
+/*
+ * Things above this line should ideally be moved to the Indic table itself.
+ */
/*
@@ -120,16 +270,23 @@ struct hb_indic_would_substitute_feature_t
* instead of adding a new flag in these structs.
*/
+enum base_position_t {
+ BASE_POS_FIRST,
+ BASE_POS_LAST_SINHALA,
+ BASE_POS_LAST
+};
enum reph_position_t {
REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
REPH_POS_AFTER_SUB = POS_AFTER_SUB,
REPH_POS_BEFORE_POST = POS_BEFORE_POST,
- REPH_POS_AFTER_POST = POS_AFTER_POST
+ REPH_POS_AFTER_POST = POS_AFTER_POST,
+ REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH
};
enum reph_mode_t {
REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
REPH_MODE_EXPLICIT, /* Reph formed out of initial Ra,H,ZWJ sequence. */
+ REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
};
enum blwf_mode_t {
@@ -141,6 +298,7 @@ struct indic_config_t
hb_script_t script;
bool has_old_spec;
hb_codepoint_t virama;
+ base_position_t base_pos;
reph_position_t reph_pos;
reph_mode_t reph_mode;
blwf_mode_t blwf_mode;
@@ -149,92 +307,116 @@ struct indic_config_t
static const indic_config_t indic_configs[] =
{
/* Default. Should be first. */
- {HB_SCRIPT_INVALID, false, 0,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_DEVANAGARI,true, 0x094Du,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_BENGALI, true, 0x09CDu,REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_GUJARATI, true, 0x0ACDu,REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_ORIYA, true, 0x0B4Du,REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TAMIL, true, 0x0BCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
- {HB_SCRIPT_TELUGU, true, 0x0C4Du,REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_KANNADA, true, 0x0CCDu,REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
- {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
+ {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA,
+ REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
+ {HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
};
-static const hb_ot_map_feature_t
+
+/*
+ * Indic shaper.
+ */
+
+struct feature_list_t {
+ hb_tag_t tag;
+ hb_ot_map_feature_flags_t flags;
+};
+
+static const feature_list_t
indic_features[] =
{
/*
* Basic features.
- * These features are applied in order, one at a time, after initial_reordering,
- * constrained to the syllable.
+ * These features are applied in order, one at a time, after initial_reordering.
*/
- {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('r','p','h','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('h','a','l','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+ {HB_TAG('n','u','k','t'), F_GLOBAL},
+ {HB_TAG('a','k','h','n'), F_GLOBAL},
+ {HB_TAG('r','p','h','f'), F_NONE},
+ {HB_TAG('r','k','r','f'), F_GLOBAL},
+ {HB_TAG('p','r','e','f'), F_NONE},
+ {HB_TAG('b','l','w','f'), F_NONE},
+ {HB_TAG('a','b','v','f'), F_NONE},
+ {HB_TAG('h','a','l','f'), F_NONE},
+ {HB_TAG('p','s','t','f'), F_NONE},
+ {HB_TAG('v','a','t','u'), F_GLOBAL},
+ {HB_TAG('c','j','c','t'), F_GLOBAL},
+ {HB_TAG('c','f','a','r'), F_NONE},
/*
* Other features.
- * These features are applied all at once, after final_reordering, constrained
- * to the syllable.
+ * These features are applied all at once, after final_reordering.
* Default Bengali font in Windows for example has intermixed
* lookups for init,pres,abvs,blws features.
*/
- {HB_TAG('i','n','i','t'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS | F_PER_SYLLABLE},
+ {HB_TAG('i','n','i','t'), F_NONE},
+ {HB_TAG('p','r','e','s'), F_GLOBAL},
+ {HB_TAG('a','b','v','s'), F_GLOBAL},
+ {HB_TAG('b','l','w','s'), F_GLOBAL},
+ {HB_TAG('p','s','t','s'), F_GLOBAL},
+ {HB_TAG('h','a','l','n'), F_GLOBAL},
+ /* Positioning features, though we don't care about the types. */
+ {HB_TAG('d','i','s','t'), F_GLOBAL},
+ {HB_TAG('a','b','v','m'), F_GLOBAL},
+ {HB_TAG('b','l','w','m'), F_GLOBAL},
};
/*
* Must be in the same order as the indic_features array.
*/
enum {
- _INDIC_NUKT,
- _INDIC_AKHN,
- INDIC_RPHF,
- _INDIC_RKRF,
- INDIC_PREF,
- INDIC_BLWF,
- INDIC_ABVF,
- INDIC_HALF,
- INDIC_PSTF,
- _INDIC_VATU,
- _INDIC_CJCT,
-
- INDIC_INIT,
- _INDIC_PRES,
- _INDIC_ABVS,
- _INDIC_BLWS,
- _INDIC_PSTS,
- _INDIC_HALN,
+ _NUKT,
+ _AKHN,
+ RPHF,
+ _RKRF,
+ PREF,
+ BLWF,
+ ABVF,
+ HALF,
+ PSTF,
+ _VATU,
+ _CJCT,
+ CFAR,
+
+ INIT,
+ _PRES,
+ _ABVS,
+ _BLWS,
+ _PSTS,
+ _HALN,
+ _DIST,
+ _ABVM,
+ _BLWM,
INDIC_NUM_FEATURES,
- INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
+ INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
};
-static bool
-setup_syllables_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-initial_reordering_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-final_reordering_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -242,42 +424,83 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
- map->add_gsub_pause (setup_syllables_indic);
+ map->add_gsub_pause (setup_syllables);
- map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
- map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
unsigned int i = 0;
- map->add_gsub_pause (initial_reordering_indic);
-
+ map->add_gsub_pause (initial_reordering);
for (; i < INDIC_BASIC_FEATURES; i++) {
- map->add_feature (indic_features[i]);
+ 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 | F_MANUAL_ZWNJ);
+ }
- map->add_gsub_pause (final_reordering_indic);
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_global_bool_feature (HB_TAG('c','l','i','g'));
- for (; i < INDIC_NUM_FEATURES; i++)
- map->add_feature (indic_features[i]);
+ map->add_gsub_pause (clear_syllables);
}
static void
override_features_indic (hb_ot_shape_planner_t *plan)
{
- plan->map.disable_feature (HB_TAG('l','i','g','a'));
- plan->map.add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
+ /* Uniscribe does not apply 'kern' in Khmer. */
+ if (hb_options ().uniscribe_bug_compatible)
+ {
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_KHMER:
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ break;
+ }
+ }
+
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
+struct would_substitute_feature_t
+{
+ inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
+ {
+ zero_context = zero_context_;
+ map->get_stage_lookups (0/*GSUB*/,
+ map->get_feature_stage (0/*GSUB*/, feature_tag),
+ &lookups, &count);
+ }
+
+ inline bool would_substitute (const hb_codepoint_t *glyphs,
+ unsigned int glyphs_count,
+ hb_face_t *face) const
+ {
+ for (unsigned int i = 0; i < count; i++)
+ if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+ return true;
+ return false;
+ }
+
+ private:
+ const hb_ot_map_t::lookup_map_t *lookups;
+ unsigned int count;
+ bool zero_context;
+};
+
struct indic_shape_plan_t
{
- bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
+ ASSERT_POD ();
+
+ inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
{
hb_codepoint_t glyph = virama_glyph;
- if (unlikely (glyph == (hb_codepoint_t) -1))
+ if (unlikely (virama_glyph == (hb_codepoint_t) -1))
{
if (!config->virama || !font->get_nominal_glyph (config->virama, &glyph))
glyph = 0;
@@ -285,8 +508,8 @@ struct indic_shape_plan_t
* Maybe one day... */
/* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
- * during shape planning... Instead, overwrite it here. */
- virama_glyph = (int) glyph;
+ * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
+ virama_glyph = glyph;
}
*pglyph = glyph;
@@ -296,18 +519,12 @@ struct indic_shape_plan_t
const indic_config_t *config;
bool is_old_spec;
-#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
- bool uniscribe_bug_compatible;
-#else
- static constexpr bool uniscribe_bug_compatible = false;
-#endif
- mutable hb_atomic_int_t virama_glyph;
+ mutable hb_codepoint_t virama_glyph;
- hb_indic_would_substitute_feature_t rphf;
- hb_indic_would_substitute_feature_t pref;
- hb_indic_would_substitute_feature_t blwf;
- hb_indic_would_substitute_feature_t pstf;
- hb_indic_would_substitute_feature_t vatu;
+ would_substitute_feature_t rphf;
+ would_substitute_feature_t pref;
+ would_substitute_feature_t blwf;
+ would_substitute_feature_t pstf;
hb_mask_t mask_array[INDIC_NUM_FEATURES];
};
@@ -315,7 +532,7 @@ struct indic_shape_plan_t
static void *
data_create_indic (const hb_ot_shape_plan_t *plan)
{
- indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) hb_calloc (1, sizeof (indic_shape_plan_t));
+ indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
if (unlikely (!indic_plan))
return nullptr;
@@ -327,10 +544,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
}
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
-#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
- indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
-#endif
- indic_plan->virama_glyph = -1;
+ indic_plan->virama_glyph = (hb_codepoint_t) -1;
/* Use zero-context would_substitute() matching for new-spec of the main
* Indic scripts, and scripts with one spec only, but not for old-specs.
@@ -346,7 +560,6 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
- indic_plan->vatu.init (&plan->map, HB_TAG('v','a','t','u'), zero_context);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
@@ -358,7 +571,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
static void
data_destroy_indic (void *data)
{
- hb_free (data);
+ free (data);
}
static indic_position_t
@@ -376,16 +589,10 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* base at 0. The font however, only has lookups matching
* 930,94D in 'blwf', not the expected 94D,930 (with new-spec
* table). As such, we simply match both sequences. Seems
- * to work.
- *
- * Vatu is done as well, for:
- * https://github.com/harfbuzz/harfbuzz/issues/1587
- */
+ * to work. */
hb_codepoint_t glyphs[3] = {virama, consonant, virama};
if (indic_plan->blwf.would_substitute (glyphs , 2, face) ||
- indic_plan->blwf.would_substitute (glyphs+1, 2, face) ||
- indic_plan->vatu.would_substitute (glyphs , 2, face) ||
- indic_plan->vatu.would_substitute (glyphs+1, 2, face))
+ indic_plan->blwf.would_substitute (glyphs+1, 2, face))
return POS_BELOW_C;
if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
indic_plan->pstf.would_substitute (glyphs+1, 2, face))
@@ -396,6 +603,19 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
return POS_BASE_C;
}
+
+enum syllable_type_t {
+ consonant_syllable,
+ vowel_syllable,
+ standalone_cluster,
+ symbol_cluster,
+ broken_cluster,
+ non_indic_cluster,
+};
+
+#include "hb-ot-shape-complex-indic-machine.hh"
+
+
static void
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@@ -413,16 +633,14 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
set_indic_properties (info[i]);
}
-static bool
-setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
{
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
- find_syllables_indic (buffer);
+ find_syllables (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
- return false;
}
static int
@@ -431,20 +649,23 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
int a = pa->indic_position();
int b = pb->indic_position();
- return (int) a - (int) b;
+ return a < b ? -1 : a == b ? 0 : +1;
}
static void
-update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
+update_consonant_positions (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+ if (indic_plan->config->base_pos != BASE_POS_LAST)
+ return;
+
hb_codepoint_t virama;
- if (indic_plan->load_virama_glyph (font, &virama))
+ if (indic_plan->get_virama_glyph (font, &virama))
{
hb_face_t *face = font->face;
unsigned int count = buffer->len;
@@ -460,7 +681,7 @@ update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
/* Rules from:
- * https://docs.microsqoft.com/en-us/typography/script-development/devanagari */
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
@@ -477,12 +698,14 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
*/
if (buffer->props.script == HB_SCRIPT_KANNADA &&
start + 3 <= end &&
- is_one_of (info[start ], FLAG (I_Cat(Ra))) &&
- is_one_of (info[start+1], FLAG (I_Cat(H))) &&
- is_one_of (info[start+2], FLAG (I_Cat(ZWJ))))
+ 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_swap (info[start+1], info[start+2]);
+ hb_glyph_info_t tmp = info[start+1];
+ info[start+1] = info[start+2];
+ info[start+2] = tmp;
}
/* 1. Find base consonant:
@@ -507,11 +730,12 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
- if (indic_plan->mask_array[INDIC_RPHF] &&
+ if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
+ indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
- (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == I_Cat(ZWJ))
+ (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
))
{
/* See if it matches the 'rphf' feature. */
@@ -529,7 +753,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
base = start;
has_reph = true;
}
- } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == I_Cat(Repha))
+ } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha)
{
limit += 1;
while (limit < end && is_joiner (info[limit]))
@@ -538,51 +762,100 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
has_reph = true;
}
+ switch (indic_plan->config->base_pos)
{
- /* -> starting from the end of the syllable, move backwards */
- unsigned int i = end;
- bool seen_below = false;
- do {
- i--;
- /* -> until a consonant is found */
- if (is_consonant (info[i]))
- {
- /* -> that does not have a below-base or post-base form
- * (post-base forms have to follow below-base forms), */
- if (info[i].indic_position() != POS_BELOW_C &&
- (info[i].indic_position() != POS_POST_C || seen_below))
+ case BASE_POS_LAST:
+ {
+ /* -> starting from the end of the syllable, move backwards */
+ unsigned int i = end;
+ bool seen_below = false;
+ do {
+ i--;
+ /* -> until a consonant is found */
+ if (is_consonant (info[i]))
{
+ /* -> that does not have a below-base or post-base form
+ * (post-base forms have to follow below-base forms), */
+ if (info[i].indic_position() != POS_BELOW_C &&
+ (info[i].indic_position() != POS_POST_C || seen_below))
+ {
+ base = i;
+ break;
+ }
+ if (info[i].indic_position() == POS_BELOW_C)
+ seen_below = true;
+
+ /* -> 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
+ * by the logic above already.
+ */
+
+ /* -> or arrive at the first consonant. The consonant stopped at will
+ * be the base. */
base = i;
- break;
}
- if (info[i].indic_position() == POS_BELOW_C)
- seen_below = true;
+ else
+ {
+ /* A ZWJ after a Halant stops the base search, and requests an explicit
+ * half form.
+ * A ZWJ before a Halant, requests a subjoined form instead, and hence
+ * search continues. This is particularly important for Bengali
+ * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
+ if (start < i &&
+ info[i].indic_category() == OT_ZWJ &&
+ info[i - 1].indic_category() == OT_H)
+ break;
+ }
+ } while (i > limit);
+ }
+ break;
- /* -> 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
- * by the logic above already.
- */
+ case BASE_POS_LAST_SINHALA:
+ {
+ /* Sinhala base positioning is slightly different from main Indic, in that:
+ * 1. Its ZWJ behavior is different,
+ * 2. We don't need to look into the font for consonant positions.
+ */
- /* -> or arrive at the first consonant. The consonant stopped at will
- * be the base. */
- base = i;
- }
- else
- {
- /* A ZWJ after a Halant stops the base search, and requests an explicit
- * half form.
- * A ZWJ before a Halant, requests a subjoined form instead, and hence
- * search continues. This is particularly important for Bengali
- * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
- if (start < i &&
- info[i].indic_category() == I_Cat(ZWJ) &&
- info[i - 1].indic_category() == I_Cat(H))
- break;
- }
- } while (i > limit);
+ if (!has_reph)
+ base = limit;
+
+ /* Find the last base consonant that is not blocked by ZWJ. If there is
+ * a ZWJ right before a base consonant, that would request a subjoined form. */
+ for (unsigned int i = limit; i < end; i++)
+ if (is_consonant (info[i]))
+ {
+ if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
+ break;
+ else
+ base = i;
+ }
+
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]))
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
+
+ case BASE_POS_FIRST:
+ {
+ /* The first consonant is always the base. */
+
+ assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+ assert (!has_reph);
+
+ base = start;
+
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]))
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
@@ -632,11 +905,23 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Reorder characters */
for (unsigned int i = start; i < base; i++)
- info[i].indic_position() = hb_min (POS_PRE_C, (indic_position_t) info[i].indic_position());
+ info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position());
if (base < end)
info[base].indic_position() = POS_BASE_C;
+ /* Mark final consonants. A final consonant is one appearing after a matra,
+ * like in Khmer. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (info[i].indic_category() == OT_M) {
+ for (unsigned int j = i + 1; j < end; j++)
+ if (is_consonant (info[j])) {
+ info[j].indic_position() = POS_FINAL_C;
+ break;
+ }
+ break;
+ }
+
/* Handle beginning Ra */
if (has_reph)
info[start].indic_position() = POS_RA_TO_BECOME_REPH;
@@ -645,10 +930,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* last consonant.
*
* Reports suggest that in some scripts Uniscribe does this only if there
- * is *not* a Halant after last consonant already. We know that is the
- * case for Kannada, while it reorders unconditionally in other scripts,
- * eg. Malayalam, Bengali, and Devanagari. We don't currently know about
- * other scripts, so we block Kannada.
+ * is *not* a Halant after last consonant already (eg. Kannada), while it
+ * does it unconditionally in other scripts (eg. Malayalam). We don't
+ * currently know about other scripts, so we single out Malayalam for now.
*
* Kannada test case:
* U+0C9A,U+0CCD,U+0C9A,U+0CCD
@@ -658,35 +942,25 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* Malayalam test case:
* U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D
* With lohit-ttf-20121122/Lohit-Malayalam.ttf
- *
- * Bengali test case:
- * U+0998,U+09CD,U+09AF,U+09CD
- * With Windows XP vrinda.ttf
- * https://github.com/harfbuzz/harfbuzz/issues/1073
- *
- * Devanagari test case:
- * U+091F,U+094D,U+0930,U+094D
- * With chandas.ttf
- * https://github.com/harfbuzz/harfbuzz/issues/1071
*/
if (indic_plan->is_old_spec)
{
- bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA;
+ bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM;
for (unsigned int i = base + 1; i < end; i++)
- if (info[i].indic_category() == I_Cat(H))
+ if (info[i].indic_category() == OT_H)
{
- unsigned int j;
- for (j = end - 1; j > i; j--)
+ unsigned int j;
+ for (j = end - 1; j > i; j--)
if (is_consonant (info[j]) ||
- (disallow_double_halants && info[j].indic_category() == I_Cat(H)))
+ (disallow_double_halants && info[j].indic_category() == OT_H))
break;
- if (info[j].indic_category() != I_Cat(H) && j > i) {
+ if (info[j].indic_category() != OT_H && j > i) {
/* Move Halant to after last consonant. */
hb_glyph_info_t t = info[i];
memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
info[j] = t;
}
- break;
+ break;
}
}
@@ -695,16 +969,20 @@ 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_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (I_Cat(N)) | FLAG (I_Cat(RS)) | FLAG (I_Cat(CM)) | FLAG (I_Cat(H)))))
+ 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() == I_Cat(H) &&
+ if (unlikely (info[i].indic_category() == OT_H &&
info[i].indic_position() == POS_PRE_M))
{
/*
* Uniscribe doesn't move the Halant with Left Matra.
- * TEST: U+092B,U+093F,U+094D
- * We follow.
+ * TEST: U+092B,U+093F,U+094DE
+ * We follow. This is important for the Sinhala
+ * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
+ * where U+0DD9 is a left matra and U+0DCA is the virama.
+ * We don't want to move the virama with the left matra.
+ * TEST: U+0D9A,U+0DDA
*/
for (unsigned int j = i; j > start; j--)
if (info[j - 1].indic_position() != POS_PRE_M) {
@@ -713,10 +991,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
} else if (info[i].indic_position() != POS_SMVD) {
- if (info[i].indic_category() == I_Cat(MPst) &&
- i > start && info[i - 1].indic_category() == I_Cat(SM))
- info[i - 1].indic_position() = info[i].indic_position();
- last_pos = (indic_position_t) info[i].indic_position();
+ last_pos = (indic_position_t) info[i].indic_position();
}
}
}
@@ -731,8 +1006,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position();
last = i;
- } else if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
- last = i;
+ } else if (info[i].indic_category() == OT_M)
+ last = i;
}
@@ -744,40 +1019,14 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Sit tight, rock 'n roll! */
hb_stable_sort (info + start, end - start, compare_indic_order);
-
- /* Find base again; also flip left-matra sequence. */
- unsigned first_left_matra = end;
- unsigned last_left_matra = end;
+ /* Find base again */
base = end;
for (unsigned int i = start; i < end; i++)
- {
if (info[i].indic_position() == POS_BASE_C)
{
base = i;
break;
}
- else if (info[i].indic_position() == POS_PRE_M)
- {
- if (first_left_matra == end)
- first_left_matra = i;
- last_left_matra = i;
- }
- }
- /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
- if (first_left_matra < last_left_matra)
- {
- /* No need to merge clusters, handled later. */
- buffer->reverse_range (first_left_matra, last_left_matra + 1);
- /* Reverse back nuktas, etc. */
- unsigned i = first_left_matra;
- for (unsigned j = i; j <= last_left_matra; j++)
- if (FLAG_UNSAFE (info[j].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
- {
- buffer->reverse_range (i, j + 1);
- i = j + 1;
- }
- }
-
/* Things are out-of-control for post base positions, they may shuffle
* around like crazy. In old-spec mode, we move halants around, so in
* that case merge all clusters after base. Otherwise, check the sort
@@ -786,50 +1035,26 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
*
* We could use buffer->sort() for this, if there was no special
* reordering of pre-base stuff happening later...
- * We don't want to merge_clusters all of that, which buffer->sort()
- * would. Here's a concrete example:
- *
- * Assume there's a pre-base consonant and explicit Halant before base,
- * followed by a prebase-reordering (left) Matra:
- *
- * C,H,ZWNJ,B,M
- *
- * At this point in reordering we would have:
- *
- * M,C,H,ZWNJ,B
- *
- * whereas in final reordering we will bring the Matra closer to Base:
- *
- * C,H,ZWNJ,M,B
- *
- * That's why we don't want to merge-clusters anything before the Base
- * at this point. But if something moved from after Base to before it,
- * we should merge clusters from base to them. In final-reordering, we
- * only move things around before base, and merge-clusters up to base.
- * These two merge-clusters from the two sides of base will interlock
- * to merge things correctly. See:
- * https://github.com/harfbuzz/harfbuzz/issues/2272
*/
- if (indic_plan->is_old_spec || end - start > 127)
+ if (indic_plan->is_old_spec || end - base > 127)
buffer->merge_clusters (base, end);
else
{
/* Note! syllable() is a one-byte field. */
for (unsigned int i = base; i < end; i++)
- if (info[i].syllable() != 255)
+ if (info[i].syllable() != 255)
{
- unsigned int min = i;
unsigned int max = i;
unsigned int j = start + info[i].syllable();
while (j != i)
{
- min = hb_min (min, j);
- max = hb_max (max, j);
+ max = MAX (max, j);
unsigned int next = start + info[j].syllable();
info[j].syllable() = 255; /* So we don't process j later again. */
j = next;
}
- buffer->merge_clusters (hb_max (base, min), max + 1);
+ if (i != max)
+ buffer->merge_clusters (i, max + 1);
}
}
@@ -845,13 +1070,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Reph */
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
- info[i].mask |= indic_plan->mask_array[INDIC_RPHF];
+ info[i].mask |= indic_plan->mask_array[RPHF];
/* Pre-base */
- mask = indic_plan->mask_array[INDIC_HALF];
+ mask = indic_plan->mask_array[HALF];
if (!indic_plan->is_old_spec &&
indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
- mask |= indic_plan->mask_array[INDIC_BLWF];
+ mask |= indic_plan->mask_array[BLWF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
/* Base */
@@ -859,9 +1084,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end)
info[base].mask |= mask;
/* Post-base */
- mask = indic_plan->mask_array[INDIC_BLWF] |
- indic_plan->mask_array[INDIC_ABVF] |
- indic_plan->mask_array[INDIC_PSTF];
+ mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
for (unsigned int i = base + 1; i < end; i++)
info[i].mask |= mask;
}
@@ -888,28 +1111,39 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
*/
for (unsigned int i = start; i + 1 < base; i++)
- if (info[i ].indic_category() == I_Cat(Ra) &&
- info[i+1].indic_category() == I_Cat(H) &&
+ if (info[i ].indic_category() == OT_Ra &&
+ info[i+1].indic_category() == OT_H &&
(i + 2 == base ||
- info[i+2].indic_category() != I_Cat(ZWJ)))
+ info[i+2].indic_category() != OT_ZWJ))
{
- info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
- info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
+ info[i ].mask |= indic_plan->mask_array[BLWF];
+ info[i+1].mask |= indic_plan->mask_array[BLWF];
}
}
unsigned int pref_len = 2;
- if (indic_plan->mask_array[INDIC_PREF] && base + pref_len < end)
+ if (indic_plan->mask_array[PREF] && base + pref_len < end)
{
/* 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++)
- glyphs[j] = info[i + j].codepoint;
+ glyphs[j] = info[i + j].codepoint;
if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
for (unsigned int j = 0; j < pref_len; j++)
- info[i++].mask |= indic_plan->mask_array[INDIC_PREF];
+ info[i++].mask |= indic_plan->mask_array[PREF];
+
+ /* Mark the subsequent stuff with 'cfar'. Used in Khmer.
+ * Read the feature spec.
+ * This allows distinguishing the following cases with MS Khmer fonts:
+ * U+1784,U+17D2,U+179A,U+17D2,U+1782
+ * U+1784,U+17D2,U+1782,U+17D2,U+179A
+ */
+ if (indic_plan->mask_array[CFAR])
+ for (; i < end; i++)
+ info[i].mask |= indic_plan->mask_array[CFAR];
+
break;
}
}
@@ -918,7 +1152,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Apply ZWJ/ZWNJ effects */
for (unsigned int i = start + 1; i < end; i++)
if (is_joiner (info[i])) {
- bool non_joiner = info[i].indic_category() == I_Cat(ZWNJ);
+ bool non_joiner = info[i].indic_category() == OT_ZWNJ;
unsigned int j = i;
do {
@@ -930,7 +1164,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* A ZWNJ disables HALF. */
if (non_joiner)
- info[j].mask &= ~indic_plan->mask_array[INDIC_HALF];
+ info[j].mask &= ~indic_plan->mask_array[HALF];
} while (j > start && !is_consonant (info[j]));
}
@@ -945,13 +1179,12 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
/* We treat placeholder/dotted-circle as if they are consonants, so we
* should just chain. Only if not in compatibility mode that is... */
- const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- if (indic_plan->uniscribe_bug_compatible)
+ if (hb_options ().uniscribe_bug_compatible)
{
/* For dotted-circle, this is what Uniscribe does:
* If dotted-circle is the last glyph, it just does nothing.
* Ie. It doesn't form Reph. */
- if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE))
+ if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE)
return;
}
@@ -959,59 +1192,107 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
}
static void
-initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
- hb_face_t *face,
- hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
{
- indic_syllable_type_t syllable_type = (indic_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+ syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
- case indic_vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
- case indic_consonant_syllable:
+ case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
+ case consonant_syllable:
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
break;
- case indic_broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
- case indic_standalone_cluster:
+ case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
+ case standalone_cluster:
initial_reordering_standalone_cluster (plan, face, buffer, start, end);
break;
- case indic_symbol_cluster:
- case indic_non_indic_cluster:
+ case symbol_cluster:
+ case non_indic_cluster:
break;
}
}
-static bool
-initial_reordering_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
{
- bool ret = false;
- if (!buffer->message (font, "start reordering indic initial"))
- return ret;
-
- update_consonant_positions_indic (plan, font, buffer);
- if (hb_syllabic_insert_dotted_circles (font, buffer,
- indic_broken_cluster,
- I_Cat(DOTTEDCIRCLE),
- I_Cat(Repha),
- POS_END))
- ret = true;
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
- foreach_syllable (buffer, start, end)
- initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
- (void) buffer->message (font, "end reordering indic initial");
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ dottedcircle.codepoint = 0x25CCu;
+ set_indic_properties (dottedcircle);
+ dottedcircle.codepoint = dottedcircle_glyph;
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len && !buffer->in_error)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
- return ret;
+ hb_glyph_info_t ginfo = dottedcircle;
+ ginfo.cluster = buffer->cur().cluster;
+ ginfo.mask = buffer->cur().mask;
+ ginfo.syllable() = buffer->cur().syllable();
+ /* TODO Set glyph_props? */
+
+ /* Insert dottedcircle after possible Repha. */
+ while (buffer->idx < buffer->len && !buffer->in_error &&
+ last_syllable == buffer->cur().syllable() &&
+ buffer->cur().indic_category() == OT_Repha)
+ buffer->next_glyph ();
+
+ buffer->output_info (ginfo);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
}
static void
-final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ update_consonant_positions (plan, font, buffer);
+ insert_dotted_circles (plan, font, buffer);
+
+ foreach_syllable (buffer, start, end)
+ initial_reordering_syllable (plan, font->face, buffer, start, end);
+}
+
+static void
+final_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
@@ -1021,19 +1302,17 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* 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 I_Cat(H) is desired but has been lost. */
- /* We don't call load_virama_glyph(), since we know it's already
- * loaded. */
- hb_codepoint_t virama_glyph = indic_plan->virama_glyph;
- if (virama_glyph)
+ * class of OT_H is desired but has been lost. */
+ if (indic_plan->virama_glyph)
{
+ unsigned int virama_glyph = indic_plan->virama_glyph;
for (unsigned int i = start; i < end; i++)
if (info[i].codepoint == virama_glyph &&
_hb_glyph_info_ligated (&info[i]) &&
_hb_glyph_info_multiplied (&info[i]))
{
- /* This will make sure that this glyph passes is_halant() test. */
- info[i].indic_category() = I_Cat(H);
+ /* This will make sure that this glyph passes is_halant_or_coeng() test. */
+ info[i].indic_category() = OT_H;
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
}
}
@@ -1047,7 +1326,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* syllable.
*/
- bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
+ bool try_pref = !!indic_plan->mask_array[PREF];
/* Find base again */
unsigned int base;
@@ -1057,7 +1336,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end)
{
for (unsigned int i = base + 1; i < end; i++)
- if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
+ if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
{
if (!(_hb_glyph_info_substituted (&info[i]) &&
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
@@ -1065,17 +1344,14 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
/* Ok, this was a 'pref' candidate but didn't form any.
* Base is around here... */
base = i;
- while (base < end && is_halant (info[base]))
+ while (base < end && is_halant_or_coeng (info[base]))
base++;
- if (base < end)
- info[base].indic_position() = POS_BASE_C;
+ info[base].indic_position() = POS_BASE_C;
try_pref = false;
}
break;
}
- if (base == end)
- break;
}
/* For Malayalam, skip over unformed below- (but NOT post-) forms. */
if (buffer->props.script == HB_SCRIPT_MALAYALAM)
@@ -1084,7 +1360,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
{
while (i < end && is_joiner (info[i]))
i++;
- if (i == end || !is_halant (info[i]))
+ if (i == end || !is_halant_or_coeng (info[i]))
break;
i++; /* Skip halant. */
while (i < end && is_joiner (info[i]))
@@ -1098,15 +1374,15 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
if (start < base && info[base].indic_position() > POS_BASE_C)
- base--;
+ base--;
break;
}
if (base == end && start < base &&
- is_one_of (info[base - 1], FLAG (I_Cat(ZWJ))))
+ is_one_of (info[base - 1], FLAG (OT_ZWJ)))
base--;
if (base < end)
while (start < base &&
- is_one_of (info[base], (FLAG (I_Cat(N)) | FLAG (I_Cat(H)))))
+ is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS)))
base--;
@@ -1118,24 +1394,6 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* defined as “after last standalone halant glyph, after initial matra
* position and before the main consonant”. If ZWJ or ZWNJ follow this
* halant, position is moved after it.
- *
- * IMPLEMENTATION NOTES:
- *
- * It looks like the last sentence is wrong. Testing, with Windows 7 Uniscribe
- * and Devanagari shows that the behavior is best described as:
- *
- * "If ZWJ follows this halant, matra is NOT repositioned after this halant.
- * If ZWNJ follows this halant, position is moved after it."
- *
- * Test case, with Adobe Devanagari or Nirmala UI:
- *
- * U+091F,U+094D,U+200C,U+092F,U+093F
- * (Matra moves to the middle, after ZWNJ.)
- *
- * U+091F,U+094D,U+200D,U+092F,U+093F
- * (Matra does NOT move, stays to the left.)
- *
- * https://github.com/harfbuzz/harfbuzz/issues/1070
*/
if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
@@ -1149,46 +1407,22 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
*/
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
- search:
while (new_pos > start &&
- !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H))))))
+ !(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS))))
new_pos--;
/* If we found no Halant we are done.
* Otherwise only proceed if the Halant does
* not belong to the Matra itself! */
- if (is_halant (info[new_pos]) &&
+ if (is_halant_or_coeng (info[new_pos]) &&
info[new_pos].indic_position() != POS_PRE_M)
{
-#if 0 // See comment above
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
new_pos++;
-#endif
- if (new_pos + 1 < end)
- {
- /* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */
- if (info[new_pos + 1].indic_category() == I_Cat(ZWJ))
- {
- /* Keep searching. */
- if (new_pos > start)
- {
- new_pos--;
- goto search;
- }
- }
- /* -> If ZWNJ follows this halant, position is moved after it.
- *
- * IMPLEMENTATION NOTES:
- *
- * This is taken care of by the state-machine. A Halant,ZWNJ is a terminating
- * sequence for a consonant syllable; any pre-base matras occurring after it
- * will belong to the subsequent syllable.
- */
- }
}
else
- new_pos = start; /* No move. */
+ new_pos = start; /* No move. */
}
if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
@@ -1207,14 +1441,14 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
/* Note: this merge_clusters() is intentionally *after* the reordering.
* Indic matra reordering is special and tricky... */
- buffer->merge_clusters (new_pos, hb_min (end, base + 1));
+ buffer->merge_clusters (new_pos, MIN (end, base + 1));
new_pos--;
}
} else {
for (unsigned int i = start; i < base; i++)
if (info[i].indic_position () == POS_PRE_M) {
- buffer->merge_clusters (i, hb_min (end, base + 1));
+ buffer->merge_clusters (i, MIN (end, base + 1));
break;
}
}
@@ -1241,12 +1475,14 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
*/
if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
- ((info[start].indic_category() == I_Cat(Repha)) ^
+ ((info[start].indic_category() == OT_Repha) ^
_hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
{
unsigned int new_reph_pos;
reph_position_t reph_pos = indic_plan->config->reph_pos;
+ assert (reph_pos != REPH_POS_DONT_CARE);
+
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
*/
@@ -1268,10 +1504,10 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
*/
{
new_reph_pos = start + 1;
- while (new_reph_pos < base && !is_halant (info[new_reph_pos]))
+ while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
new_reph_pos++;
- if (new_reph_pos < base && is_halant (info[new_reph_pos]))
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
{
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
@@ -1290,7 +1526,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
new_reph_pos++;
if (new_reph_pos < end)
- goto reph_move;
+ goto reph_move;
}
/* 4. If reph should be positioned before post-base consonant, find
@@ -1306,7 +1542,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
!( 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;
+ goto reph_move;
}
/* 5. If no consonant is found in steps 3 or 4, move reph to a position
@@ -1320,10 +1556,10 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
{
/* Copied from step 2. */
new_reph_pos = start + 1;
- while (new_reph_pos < base && !is_halant (info[new_reph_pos]))
+ while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
new_reph_pos++;
- if (new_reph_pos < base && is_halant (info[new_reph_pos]))
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
{
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
@@ -1331,7 +1567,6 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
goto reph_move;
}
}
- /* See https://github.com/harfbuzz/harfbuzz/issues/2298#issuecomment-615318654 */
/* 6. Otherwise, reorder reph to the end of the syllable.
*/
@@ -1347,17 +1582,14 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* Uniscribe doesn't do this.
* TEST: U+0930,U+094D,U+0915,U+094B,U+094D
*/
- if (!indic_plan->uniscribe_bug_compatible &&
- unlikely (is_halant (info[new_reph_pos])))
- {
+ if (!hb_options ().uniscribe_bug_compatible &&
+ unlikely (is_halant_or_coeng (info[new_reph_pos]))) {
for (unsigned int i = base + 1; i < new_reph_pos; i++)
- if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst))))
- {
+ if (info[i].indic_category() == OT_M) {
/* Ok, got it. */
new_reph_pos--;
}
}
-
goto reph_move;
}
@@ -1384,13 +1616,13 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
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[INDIC_PREF]) != 0)
+ if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
{
/* 1. Only reorder a glyph produced by substitution during application
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
- /* Note: We just check that something got substituted. We don't check that
+ /* Note: We just check that something got substituted. We don't check that
* the <pref> feature actually did it...
*
* Reorder pref only if it ligated. */
@@ -1412,11 +1644,24 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
while (new_pos > start &&
- !(is_one_of (info[new_pos - 1], FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)) | FLAG (I_Cat(H)))))
+ !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
new_pos--;
+
+ /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
+ * split matra, it should be reordered to *before* the left part of such matra. */
+ if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
+ {
+ unsigned int old_pos = i;
+ for (unsigned int j = base + 1; j < old_pos; j++)
+ if (info[j].indic_category() == OT_M)
+ {
+ new_pos--;
+ break;
+ }
+ }
}
- if (new_pos > start && is_halant (info[new_pos - 1]))
+ if (new_pos > start && is_halant_or_coeng (info[new_pos - 1]))
{
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos < end && is_joiner (info[new_pos]))
@@ -1436,7 +1681,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
}
- break;
+ break;
}
}
@@ -1447,7 +1692,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
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[INDIC_INIT];
+ info[start].mask |= indic_plan->mask_array[INIT];
else
buffer->unsafe_to_break (start - 1, start + 1);
}
@@ -1456,15 +1701,16 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
/*
* Finish off the clusters and go home!
*/
- if (indic_plan->uniscribe_bug_compatible)
+ if (hb_options ().uniscribe_bug_compatible)
{
switch ((hb_tag_t) plan->props.script)
{
case HB_SCRIPT_TAMIL:
- break;
+ case HB_SCRIPT_SINHALA:
+ break;
default:
- /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil.
+ /* 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. */
@@ -1475,37 +1721,34 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
-static bool
-final_reordering_indic (const hb_ot_shape_plan_t *plan,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
- if (unlikely (!count)) return false;
+ if (unlikely (!count)) return;
- if (buffer->message (font, "start reordering indic final")) {
- foreach_syllable (buffer, start, end)
- final_reordering_syllable_indic (plan, buffer, start, end);
- (void) buffer->message (font, "end reordering indic final");
- }
+ foreach_syllable (buffer, start, end)
+ final_reordering_syllable (plan, buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
-
- return false;
}
static void
-preprocess_text_indic (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- hb_font_t *font)
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
{
- const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- if (!indic_plan->uniscribe_bug_compatible)
- _hb_preprocess_text_vowel_constraints (plan, buffer, font);
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
}
+
static bool
decompose_indic (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
@@ -1516,9 +1759,6 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
{
/* Don't decompose these. */
case 0x0931u : return false; /* DEVANAGARI LETTER RRA */
- // https://github.com/harfbuzz/harfbuzz/issues/779
- case 0x09DCu : return false; /* BENGALI LETTER RRA */
- case 0x09DDu : return false; /* BENGALI LETTER RHA */
case 0x0B94u : return false; /* TAMIL LETTER AU */
@@ -1526,6 +1766,13 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
* Decompose split matras that don't have Unicode decompositions.
*/
+ /* Khmer */
+ case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true;
+ case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true;
+ case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true;
+ case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true;
+ case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true;
+
#if 0
/* Gujarati */
/* This one has no decomposition in Unicode, but needs no decomposition either. */
@@ -1536,6 +1783,49 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
#endif
}
+ if ((ab == 0x0DDAu || hb_in_range<hb_codepoint_t> (ab, 0x0DDCu, 0x0DDEu)))
+ {
+ /*
+ * Sinhala split matras... Let the fun begin.
+ *
+ * These four characters have Unicode decompositions. However, Uniscribe
+ * decomposes them "Khmer-style", that is, it uses the character itself to
+ * get the second half. The first half of all four decompositions is always
+ * U+0DD9.
+ *
+ * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
+ * broken with Uniscribe. But we need to support them. As such, we only
+ * do the Uniscribe-style decomposition if the character is transformed into
+ * its "sec.half" form by the 'pstf' feature. Otherwise, we fall back to
+ * Unicode decomposition.
+ *
+ * Note that we can't unconditionally use Unicode decomposition. That would
+ * break some other fonts, that are designed to work with Uniscribe, and
+ * don't have positioning features for the Unicode-style decomposition.
+ *
+ * Argh...
+ *
+ * The Uniscribe behavior is now documented in the newly published Sinhala
+ * spec in 2012:
+ *
+ * http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping
+ */
+
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
+
+ hb_codepoint_t glyph;
+
+ if (hb_options ().uniscribe_bug_compatible ||
+ (c->font->get_nominal_glyph (ab, &glyph) &&
+ indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
+ {
+ /* Ok, safe to use Uniscribe-style decomposition. */
+ *a = 0x0DD9u;
+ *b = ab;
+ return true;
+ }
+ }
+
return (bool) c->unicode->decompose (ab, a, b);
}
@@ -1556,23 +1846,20 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
}
-const hb_ot_shaper_t _hb_ot_shaper_indic =
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
{
collect_features_indic,
override_features_indic,
data_create_indic,
data_destroy_indic,
- preprocess_text_indic,
+ nullptr, /* preprocess_text */
nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_indic,
compose_indic,
setup_masks_indic,
+ nullptr, /* disable_otl */
nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
-
-
-#endif
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
new file mode 100644
index 00000000000..ed87404305b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -0,0 +1,404 @@
+
+#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
+/*
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
+static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
+ 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, 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[] = {
+ 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, 32, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 32, 1
+};
+
+static const short _myanmar_syllable_machine_index_offsets[] = {
+ 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, 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,
+ 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, 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, 0, 6, 0, 0,
+ 7, 0, 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
+};
+
+static const char _myanmar_syllable_machine_to_state_actions[] = {
+ 1, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+static const char _myanmar_syllable_machine_from_state_actions[] = {
+ 2, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+static const short _myanmar_syllable_machine_eof_trans[] = {
+ 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;
+static const int myanmar_syllable_machine_first_final = 0;
+static const int myanmar_syllable_machine_error = -1;
+
+static const int myanmar_syllable_machine_en_main = 0;
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+
+#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 293 "hb-ot-shape-complex-myanmar-machine.hh"
+ {
+ cs = myanmar_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 115 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 310 "hb-ot-shape-complex-myanmar-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
+ case 2:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 324 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+ _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
+ _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
+
+ _slen = _myanmar_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
+ ( info[p].myanmar_category()) <= _keys[1] ?
+ ( info[p].myanmar_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _myanmar_syllable_machine_trans_targs[_trans];
+
+ if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
+ case 7:
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (consonant_syllable); }}
+ break;
+ case 5:
+#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+ break;
+ case 10:
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (punctuation_cluster); }}
+ break;
+ case 4:
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (broken_cluster); }}
+ break;
+ case 3:
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+ break;
+ case 6:
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (consonant_syllable); }}
+ break;
+ case 8:
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+ case 9:
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (non_myanmar_cluster); }}
+ break;
+#line 374 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+_again:
+ switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
+ case 1:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 383 "hb-ot-shape-complex-myanmar-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 124 "hb-ot-shape-complex-myanmar-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
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
new file mode 100644
index 00000000000..5ea1dbff27a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -0,0 +1,547 @@
+/*
+ * Copyright © 2011,2012,2013 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-ot-shape-complex-indic-private.hh"
+
+/* buffer var allocations */
+#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */
+#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */
+
+
+/*
+ * Myanmar shaper.
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+ /*
+ * Basic features.
+ * These features are applied in order, one at a time, after initial_reordering.
+ */
+ HB_TAG('r','p','h','f'),
+ HB_TAG('p','r','e','f'),
+ HB_TAG('b','l','w','f'),
+ HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
+ /*
+ * Other features.
+ * These features are applied all at once, after final_reordering.
+ */
+ HB_TAG('p','r','e','s'),
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('p','s','t','s'),
+ /* Positioning features, though we don't care about the types. */
+ HB_TAG('d','i','s','t'),
+ /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
+ * features. The released Windows 8 version of the font (as well
+ * as the released spec) used 'mark' instead. The Windows 8
+ * shaper however didn't apply 'mark' but did apply 'mkmk'.
+ * Perhaps it applied abvm/blwm. This was fixed in a Windows 8
+ * update, so now it applies mark/mkmk. We are guessing that
+ * it still applies abvm/blwm too.
+ */
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+ /* The Indic specs do not require ccmp, but we apply it here since if
+ * there is a use of it, it's typically at the beginning. */
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+
+ map->add_gsub_pause (initial_reordering);
+ 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 (nullptr);
+ }
+ map->add_gsub_pause (final_reordering);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+ map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+static void
+override_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+enum syllable_type_t {
+ consonant_syllable,
+ punctuation_cluster,
+ broken_cluster,
+ non_myanmar_cluster,
+};
+
+#include "hb-ot-shape-complex-myanmar-machine.hh"
+
+
+/* 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_D0 = 20, /* Digit zero */
+ OT_DB = OT_N, /* Dot below */
+ OT_GB = OT_PLACEHOLDER,
+ OT_MH = 21, /* Various consonant medial types */
+ OT_MR = 22, /* Various consonant medial types */
+ OT_MW = 23, /* Various consonant medial types */
+ OT_MY = 24, /* Various consonant medial types */
+ OT_PT = 25, /* Pwo and other tones */
+ OT_VAbv = 26,
+ OT_VBlw = 27,
+ OT_VPre = 28,
+ OT_VPst = 29,
+ OT_VS = 30, /* Variation selectors */
+ OT_P = 31, /* Punctuation */
+ OT_D = 32, /* Digits except zero */
+};
+
+
+static inline bool
+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_UNSAFE (info.myanmar_category()) & flags);
+}
+
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+ return is_one_of (info, CONSONANT_FLAGS);
+}
+
+
+static inline void
+set_myanmar_properties (hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ unsigned int type = hb_indic_get_categories (u);
+ indic_category_t cat = (indic_category_t) (type & 0x7Fu);
+ indic_position_t pos = (indic_position_t) (type >> 8);
+
+ /* Myanmar
+ * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
+ */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)))
+ cat = (indic_category_t) OT_VS;
+
+ switch (u)
+ {
+ case 0x104Eu:
+ cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+ break;
+
+ case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u:
+ case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u:
+ case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu:
+ case 0x25FEu:
+ cat = (indic_category_t) OT_GB;
+ break;
+
+ case 0x1004u: case 0x101Bu: case 0x105Au:
+ cat = (indic_category_t) OT_Ra;
+ break;
+
+ case 0x1032u: case 0x1036u:
+ cat = (indic_category_t) OT_A;
+ break;
+
+ case 0x1039u:
+ cat = (indic_category_t) OT_H;
+ break;
+
+ case 0x103Au:
+ cat = (indic_category_t) OT_As;
+ break;
+
+ case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u:
+ case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u:
+ case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u:
+ case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u:
+ case 0x1097u: case 0x1098u: case 0x1099u:
+ cat = (indic_category_t) OT_D;
+ break;
+
+ case 0x1040u:
+ cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
+ break;
+
+ case 0x103Eu: case 0x1060u:
+ cat = (indic_category_t) OT_MH;
+ break;
+
+ case 0x103Cu:
+ cat = (indic_category_t) OT_MR;
+ break;
+
+ case 0x103Du: case 0x1082u:
+ cat = (indic_category_t) OT_MW;
+ break;
+
+ case 0x103Bu: case 0x105Eu: case 0x105Fu:
+ cat = (indic_category_t) OT_MY;
+ break;
+
+ case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au:
+ case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu:
+ cat = (indic_category_t) OT_PT;
+ break;
+
+ case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u:
+ case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du:
+ case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu:
+ cat = (indic_category_t) OT_SM;
+ break;
+
+ case 0x104Au: case 0x104Bu:
+ cat = (indic_category_t) OT_P;
+ break;
+
+ case 0xAA74u: case 0xAA75u: case 0xAA76u:
+ /* https://github.com/roozbehp/unicode-data/issues/3 */
+ cat = (indic_category_t) OT_C;
+ break;
+ }
+
+ if (cat == OT_M)
+ {
+ switch ((int) pos)
+ {
+ case POS_PRE_C: cat = (indic_category_t) OT_VPre;
+ pos = POS_PRE_M; break;
+ case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
+ case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
+ case POS_POST_C: cat = (indic_category_t) OT_VPst; break;
+ }
+ }
+
+ info.myanmar_category() = (myanmar_category_t) cat;
+ info.myanmar_position() = pos;
+}
+
+
+
+static void
+setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
+ HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
+
+ /* We cannot setup masks here. We save information about characters
+ * and setup masks later on in a pause-callback. */
+
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ set_myanmar_properties (info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ find_syllables (buffer);
+ foreach_syllable (buffer, start, end)
+ buffer->unsafe_to_break (start, end);
+}
+
+static int
+compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ int a = pa->myanmar_position();
+ int b = pb->myanmar_position();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+/* Rules from:
+ * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */
+
+static void
+initial_reordering_consonant_syllable (hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int base = end;
+ bool has_reph = false;
+
+ {
+ unsigned int limit = start;
+ if (start + 3 <= end &&
+ info[start ].myanmar_category() == OT_Ra &&
+ info[start+1].myanmar_category() == OT_As &&
+ info[start+2].myanmar_category() == OT_H)
+ {
+ limit += 3;
+ base = start;
+ has_reph = true;
+ }
+
+ {
+ if (!has_reph)
+ base = limit;
+
+ for (unsigned int i = limit; i < end; i++)
+ if (is_consonant (info[i]))
+ {
+ base = i;
+ break;
+ }
+ }
+ }
+
+ /* Reorder! */
+ {
+ unsigned int i = start;
+ for (; i < start + (has_reph ? 3 : 0); i++)
+ info[i].myanmar_position() = POS_AFTER_MAIN;
+ for (; i < base; i++)
+ info[i].myanmar_position() = POS_PRE_C;
+ if (i < end)
+ {
+ info[i].myanmar_position() = POS_BASE_C;
+ i++;
+ }
+ indic_position_t pos = POS_AFTER_MAIN;
+ /* The following loop may be ugly, but it implements all of
+ * Myanmar reordering! */
+ for (; i < end; i++)
+ {
+ if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
+ {
+ info[i].myanmar_position() = POS_PRE_C;
+ continue;
+ }
+ if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
+ {
+ continue;
+ }
+
+ if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw)
+ {
+ pos = POS_BELOW_C;
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
+ {
+ info[i].myanmar_position() = POS_BEFORE_SUB;
+ continue;
+ }
+ if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
+ {
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+ if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
+ {
+ pos = POS_AFTER_SUB;
+ info[i].myanmar_position() = pos;
+ continue;
+ }
+ info[i].myanmar_position() = pos;
+ }
+ }
+
+ /* Sit tight, rock 'n roll! */
+ buffer->sort (start, end, compare_myanmar_order);
+}
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
+ hb_buffer_t *buffer,
+ unsigned int start, unsigned int end)
+{
+ syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+ switch (syllable_type) {
+
+ case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
+ case consonant_syllable:
+ initial_reordering_consonant_syllable (buffer, start, end);
+ break;
+
+ case punctuation_cluster:
+ case non_myanmar_cluster:
+ break;
+ }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+
+ hb_codepoint_t dottedcircle_glyph;
+ if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ dottedcircle.codepoint = 0x25CCu;
+ set_myanmar_properties (dottedcircle);
+ dottedcircle.codepoint = dottedcircle_glyph;
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len && !buffer->in_error)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
+
+ hb_glyph_info_t ginfo = dottedcircle;
+ ginfo.cluster = buffer->cur().cluster;
+ ginfo.mask = buffer->cur().mask;
+ ginfo.syllable() = buffer->cur().syllable();
+
+ buffer->output_info (ginfo);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ insert_dotted_circles (plan, font, buffer);
+
+ foreach_syllable (buffer, start, end)
+ initial_reordering_syllable (plan, font->face, buffer, start, end);
+}
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+
+ /* Zero syllables now... */
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
+}
+
+
+/* Uniscribe seems to have a shaper for 'mymr' that is like the
+ * generic shaper, except that it zeros mark advances GDEF_LATE. */
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
+{
+ nullptr, /* collect_features */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+ 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 =
+{
+ collect_features_myanmar,
+ override_features_myanmar,
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+ nullptr, /* decompose */
+ nullptr, /* compose */
+ setup_masks_myanmar,
+ 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-shaper.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index 0207b2bbe3f..fb2f61157a2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -24,22 +24,22 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPER_HH
-#define HB_OT_SHAPER_HH
+#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-ot-layout.hh"
-#include "hb-ot-shape.hh"
-#include "hb-ot-shape-normalize.hh"
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
-/* buffer var allocations, used by all OT shapers */
-#define ot_shaper_var_u8_category() var2.u8[2]
-#define ot_shaper_var_u8_auxiliary() var2.u8[3]
+/* buffer var allocations, used by complex shapers */
+#define complex_var_u8_0() var2.u8[2]
+#define complex_var_u8_1() var2.u8[3]
-#define HB_OT_SHAPE_MAX_COMBINING_MARKS 32
+
+#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,
@@ -49,27 +49,26 @@ enum hb_ot_shape_zero_width_marks_type_t {
/* Master OT shaper list */
-#define HB_OT_SHAPERS_IMPLEMENT_SHAPERS \
- HB_OT_SHAPER_IMPLEMENT (arabic) \
- HB_OT_SHAPER_IMPLEMENT (default) \
- HB_OT_SHAPER_IMPLEMENT (dumber) \
- HB_OT_SHAPER_IMPLEMENT (hangul) \
- HB_OT_SHAPER_IMPLEMENT (hebrew) \
- HB_OT_SHAPER_IMPLEMENT (indic) \
- HB_OT_SHAPER_IMPLEMENT (khmer) \
- HB_OT_SHAPER_IMPLEMENT (myanmar) \
- HB_OT_SHAPER_IMPLEMENT (myanmar_zawgyi) \
- HB_OT_SHAPER_IMPLEMENT (thai) \
- HB_OT_SHAPER_IMPLEMENT (use) \
- /* ^--- Add new shapers here; keep sorted. */
-
-
-struct hb_ot_shaper_t
+#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
+ HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
+ HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (use) \
+ /* ^--- Add new shapers here */
+
+
+struct hb_ot_complex_shaper_t
{
/* 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);
@@ -77,7 +76,7 @@ struct hb_ot_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);
@@ -93,7 +92,7 @@ struct hb_ot_shaper_t
* Called when the shape_plan is being destroyed.
* plan->data is passed here for destruction.
* If nullptr is returned, means a plan failure.
- * May be NULL.
+ * May be nullptr.
*/
void (*data_destroy) (void *data);
@@ -101,7 +100,7 @@ struct hb_ot_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,
@@ -110,16 +109,18 @@ struct hb_ot_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,
hb_font_t *font);
+ hb_ot_shape_normalization_mode_t normalization_preference;
+
/* 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,
@@ -128,7 +129,7 @@ struct hb_ot_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,
@@ -139,55 +140,70 @@ struct hb_ot_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,
hb_font_t *font);
+ /* disable_otl()
+ * Called during shape().
+ * If set and returns true, GDEF/GSUB/GPOS of the font are ignored
+ * and fallback operations used.
+ * 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 NULL.
+ * May be nullptr.
*/
void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start,
unsigned int end);
- /* gpos_tag()
- * If not HB_TAG_NONE, then must match found GPOS script tag for
- * GPOS to be applied. Otherwise, fallback positioning will be used.
- */
- hb_tag_t gpos_tag;
-
- hb_ot_shape_normalization_mode_t normalization_preference;
-
hb_ot_shape_zero_width_marks_type_t zero_width_marks;
bool fallback_position;
};
-#define HB_OT_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_shaper_t _hb_ot_shaper_##name;
-HB_OT_SHAPERS_IMPLEMENT_SHAPERS
-#undef HB_OT_SHAPER_IMPLEMENT
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
+HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
-static inline const hb_ot_shaper_t *
-hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
+static inline const hb_ot_complex_shaper_t *
+hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
{
switch ((hb_tag_t) planner->props.script)
{
default:
- return &_hb_ot_shaper_default;
+ return &_hb_ot_complex_shaper_default;
/* Unicode-1.1 additions */
case HB_SCRIPT_ARABIC:
/* Unicode-3.0 additions */
+ case HB_SCRIPT_MONGOLIAN:
case HB_SCRIPT_SYRIAC:
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_NKO:
+ case HB_SCRIPT_PHAGS_PA:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_MANDAIC:
+
+ /* Unicode-7.0 additions */
+ 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
@@ -195,29 +211,42 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
planner->props.script == HB_SCRIPT_ARABIC) &&
HB_DIRECTION_IS_HORIZONTAL(planner->props.direction))
- return &_hb_ot_shaper_arabic;
+ return &_hb_ot_complex_shaper_arabic;
else
- return &_hb_ot_shaper_default;
+ return &_hb_ot_complex_shaper_default;
/* Unicode-1.1 additions */
case HB_SCRIPT_THAI:
case HB_SCRIPT_LAO:
- return &_hb_ot_shaper_thai;
+ return &_hb_ot_complex_shaper_thai;
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
- return &_hb_ot_shaper_hangul;
+ return &_hb_ot_complex_shaper_hangul;
+
+
+ /* Unicode-2.0 additions */
+ case HB_SCRIPT_TIBETAN:
+
+ return &_hb_ot_complex_shaper_tibetan;
/* Unicode-1.1 additions */
case HB_SCRIPT_HEBREW:
- return &_hb_ot_shaper_hebrew;
+ return &_hb_ot_complex_shaper_hebrew;
+
+ /* ^--- Add new shapers here */
+
+#if 0
+ /* Unicode-4.1 additions */
+ case HB_SCRIPT_NEW_TAI_LUE:
+#endif
/* Unicode-1.1 additions */
case HB_SCRIPT_BENGALI:
@@ -230,53 +259,51 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_TAMIL:
case HB_SCRIPT_TELUGU:
+ /* Unicode-3.0 additions */
+ case HB_SCRIPT_SINHALA:
+
/* If the designer designed the font for the 'DFLT' script,
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
* Otherwise, use the specific shaper.
- *
- * If it's indy3 tag, send to USE. */
+ * 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') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
- return &_hb_ot_shaper_default;
- else if ((planner->map.chosen_script[0] & 0x000000FF) == '3')
- return &_hb_ot_shaper_use;
+ return &_hb_ot_complex_shaper_default;
else
- return &_hb_ot_shaper_indic;
+ return &_hb_ot_complex_shaper_indic;
case HB_SCRIPT_KHMER:
- return &_hb_ot_shaper_khmer;
+ /* A number of Khmer fonts in the wild don't have a 'pref' feature,
+ * and as such won't shape properly via the Indic shaper;
+ * however, they typically have 'liga' / 'clig' features that implement
+ * the necessary "reordering" by means of ligature substitutions.
+ * So we send such pref-less fonts through the generic shaper instead. */
+ if (planner->map.found_script[0] &&
+ hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
+ planner->map.script_index[0],
+ planner->map.language_index[0],
+ HB_TAG ('p','r','e','f'),
+ nullptr))
+ return &_hb_ot_complex_shaper_indic;
+ else
+ return &_hb_ot_complex_shaper_default;
case HB_SCRIPT_MYANMAR:
- /* If the designer designed the font for the 'DFLT' script,
- * (or we ended up arbitrarily pick 'latn'), use the default shaper.
- * Otherwise, use the specific shaper.
- *
- * If designer designed for 'mymr' tag, also send to default
- * shaper. That's tag used from before Myanmar shaping spec
- * was developed. The shaping spec uses 'mym2' tag. */
- if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
- planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') ||
- planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
- return &_hb_ot_shaper_default;
+ if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
+ return &_hb_ot_complex_shaper_myanmar;
+ else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
+ return &_hb_ot_complex_shaper_myanmar_old;
else
- return &_hb_ot_shaper_myanmar;
-
-
-#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
-#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g'))
- case HB_SCRIPT_MYANMAR_ZAWGYI:
- /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
-
- return &_hb_ot_shaper_myanmar_zawgyi;
-#endif
+ return &_hb_ot_complex_shaper_default;
/* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN:
+ //case HB_SCRIPT_TIBETAN:
/* Unicode-3.0 additions */
- case HB_SCRIPT_MONGOLIAN:
- case HB_SCRIPT_SINHALA:
+ //case HB_SCRIPT_MONGOLIAN:
+ //case HB_SCRIPT_SINHALA:
/* Unicode-3.2 additions */
case HB_SCRIPT_BUHID:
@@ -296,8 +323,8 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-5.0 additions */
case HB_SCRIPT_BALINESE:
- case HB_SCRIPT_NKO:
- case HB_SCRIPT_PHAGS_PA:
+ //case HB_SCRIPT_NKO:
+ //case HB_SCRIPT_PHAGS_PA:
/* Unicode-5.1 additions */
case HB_SCRIPT_CHAM:
@@ -318,11 +345,10 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-6.0 additions */
case HB_SCRIPT_BATAK:
case HB_SCRIPT_BRAHMI:
- case HB_SCRIPT_MANDAIC:
+ //case HB_SCRIPT_MANDAIC:
/* Unicode-6.1 additions */
case HB_SCRIPT_CHAKMA:
- case HB_SCRIPT_MIAO:
case HB_SCRIPT_SHARADA:
case HB_SCRIPT_TAKRI:
@@ -332,19 +358,18 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_KHOJKI:
case HB_SCRIPT_KHUDAWADI:
case HB_SCRIPT_MAHAJANI:
- case HB_SCRIPT_MANICHAEAN:
+ //case HB_SCRIPT_MANICHAEAN:
case HB_SCRIPT_MODI:
case HB_SCRIPT_PAHAWH_HMONG:
- case HB_SCRIPT_PSALTER_PAHLAVI:
+ //case HB_SCRIPT_PSALTER_PAHLAVI:
case HB_SCRIPT_SIDDHAM:
case HB_SCRIPT_TIRHUTA:
/* Unicode-8.0 additions */
case HB_SCRIPT_AHOM:
- case HB_SCRIPT_MULTANI:
+ //case HB_SCRIPT_MULTANI:
/* Unicode-9.0 additions */
- case HB_SCRIPT_ADLAM:
case HB_SCRIPT_BHAIKSUKI:
case HB_SCRIPT_MARCHEN:
case HB_SCRIPT_NEWA:
@@ -354,38 +379,6 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_SOYOMBO:
case HB_SCRIPT_ZANABAZAR_SQUARE:
- /* Unicode-11.0 additions */
- case HB_SCRIPT_DOGRA:
- case HB_SCRIPT_GUNJALA_GONDI:
- case HB_SCRIPT_HANIFI_ROHINGYA:
- case HB_SCRIPT_MAKASAR:
- case HB_SCRIPT_MEDEFAIDRIN:
- case HB_SCRIPT_OLD_SOGDIAN:
- case HB_SCRIPT_SOGDIAN:
-
- /* Unicode-12.0 additions */
- case HB_SCRIPT_ELYMAIC:
- case HB_SCRIPT_NANDINAGARI:
- case HB_SCRIPT_NYIAKENG_PUACHUE_HMONG:
- case HB_SCRIPT_WANCHO:
-
- /* Unicode-13.0 additions */
- case HB_SCRIPT_CHORASMIAN:
- case HB_SCRIPT_DIVES_AKURU:
- case HB_SCRIPT_KHITAN_SMALL_SCRIPT:
- case HB_SCRIPT_YEZIDI:
-
- /* Unicode-14.0 additions */
- case HB_SCRIPT_CYPRO_MINOAN:
- case HB_SCRIPT_OLD_UYGHUR:
- case HB_SCRIPT_TANGSA:
- case HB_SCRIPT_TOTO:
- case HB_SCRIPT_VITHKUQI:
-
- /* Unicode-15.0 additions */
- case HB_SCRIPT_KAWI:
- case HB_SCRIPT_NAG_MUNDARI:
-
/* If the designer designed the font for the 'DFLT' script,
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
* Otherwise, use the specific shaper.
@@ -393,11 +386,11 @@ hb_ot_shaper_categorize (const hb_ot_shape_planner_t *planner)
* GSUB/GPOS needed, so there may be no scripts found! */
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_shaper_default;
+ return &_hb_ot_complex_shaper_default;
else
- return &_hb_ot_shaper_use;
+ return &_hb_ot_complex_shaper_use;
}
}
-#endif /* HB_OT_SHAPER_HH */
+#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
index 6cd67cde35e..6ba925c675c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -24,11 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper.hh"
+#include "hb-ot-shape-complex-private.hh"
/* Thai / Lao shaper */
@@ -98,9 +94,9 @@ static hb_codepoint_t
thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
{
struct thai_pua_mapping_t {
- uint16_t u;
- uint16_t win_pua;
- uint16_t mac_pua;
+ hb_codepoint_t u;
+ hb_codepoint_t win_pua;
+ hb_codepoint_t mac_pua;
} const *pua_mappings = nullptr;
static const thai_pua_mapping_t SD_mappings[] = {
{0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */
@@ -222,10 +218,6 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font)
{
-#ifdef HB_NO_OT_SHAPER_THAI_FALLBACK
- return;
-#endif
-
thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
unsigned int base = 0;
@@ -268,7 +260,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
{
/* This function implements the shaping logic documented here:
*
- * https://linux.thai.net/~thep/th-otf/shaping.html
+ * http://linux.thai.net/~thep/th-otf/shaping.html
*
* The first shaping rule listed there is needed even if the font has Thai
* OpenType tables. The rest do fallback positioning based on PUA codepoints.
@@ -279,7 +271,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
* to be what Uniscribe and other engines implement. According to Eric Muller:
*
* When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
- * NIKHAHIT backwards over any above-base marks.
+ * NIKHAHIT backwards over any tone mark (0E48-0E4B).
*
* <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
*
@@ -308,8 +300,8 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
* Nikhahit: U+0E4D U+0ECD
*
* Testing shows that Uniscribe reorder the following marks:
- * Thai: <0E31,0E34..0E37, 0E47..0E4E>
- * Lao: <0EB1,0EB4..0EB7,0EBB,0EC8..0ECD>
+ * Thai: <0E31,0E34..0E37,0E47..0E4E>
+ * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
*
* Note how the Lao versions are the same as Thai + 0x80.
*/
@@ -319,23 +311,24 @@ 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_ABOVE_BASE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u, 0x0E3Bu, 0x0E3Bu))
+#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;
- for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;)
+ for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
{
hb_codepoint_t u = buffer->cur().codepoint;
- if (likely (!IS_SARA_AM (u)))
- {
- if (unlikely (!buffer->next_glyph ())) break;
+ if (likely (!IS_SARA_AM (u))) {
+ buffer->next_glyph ();
continue;
}
/* Is SARA AM. Decompose and reorder. */
- (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
- _hb_glyph_info_set_continuation (&buffer->prev());
- if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break;
+ hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
+ hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
+ buffer->replace_glyphs (1, 2, decomposed);
+ if (unlikely (buffer->in_error))
+ return;
/* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
unsigned int end = buffer->out_len;
@@ -343,7 +336,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
/* Ok, let's see... */
unsigned int start = end - 2;
- while (start > 0 && IS_ABOVE_BASE_MARK (buffer->out_info[start - 1].codepoint))
+ while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
start--;
if (start + 2 < end)
@@ -364,14 +357,14 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
buffer->merge_out_clusters (start - 1, end);
}
}
- buffer->sync ();
+ buffer->swap_buffers ();
/* If font has Thai GSUB, we are done. */
if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
do_thai_pua_shaping (plan, buffer, font);
}
-const hb_ot_shaper_t _hb_ot_shaper_thai =
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
{
nullptr, /* collect_features */
nullptr, /* override_features */
@@ -379,15 +372,12 @@ const hb_ot_shaper_t _hb_ot_shaper_thai =
nullptr, /* data_destroy */
preprocess_text_thai,
nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
nullptr, /* decompose */
nullptr, /* compose */
nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
false,/* fallback_position */
};
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
index 2243ee02874..eaac0bf689f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
@@ -1,5 +1,5 @@
/*
- * Copyright © 2018 Google, Inc.
+ * Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -24,35 +24,40 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-ot-face.hh"
+#include "hb-ot-shape-complex-private.hh"
-#include "hb-ot-cmap-table.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
-#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-kern-table.hh"
-#include "hb-ot-meta-table.hh"
-#include "hb-ot-name-table.hh"
-#include "hb-ot-post-table.hh"
-#include "OT/Color/CBDT/CBDT.hh"
-#include "OT/Color/sbix/sbix.hh"
-#include "OT/Color/svg/svg.hh"
-#include "hb-ot-layout-gdef-table.hh"
-#include "hb-ot-layout-gsub-table.hh"
-#include "hb-ot-layout-gpos-table.hh"
+static const hb_tag_t tibetan_features[] =
+{
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+ HB_TAG_NONE
+};
-void hb_ot_face_t::init0 (hb_face_t *face)
+static void
+collect_features_tibetan (hb_ot_shape_planner_t *plan)
{
- this->face = face;
-#define HB_OT_TABLE(Namespace, Type) Type.init0 ();
-#include "hb-ot-face-table-list.hh"
-#undef HB_OT_TABLE
+ for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
+ plan->map.add_global_bool_feature (*script_features);
}
-void hb_ot_face_t::fini ()
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
{
-#define HB_OT_TABLE(Namespace, Type) Type.fini ();
-#include "hb-ot-face-table-list.hh"
-#undef HB_OT_TABLE
-}
+ collect_features_tibetan,
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+ 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
new file mode 100644
index 00000000000..4f6727186de
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh
@@ -0,0 +1,459 @@
+
+#line 1 "hb-ot-shape-complex-use-machine.rl"
+/*
+ * Copyright © 2015 Mozilla Foundation.
+ * Copyright © 2015 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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 38 "hb-ot-shape-complex-use-machine.hh"
+static const unsigned char _use_syllable_machine_trans_keys[] = {
+ 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, 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, 44, 1, 32, 32, 1, 32, 32,
+ 32, 19, 19, 19, 32, 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, 32, 1, 39, 32,
+ 22, 2, 1, 5
+};
+
+static const short _use_syllable_machine_index_offsets[] = {
+ 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[] = {
+ 1, 0, 2, 3, 4, 2, 5, 3,
+ 4, 4, 6, 4, 4, 1, 7, 4,
+ 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, 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, 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, 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, 0, 7, 8, 9, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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[] = {
+ 0, 3, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static const char _use_syllable_machine_from_state_actions[] = {
+ 0, 4, 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, 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, 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;
+static const int use_syllable_machine_first_final = 1;
+static const int use_syllable_machine_error = -1;
+
+static const int use_syllable_machine_en_main = 1;
+
+
+#line 38 "hb-ot-shape-complex-use-machine.rl"
+
+
+
+#line 140 "hb-ot-shape-complex-use-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+ HB_STMT_START { \
+ if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+ for (unsigned int i = last; i < p+1; i++) \
+ info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+ last = p+1; \
+ syllable_serial++; \
+ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+ } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+ int cs;
+ hb_glyph_info_t *info = buffer->info;
+
+#line 324 "hb-ot-shape-complex-use-machine.hh"
+ {
+ cs = use_syllable_machine_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 161 "hb-ot-shape-complex-use-machine.rl"
+
+
+ p = 0;
+ pe = eof = buffer->len;
+
+ unsigned int last = 0;
+ unsigned int syllable_serial = 1;
+
+#line 341 "hb-ot-shape-complex-use-machine.hh"
+ {
+ int _slen;
+ int _trans;
+ const unsigned char *_keys;
+ const char *_inds;
+ if ( p == pe )
+ goto _test_eof;
+_resume:
+ switch ( _use_syllable_machine_from_state_actions[cs] ) {
+ case 4:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 355 "hb-ot-shape-complex-use-machine.hh"
+ }
+
+ _keys = _use_syllable_machine_trans_keys + (cs<<1);
+ _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
+
+ _slen = _use_syllable_machine_key_spans[cs];
+ _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) &&
+ ( info[p].use_category()) <= _keys[1] ?
+ ( info[p].use_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+ cs = _use_syllable_machine_trans_targs[_trans];
+
+ if ( _use_syllable_machine_trans_actions[_trans] == 0 )
+ goto _again;
+
+ switch ( _use_syllable_machine_trans_actions[_trans] ) {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 8:
+#line 129 "hb-ot-shape-complex-use-machine.rl"
+ {te = p+1;{ found_syllable (independent_cluster); }}
+ break;
+ case 10:
+#line 131 "hb-ot-shape-complex-use-machine.rl"
+ {te = p+1;{ found_syllable (standard_cluster); }}
+ break;
+ case 6:
+#line 135 "hb-ot-shape-complex-use-machine.rl"
+ {te = p+1;{ found_syllable (broken_cluster); }}
+ break;
+ case 5:
+#line 136 "hb-ot-shape-complex-use-machine.rl"
+ {te = p+1;{ found_syllable (non_cluster); }}
+ break;
+ case 7:
+#line 129 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (independent_cluster); }}
+ break;
+ case 11:
+#line 130 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (virama_terminated_cluster); }}
+ break;
+ case 9:
+#line 131 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (standard_cluster); }}
+ break;
+ case 13:
+#line 132 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
+ break;
+ case 12:
+#line 133 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (numeral_cluster); }}
+ break;
+ case 16:
+#line 134 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (symbol_cluster); }}
+ break;
+ case 14:
+#line 135 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (broken_cluster); }}
+ break;
+ case 15:
+#line 136 "hb-ot-shape-complex-use-machine.rl"
+ {te = p;p--;{ found_syllable (non_cluster); }}
+ break;
+ case 1:
+#line 135 "hb-ot-shape-complex-use-machine.rl"
+ {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
+ break;
+#line 429 "hb-ot-shape-complex-use-machine.hh"
+ }
+
+_again:
+ switch ( _use_syllable_machine_to_state_actions[cs] ) {
+ case 3:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 438 "hb-ot-shape-complex-use-machine.hh"
+ }
+
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
+ _trans = _use_syllable_machine_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ }
+
+#line 170 "hb-ot-shape-complex-use-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */
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
new file mode 100644
index 00000000000..3e763ae3936
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2015 Mozilla Foundation.
+ * Copyright © 2015 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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+#define USE_TABLE_ELEMENT_TYPE uint8_t
+
+/* Cateories used in the Universal Shaping Engine spec:
+ * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum use_category_t {
+ USE_O = 0, /* OTHER */
+
+ USE_B = 1, /* BASE */
+ USE_IND = 3, /* BASE_IND */
+ USE_N = 4, /* BASE_NUM */
+ USE_GB = 5, /* BASE_OTHER */
+ USE_CGJ = 6, /* CGJ */
+// USE_F = 7, /* CONS_FINAL */
+ USE_FM = 8, /* CONS_FINAL_MOD */
+// USE_M = 9, /* CONS_MED */
+// USE_CM = 10, /* CONS_MOD */
+ USE_SUB = 11, /* CONS_SUB */
+ USE_H = 12, /* HALANT */
+
+ USE_HN = 13, /* HALANT_NUM */
+ USE_ZWNJ = 14, /* Zero width non-joiner */
+ USE_ZWJ = 15, /* Zero width joiner */
+ USE_WJ = 16, /* Word joiner */
+ USE_Rsv = 17, /* Reserved characters */
+ USE_R = 18, /* REPHA */
+ USE_S = 19, /* SYM */
+// USE_SM = 20, /* SYM_MOD */
+ USE_VS = 21, /* VARIATION_SELECTOR */
+// USE_V = 36, /* VOWEL */
+// USE_VM = 40, /* VOWEL_MOD */
+
+ USE_FAbv = 24, /* CONS_FINAL_ABOVE */
+ USE_FBlw = 25, /* CONS_FINAL_BELOW */
+ USE_FPst = 26, /* CONS_FINAL_POST */
+ USE_MAbv = 27, /* CONS_MED_ABOVE */
+ USE_MBlw = 28, /* CONS_MED_BELOW */
+ USE_MPst = 29, /* CONS_MED_POST */
+ USE_MPre = 30, /* CONS_MED_PRE */
+ USE_CMAbv = 31, /* CONS_MOD_ABOVE */
+ USE_CMBlw = 32, /* CONS_MOD_BELOW */
+ USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */
+ USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */
+ USE_VPst = 35, /* VOWEL_POST UIPC = Right */
+ USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */
+ USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */
+ USE_VMBlw = 38, /* VOWEL_MOD_BELOW */
+ 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_CS = 43 /* CONS_WITH_STACKER */
+};
+
+HB_INTERNAL USE_TABLE_ELEMENT_TYPE
+hb_use_get_categories (hb_codepoint_t u);
+
+#endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */
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
new file mode 100644
index 00000000000..fd6978f281e
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc
@@ -0,0 +1,777 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # 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.
+ */
+
+#include "hb-ot-shape-complex-use-private.hh"
+
+#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 */
+#define HN USE_HN /* HALANT_NUM */
+#define IND USE_IND /* BASE_IND */
+#define N USE_N /* BASE_NUM */
+#define O USE_O /* OTHER */
+#define R USE_R /* REPHA */
+#define Rsv USE_Rsv /* Reserved */
+#define S USE_S /* SYM */
+#define SUB USE_SUB /* CONS_SUB */
+#define VS USE_VS /* VARIATION_SELECTOR */
+#define WJ USE_WJ /* Word_Joiner */
+#define ZWJ USE_ZWJ /* ZWJ */
+#define ZWNJ USE_ZWNJ /* ZWNJ */
+#define CMBlw USE_CMBlw
+#define CMAbv USE_CMAbv
+#define FBlw USE_FBlw
+#define FPst USE_FPst
+#define FAbv USE_FAbv
+#define MPre USE_MPre
+#define MBlw USE_MBlw
+#define MPst USE_MPst
+#define MAbv USE_MAbv
+#define SMBlw USE_SMBlw
+#define SMAbv USE_SMAbv
+#define VPre USE_VPre
+#define VBlw USE_VBlw
+#define VPst USE_VPst
+#define VAbv USE_VAbv
+#define VMPre USE_VMPre
+#define VMBlw USE_VMBlw
+#define VMPst USE_VMPst
+#define VMAbv USE_VMAbv
+
+static const USE_TABLE_ELEMENT_TYPE use_table[] = {
+
+
+#define use_offset_0x0028u 0
+
+
+ /* Basic Latin */
+ O, O, O, O, O, GB, O, O,
+ /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+#define use_offset_0x00a0u 24
+
+
+ /* Latin-1 Supplement */
+
+ /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 00B0 */ O, O, FM, FM, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 00D0 */ O, O, O, O, O, O, O, GB,
+
+#define use_offset_0x0900u 80
+
+
+ /* Devanagari */
+
+ /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre,
+ /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst,
+ /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B,
+ /* 0960 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0970 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+
+ /* Bengali */
+
+ /* 0980 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B,
+ /* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
+ /* 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, B, O, O, O,
+
+ /* Gurmukhi */
+
+ /* 0A00 */ O, VMAbv, VMAbv, VMPst, O, B, B, B, B, B, B, O, O, O, O, B,
+ /* 0A10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CMBlw, O, VPst, VPre,
+ /* 0A40 */ VPst, VBlw, VBlw, O, O, O, O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O,
+ /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O,
+ /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, O, O, O, O, O, O, O, O, O,
+
+ /* Gujarati */
+
+ /* 0A80 */ O, VMAbv, VMAbv, VMPst, O, B, B, B, B, B, B, B, B, B, O, B,
+ /* 0A90 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
+ /* 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, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
+
+ /* Oriya */
+
+ /* 0B00 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B,
+ /* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv,
+ /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
+ /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B,
+ /* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Tamil */
+
+ /* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B,
+ /* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B,
+ /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B,
+ /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst,
+ /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O,
+ /* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
+ /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Telugu */
+
+ /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
+ /* 0C10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv,
+ /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O,
+ /* 0C50 */ O, O, O, O, O, VAbv, VBlw, O, B, B, B, O, O, O, O, O,
+ /* 0C60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Kannada */
+
+ /* 0C80 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
+ /* 0C90 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv,
+ /* 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, CS, CS, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Malayalam */
+
+ /* 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, 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,
+ /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND,
+
+ /* Sinhala */
+
+ /* 0D80 */ O, O, VMPst, VMPst, O, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0D90 */ B, B, B, B, B, B, B, O, O, O, B, B, B, B, B, B,
+ /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O,
+ /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst,
+ /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst,
+ /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
+ /* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
+
+#define use_offset_0x1000u 1352
+
+
+ /* Myanmar */
+
+ /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1020 */ B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VAbv, VAbv, VBlw,
+ /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, H, VAbv, MPst, MPre, MBlw, MBlw, B,
+ /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O,
+ /* 1050 */ B, B, B, B, B, B, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw,
+ /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B,
+ /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst,
+ /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O,
+
+#define use_offset_0x1700u 1512
+
+
+ /* Tagalog */
+
+ /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, B,
+ /* 1710 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Hanunoo */
+
+ /* 1720 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1730 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Buhid */
+
+ /* 1740 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1750 */ B, B, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Tagbanwa */
+
+ /* 1760 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, B,
+ /* 1770 */ B, O, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Khmer */
+
+ /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre,
+ /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM,
+ /* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O,
+ /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+#define use_offset_0x1900u 1752
+
+
+ /* Limbu */
+
+ /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O,
+ /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O,
+ /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FM, O, O, O, O,
+ /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
+
+ /* Tai Le */
+
+ /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, O,
+ /* 1970 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* New Tai Lue */
+
+ /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
+ /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 19C0 */ B, B, B, B, B, B, B, B, VMPst, VMPst, O, O, O, O, O, O,
+ /* 19D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Buginese */
+
+ /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O,
+
+ /* Tai Tham */
+
+ /* 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, 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, 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,
+
+#define use_offset_0x1b00u 2168
+
+
+ /* Balinese */
+
+ /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre,
+ /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
+ /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+ /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Sundanese */
+
+ /* 1B80 */ VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, H, SUB, SUB, B, B,
+ /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+
+ /* Batak */
+
+ /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1BE0 */ B, B, B, B, B, B, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv,
+ /* 1BF0 */ FAbv, FAbv, VPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Lepcha */
+
+ /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
+ /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O,
+ /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
+
+#define use_offset_0x1cd0u 2504
+
+
+ /* Vedic Extensions */
+
+ /* 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, VMPst, VMAbv, VMAbv, O, O, O, O, O, O,
+
+#define use_offset_0x1df8u 2552
+
+
+ /* Combining Diacritical Marks Supplement */
+ O, O, O, FM, O, O, O, O,
+
+#define use_offset_0x2008u 2560
+
+
+ /* General Punctuation */
+ O, O, O, O, ZWNJ, ZWJ, O, O,
+ /* 2010 */ GB, GB, GB, GB, GB, O, O, O,
+
+#define use_offset_0x2060u 2576
+
+ /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Superscripts and Subscripts */
+
+ /* 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_0x20f0u 2616
+
+
+ /* Combining Diacritical Marks for Symbols */
+
+ /* 20F0 */ VMAbv, O, O, O, O, O, O, O,
+
+#define use_offset_0xa800u 2624
+
+
+ /* Syloti Nagri */
+
+ /* A800 */ B, B, O, B, B, B, VAbv, B, B, B, B, VMAbv, B, B, B, B,
+ /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, O, O, O, O,
+ /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Phags-pa */
+
+ /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A870 */ B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Saurashtra */
+
+ /* 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, 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, B, B, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Kayah Li */
+
+ /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A920 */ B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VAbv, VMBlw, VMBlw, VMBlw, O, O,
+
+ /* Rejang */
+
+ /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* A940 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv,
+ /* A950 */ FAbv, FAbv, FPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Javanese */
+
+ /* 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, 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,
+
+ /* Myanmar Extended-B */
+
+ /* A9E0 */ B, B, B, B, B, VAbv, O, B, B, B, B, B, B, B, B, B,
+ /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O,
+
+ /* Cham */
+
+ /* 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, 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,
+
+ /* Myanmar Extended-A */
+
+ /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* AA70 */ O, B, B, B, GB, GB, GB, O, O, O, B, VMPst, VMAbv, VMPst, B, B,
+
+ /* Tai Viet */
+
+ /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* AAB0 */ VAbv, B, VAbv, VAbv, VBlw, B, B, VAbv, VAbv, B, B, B, B, B, VAbv, VMAbv,
+ /* AAC0 */ B, VMAbv, B, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* AAD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Meetei Mayek Extensions */
+
+ /* 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 3384
+
+
+ /* Meetei Mayek */
+
+ /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* ABD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 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 3448
+
+
+ /* Variation Selectors */
+
+ /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS,
+
+#define use_offset_0x10a00u 3464
+
+
+ /* Kharoshthi */
+
+ /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv,
+ /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B,
+ /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 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 3536
+
+
+ /* Brahmi */
+
+ /* 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,
+ /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O,
+ /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+ /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B,
+ /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Kaithi */
+
+ /* 11080 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 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 3728
+
+
+ /* Chakma */
+
+ /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv,
+ /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B,
+ /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Mahajani */
+
+ /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11170 */ B, B, B, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Sharada */
+
+ /* 11180 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,
+ /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CMBlw, VAbv, VBlw, O, O, O,
+ /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+ /* Sinhala Archaic Numbers */
+
+ /* 111E0 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 111F0 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Khojki */
+
+ /* 11200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 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 4048
+
+
+ /* Multani */
+
+ /* 11280 */ B, B, B, B, B, B, B, O, B, O, B, B, B, B, O, B,
+ /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B,
+ /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
+
+ /* Khudawadi */
+
+ /* 112B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv,
+ /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, O, O, O, O, O,
+ /* 112F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+ /* Grantha */
+
+ /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B,
+ /* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 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, 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 4296
+
+
+ /* Newa */
+
+ /* 11400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv,
+ /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O,
+ /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 11460 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 11470 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Tirhuta */
+
+ /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv,
+ /* 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 4520
+
+
+ /* Siddham */
+
+ /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst,
+ /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H,
+ /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O,
+ /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Modi */
+
+ /* 11600 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H,
+ /* 11640 */ VAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 11650 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 11670 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Takri */
+
+ /* 11680 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst,
+ /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, O, O, O, O, O, O, O, O,
+ /* 116C0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+ /* 116D0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 116E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 116F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+
+ /* Ahom */
+
+ /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, MBlw, MPre, MAbv,
+ /* 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_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 */
+
+ /* 11C00 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
+ /* 11C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst,
+ /* 11C30 */ VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VBlw, O, VAbv, VAbv, VAbv, VAbv, VMAbv, VMAbv, VMPst, H,
+ /* 11C40 */ B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 11C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
+
+ /* Marchen */
+
+ /* 11C70 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11C90 */ O, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
+ /* 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,
+
+#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)
+{
+ switch (u >> 12)
+ {
+ case 0x0u:
+ 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<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<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<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<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
+ break;
+
+ case 0x10u:
+ 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<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;
+
+ default:
+ break;
+ }
+ return USE_O;
+}
+
+#undef B
+#undef CGJ
+#undef CS
+#undef FM
+#undef GB
+#undef H
+#undef HN
+#undef IND
+#undef N
+#undef O
+#undef R
+#undef Rsv
+#undef S
+#undef SUB
+#undef VS
+#undef WJ
+#undef ZWJ
+#undef ZWNJ
+#undef CMBlw
+#undef CMAbv
+#undef FBlw
+#undef FPst
+#undef FAbv
+#undef MPre
+#undef MBlw
+#undef MPst
+#undef MAbv
+#undef SMBlw
+#undef SMAbv
+#undef VPre
+#undef VBlw
+#undef VPst
+#undef VAbv
+#undef VMPre
+#undef VMBlw
+#undef VMPst
+#undef VMAbv
+
+/* == End of generated table == */
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
new file mode 100644
index 00000000000..62acd697bdd
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc
@@ -0,0 +1,612 @@
+/*
+ * Copyright © 2015 Mozilla Foundation.
+ * Copyright © 2015 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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-use-private.hh"
+#include "hb-ot-shape-complex-arabic-private.hh"
+
+/* buffer var allocations */
+#define use_category() complex_var_u8_0()
+
+
+/*
+ * Universal Shaping Engine.
+ * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+ /*
+ * Basic features.
+ * These features are applied all at once, before reordering.
+ */
+ HB_TAG('r','k','r','f'),
+ HB_TAG('a','b','v','f'),
+ HB_TAG('b','l','w','f'),
+ HB_TAG('h','a','l','f'),
+ HB_TAG('p','s','t','f'),
+ HB_TAG('v','a','t','u'),
+ HB_TAG('c','j','c','t'),
+};
+static const hb_tag_t
+arabic_features[] =
+{
+ HB_TAG('i','s','o','l'),
+ HB_TAG('i','n','i','t'),
+ HB_TAG('m','e','d','i'),
+ HB_TAG('f','i','n','a'),
+ /* The spec doesn't specify these but we apply anyway, since our Arabic shaper
+ * does. These are only used in Syriac spec. */
+ HB_TAG('m','e','d','2'),
+ HB_TAG('f','i','n','2'),
+ HB_TAG('f','i','n','3'),
+};
+/* Same order as arabic_features. Don't need Syriac stuff.*/
+enum joining_form_t {
+ ISOL,
+ INIT,
+ MEDI,
+ FINA,
+ _NONE
+};
+static const hb_tag_t
+other_features[] =
+{
+ /*
+ * Other features.
+ * These features are applied all at once, after reordering.
+ */
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('h','a','l','n'),
+ HB_TAG('p','r','e','s'),
+ HB_TAG('p','s','t','s'),
+ /* Positioning features, though we don't care about the types. */
+ HB_TAG('d','i','s','t'),
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+clear_substitution_flags (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+record_rphf (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+record_pref (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
+reorder (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
+collect_features_use (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
+ /* "Default glyph pre-processing group" */
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('n','u','k','t'));
+ map->add_global_bool_feature (HB_TAG('a','k','h','n'));
+
+ /* "Reordering group" */
+ map->add_gsub_pause (clear_substitution_flags);
+ map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ);
+ map->add_gsub_pause (record_rphf);
+ map->add_gsub_pause (clear_substitution_flags);
+ map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ);
+ map->add_gsub_pause (record_pref);
+
+ /* "Orthographic unit shaping group" */
+ 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 (reorder);
+
+ /* "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 (nullptr);
+
+ /* "Standard typographic presentation" and "Positional feature application" */
+ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+ map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+struct use_shape_plan_t
+{
+ ASSERT_POD ();
+
+ hb_mask_t rphf_mask;
+
+ arabic_shape_plan_t *arabic_plan;
+};
+
+static bool
+has_arabic_joining (hb_script_t script)
+{
+ /* List of scripts that have data in arabic-table. */
+ switch ((int) script)
+ {
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_ARABIC:
+
+ /* Unicode-3.0 additions */
+ case HB_SCRIPT_MONGOLIAN:
+ case HB_SCRIPT_SYRIAC:
+
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_NKO:
+ case HB_SCRIPT_PHAGS_PA:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_MANDAIC:
+
+ /* Unicode-7.0 additions */
+ case HB_SCRIPT_MANICHAEAN:
+ case HB_SCRIPT_PSALTER_PAHLAVI:
+
+ /* Unicode-9.0 additions */
+ case HB_SCRIPT_ADLAM:
+
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static void *
+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 nullptr;
+
+ use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f'));
+
+ if (has_arabic_joining (plan->props.script))
+ {
+ use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan);
+ if (unlikely (!use_plan->arabic_plan))
+ {
+ free (use_plan);
+ return nullptr;
+ }
+ }
+
+ return use_plan;
+}
+
+static void
+data_destroy_use (void *data)
+{
+ use_shape_plan_t *use_plan = (use_shape_plan_t *) data;
+
+ if (use_plan->arabic_plan)
+ data_destroy_arabic (use_plan->arabic_plan);
+
+ free (data);
+}
+
+enum syllable_type_t {
+ independent_cluster,
+ virama_terminated_cluster,
+ standard_cluster,
+ number_joiner_terminated_cluster,
+ numeral_cluster,
+ symbol_cluster,
+ broken_cluster,
+ non_cluster,
+};
+
+#include "hb-ot-shape-complex-use-machine.hh"
+
+
+static void
+setup_masks_use (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+ /* Do this before allocating use_category(). */
+ if (use_plan->arabic_plan)
+ {
+ setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script);
+ }
+
+ HB_BUFFER_ALLOCATE_VAR (buffer, use_category);
+
+ /* We cannot setup masks here. We save information about characters
+ * and setup masks later on in a pause-callback. */
+
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].use_category() = hb_use_get_categories (info[i].codepoint);
+}
+
+static void
+setup_rphf_mask (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer)
+{
+ const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+ hb_mask_t mask = use_plan->rphf_mask;
+ if (!mask) return;
+
+ hb_glyph_info_t *info = buffer->info;
+
+ foreach_syllable (buffer, start, end)
+ {
+ unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start);
+ for (unsigned int i = start; i < start + limit; i++)
+ info[i].mask |= mask;
+ }
+}
+
+static void
+setup_topographical_masks (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer)
+{
+ const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+ if (use_plan->arabic_plan)
+ return;
+
+ 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++)
+ {
+ masks[i] = plan->map.get_1_mask (arabic_features[i]);
+ if (masks[i] == plan->map.get_global_mask ())
+ masks[i] = 0;
+ all_masks |= masks[i];
+ }
+ if (!all_masks)
+ return;
+ hb_mask_t other_masks = ~all_masks;
+
+ unsigned int last_start = 0;
+ joining_form_t last_form = _NONE;
+ hb_glyph_info_t *info = buffer->info;
+ foreach_syllable (buffer, start, end)
+ {
+ syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
+ switch (syllable_type)
+ {
+ case independent_cluster:
+ case symbol_cluster:
+ case non_cluster:
+ /* These don't join. Nothing to do. */
+ last_form = _NONE;
+ break;
+
+ case virama_terminated_cluster:
+ case standard_cluster:
+ case number_joiner_terminated_cluster:
+ case numeral_cluster:
+ case broken_cluster:
+
+ bool join = last_form == FINA || last_form == ISOL;
+
+ if (join)
+ {
+ /* Fixup previous syllable's form. */
+ last_form = last_form == FINA ? MEDI : INIT;
+ for (unsigned int i = last_start; i < start; i++)
+ info[i].mask = (info[i].mask & other_masks) | masks[last_form];
+ }
+
+ /* Form for this syllable. */
+ last_form = join ? FINA : ISOL;
+ for (unsigned int i = start; i < end; i++)
+ info[i].mask = (info[i].mask & other_masks) | masks[last_form];
+
+ break;
+ }
+
+ last_start = start;
+ }
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ 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);
+}
+
+static void
+clear_substitution_flags (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ _hb_glyph_info_clear_substituted (&info[i]);
+}
+
+static void
+record_rphf (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+ hb_mask_t mask = use_plan->rphf_mask;
+ if (!mask) return;
+ hb_glyph_info_t *info = buffer->info;
+
+ foreach_syllable (buffer, start, end)
+ {
+ /* Mark a substituted repha as USE_R. */
+ for (unsigned int i = start; i < end && (info[i].mask & mask); i++)
+ if (_hb_glyph_info_substituted (&info[i]))
+ {
+ info[i].use_category() = USE_R;
+ break;
+ }
+ }
+}
+
+static void
+record_pref (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+
+ foreach_syllable (buffer, start, end)
+ {
+ /* Mark a substituted pref as VPre, as they behave the same way. */
+ for (unsigned int i = start; i < end; i++)
+ if (_hb_glyph_info_substituted (&info[i]))
+ {
+ info[i].use_category() = USE_VPre;
+ break;
+ }
+ }
+}
+
+static inline bool
+is_halant (const hb_glyph_info_t &info)
+{
+ return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info);
+}
+
+static void
+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_UNSAFE (syllable_type) &
+ (FLAG (virama_terminated_cluster) |
+ FLAG (standard_cluster) |
+ FLAG (broken_cluster) |
+ 0))))
+ return;
+
+ hb_glyph_info_t *info = buffer->info;
+
+#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB))
+
+ /* Move things forward. */
+ if (info[start].use_category() == USE_R && end - start > 1)
+ {
+ /* Got a repha. Reorder it to after first base, before first halant. */
+ for (unsigned int i = start + 1; i < end; i++)
+ if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i]))
+ {
+ /* If we hit a halant, move before it; otherwise it's a base: move to it's
+ * place, and shift things in between backward. */
+
+ if (is_halant (info[i]))
+ i--;
+
+ buffer->merge_clusters (start, i + 1);
+ hb_glyph_info_t t = info[start];
+ memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]));
+ info[i] = t;
+
+ break;
+ }
+ }
+
+ /* Move things back. */
+ unsigned int j = end;
+ for (unsigned int i = start; i < end; i++)
+ {
+ uint32_t flag = FLAG_UNSAFE (info[i].use_category());
+ if ((flag & (BASE_FLAGS)) || is_halant (info[i]))
+ {
+ /* If we hit a halant, move after it; otherwise it's a base: move to it's
+ * place, and shift things in between backward. */
+ if (is_halant (info[i]))
+ j = i + 1;
+ else
+ j = i;
+ }
+ else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) &&
+ /* Only move the first component of a MultipleSubst. */
+ 0 == _hb_glyph_info_get_lig_comp (&info[i]) &&
+ j < i)
+ {
+ buffer->merge_clusters (j, i + 1);
+ hb_glyph_info_t t = info[i];
+ memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0]));
+ info[j] = t;
+ }
+ }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+ hb_glyph_info_t dottedcircle = {0};
+ if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint))
+ return;
+ dottedcircle.use_category() = hb_use_get_categories (0x25CC);
+
+ buffer->clear_output ();
+
+ buffer->idx = 0;
+ unsigned int last_syllable = 0;
+ while (buffer->idx < buffer->len && !buffer->in_error)
+ {
+ unsigned int syllable = buffer->cur().syllable();
+ syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+ if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+ {
+ last_syllable = syllable;
+
+ hb_glyph_info_t ginfo = dottedcircle;
+ ginfo.cluster = buffer->cur().cluster;
+ ginfo.mask = buffer->cur().mask;
+ ginfo.syllable() = buffer->cur().syllable();
+ /* TODO Set glyph_props? */
+
+ /* Insert dottedcircle after possible Repha. */
+ while (buffer->idx < buffer->len && !buffer->in_error &&
+ last_syllable == buffer->cur().syllable() &&
+ buffer->cur().use_category() == USE_R)
+ buffer->next_glyph ();
+
+ buffer->output_info (ginfo);
+ }
+ else
+ buffer->next_glyph ();
+ }
+
+ buffer->swap_buffers ();
+}
+
+static void
+reorder (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
+{
+ insert_dotted_circles (plan, font, buffer);
+
+ hb_glyph_info_t *info = buffer->info;
+
+ foreach_syllable (buffer, start, end)
+ reorder_syllable (buffer, start, end);
+
+ /* Zero syllables now... */
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
+}
+
+static bool
+decompose_use (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
+{
+ switch (ab)
+ {
+ /* Chakma:
+ * Special case where the Unicode decomp gives matras in the wrong order
+ * for cluster validation.
+ */
+ case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true;
+ case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true;
+ }
+
+ return (bool) c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_use (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ /* Avoid recomposing split matras. */
+ if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
+ return false;
+
+ return (bool)c->unicode->compose (a, b, ab);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
+{
+ collect_features_use,
+ nullptr, /* override_features */
+ data_create_use,
+ data_destroy_use,
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+ decompose_use,
+ compose_use,
+ setup_masks_use,
+ 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.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
index 5faf5f2dfb1..e134224df92 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh
@@ -24,22 +24,21 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_FALLBACK_HH
-#define HB_OT_SHAPE_FALLBACK_HH
+#ifndef HB_OT_SHAPE_FALLBACK_PRIVATE_HH
+#define HB_OT_SHAPE_FALLBACK_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-ot-shape.hh"
+#include "hb-ot-shape-private.hh"
-HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- bool adjust_offsets_when_zeroing);
+HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
-HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
+HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
@@ -51,4 +50,4 @@ HB_INTERNAL void _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer);
-#endif /* HB_OT_SHAPE_FALLBACK_HH */
+#endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */
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 b2eedb027bb..458c8eaa048 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -24,12 +24,8 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shape-fallback.hh"
-#include "hb-kern.hh"
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-layout-gsubgpos-private.hh"
static unsigned int
recategorize_combining_class (hb_codepoint_t u,
@@ -45,30 +41,30 @@ recategorize_combining_class (hb_codepoint_t u,
{
switch (u)
{
- case 0x0E31u:
- case 0x0E34u:
- case 0x0E35u:
- case 0x0E36u:
- case 0x0E37u:
- case 0x0E47u:
- case 0x0E4Cu:
- case 0x0E4Du:
- case 0x0E4Eu:
+ case 0x0E31u:
+ case 0x0E34u:
+ case 0x0E35u:
+ case 0x0E36u:
+ case 0x0E37u:
+ case 0x0E47u:
+ case 0x0E4Cu:
+ case 0x0E4Du:
+ case 0x0E4Eu:
klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
break;
- case 0x0EB1u:
- case 0x0EB4u:
- case 0x0EB5u:
- case 0x0EB6u:
- case 0x0EB7u:
- case 0x0EBBu:
- case 0x0ECCu:
- case 0x0ECDu:
+ case 0x0EB1u:
+ case 0x0EB4u:
+ case 0x0EB5u:
+ case 0x0EB6u:
+ case 0x0EB7u:
+ case 0x0EBBu:
+ case 0x0ECCu:
+ case 0x0ECDu:
klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
break;
- case 0x0EBCu:
+ case 0x0EBCu:
klass = HB_UNICODE_COMBINING_CLASS_BELOW;
break;
}
@@ -92,7 +88,7 @@ recategorize_combining_class (hb_codepoint_t u,
case HB_MODIFIED_COMBINING_CLASS_CCC15: /* tsere */
case HB_MODIFIED_COMBINING_CLASS_CCC16: /* segol */
case HB_MODIFIED_COMBINING_CLASS_CCC17: /* patah */
- case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats & qamats qatan */
+ case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats */
case HB_MODIFIED_COMBINING_CLASS_CCC20: /* qubuts */
case HB_MODIFIED_COMBINING_CLASS_CCC22: /* meteg */
return HB_UNICODE_COMBINING_CLASS_BELOW;
@@ -104,7 +100,7 @@ recategorize_combining_class (hb_codepoint_t u,
return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
case HB_MODIFIED_COMBINING_CLASS_CCC25: /* sin dot */
- case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam & holam haser for vav */
+ case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam */
return HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT;
case HB_MODIFIED_COMBINING_CLASS_CCC26: /* point varika */
@@ -166,14 +162,10 @@ recategorize_combining_class (hb_codepoint_t u,
}
void
-_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
+_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
{
-#ifdef HB_NO_OT_SHAPE_FALLBACK
- return;
-#endif
-
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
@@ -188,25 +180,19 @@ _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t
static void
zero_mark_advances (hb_buffer_t *buffer,
unsigned int start,
- unsigned int end,
- bool adjust_offsets_when_zeroing)
+ unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = start; i < end; i++)
if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
{
- if (adjust_offsets_when_zeroing)
- {
- buffer->pos[i].x_offset -= buffer->pos[i].x_advance;
- buffer->pos[i].y_offset -= buffer->pos[i].y_advance;
- }
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
}
}
static inline void
-position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
+position_mark (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer,
hb_glyph_extents_t &base_extents,
@@ -214,7 +200,8 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int combining_class)
{
hb_glyph_extents_t mark_extents;
- if (!font->get_glyph_extents (buffer->info[i].codepoint, &mark_extents))
+ if (!font->get_glyph_extents (buffer->info[i].codepoint,
+ &mark_extents))
return;
hb_position_t y_gap = font->y_scale / 16;
@@ -232,10 +219,10 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
if (buffer->props.direction == HB_DIRECTION_LTR) {
pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
- break;
+ break;
} else if (buffer->props.direction == HB_DIRECTION_RTL) {
pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
- break;
+ break;
}
HB_FALLTHROUGH;
@@ -301,7 +288,7 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Don't shift down "above" marks too much. */
if ((y_gap > 0) != (pos.y_offset > 0))
{
- int correction = -pos.y_offset / 2;
+ unsigned int correction = -pos.y_offset / 2;
base_extents.y_bearing += correction;
base_extents.height -= correction;
pos.y_offset += correction;
@@ -317,8 +304,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer,
unsigned int base,
- unsigned int end,
- bool adjust_offsets_when_zeroing)
+ unsigned int end)
{
hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
@@ -329,20 +315,14 @@ position_around_base (const hb_ot_shape_plan_t *plan,
&base_extents))
{
/* If extents don't work, zero marks and go home. */
- zero_mark_advances (buffer, base + 1, end, adjust_offsets_when_zeroing);
+ zero_mark_advances (buffer, base + 1, end);
return;
}
+ base_extents.x_bearing += buffer->pos[base].x_offset;
base_extents.y_bearing += buffer->pos[base].y_offset;
- /* Use horizontal advance for horizontal positioning.
- * Generally a better idea. Also works for zero-ink glyphs. See:
- * https://github.com/harfbuzz/harfbuzz/issues/1532 */
- base_extents.x_bearing = 0;
- base_extents.width = font->get_glyph_h_advance (buffer->info[base].codepoint);
unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]);
- /* Use integer for num_lig_components such that it doesn't convert to unsigned
- * when we divide or multiply by it. */
- int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
+ unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
hb_position_t x_offset = 0, y_offset = 0;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
@@ -351,7 +331,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
}
hb_glyph_extents_t component_extents = base_extents;
- int last_lig_component = -1;
+ unsigned int last_lig_component = (unsigned int) -1;
unsigned int last_combining_class = 255;
hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
hb_glyph_info_t *info = buffer->info;
@@ -360,7 +340,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
{
if (num_lig_components > 1) {
unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]);
- int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1;
+ unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1;
/* Conditions for attaching to the last component. */
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
this_lig_component = num_lig_components - 1;
@@ -387,7 +367,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
if (last_combining_class != this_combining_class)
{
last_combining_class = this_combining_class;
- cluster_extents = component_extents;
+ cluster_extents = component_extents;
}
position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
@@ -413,8 +393,7 @@ position_cluster (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer,
unsigned int start,
- unsigned int end,
- bool adjust_offsets_when_zeroing)
+ unsigned int end)
{
if (end - start < 2)
return;
@@ -422,128 +401,109 @@ position_cluster (const hb_ot_shape_plan_t *plan,
/* Find the base glyph */
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = start; i < end; i++)
- if (!_hb_glyph_info_is_unicode_mark (&info[i]))
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
{
/* Find mark glyphs */
unsigned int j;
for (j = i + 1; j < end; j++)
- if (!_hb_glyph_info_is_unicode_mark (&info[j]))
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j])))
break;
- position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing);
+ position_around_base (plan, font, buffer, i, j);
i = j - 1;
}
}
void
-_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- bool adjust_offsets_when_zeroing)
+_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer)
{
-#ifdef HB_NO_OT_SHAPE_FALLBACK
- return;
-#endif
-
- if (!buffer->message (font, "start fallback mark"))
- return;
-
_hb_buffer_assert_gsubgpos_vars (buffer);
unsigned int start = 0;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 1; i < count; i++)
- if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) {
- position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing);
+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) {
+ position_cluster (plan, font, buffer, start, i);
start = i;
}
- position_cluster (plan, font, buffer, start, count, adjust_offsets_when_zeroing);
-
- (void) buffer->message (font, "end fallback mark");
+ position_cluster (plan, font, buffer, start, count);
}
-#ifndef HB_DISABLE_DEPRECATED
-struct hb_ot_shape_fallback_kern_driver_t
-{
- hb_ot_shape_fallback_kern_driver_t (hb_font_t *font_,
- hb_buffer_t *buffer) :
- font (font_), direction (buffer->props.direction) {}
-
- hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
- {
- hb_position_t kern = 0;
- font->get_glyph_kerning_for_direction (first, second,
- direction,
- &kern, &kern);
- return kern;
- }
-
- hb_font_t *font;
- hb_direction_t direction;
-};
-#endif
-
-/* Performs font-assisted kerning. */
+/* Performs old-style TrueType kerning. */
void
_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
- hb_buffer_t *buffer)
+ hb_buffer_t *buffer)
{
-#ifdef HB_NO_OT_SHAPE_FALLBACK
- return;
-#endif
-
-#ifndef HB_DISABLE_DEPRECATED
- if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
- !font->has_glyph_h_kerning_func () :
- !font->has_glyph_v_kerning_func ())
- return;
+ if (!plan->has_kern) return;
- if (!buffer->message (font, "start fallback kern"))
- return;
+ OT::hb_apply_context_t c (1, font, buffer);
+ c.set_lookup_mask (plan->kern_mask);
+ c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+ OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
+ skippy_iter.init (&c);
- bool reverse = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
+ for (unsigned int idx = 0; idx < count;)
+ {
+ skippy_iter.reset (idx, 1);
+ if (!skippy_iter.next ())
+ {
+ idx++;
+ continue;
+ }
- if (reverse)
- buffer->reverse ();
+ hb_position_t x_kern, y_kern;
+ font->get_glyph_kerning_for_direction (info[idx].codepoint,
+ info[skippy_iter.idx].codepoint,
+ buffer->props.direction,
+ &x_kern, &y_kern);
- hb_ot_shape_fallback_kern_driver_t driver (font, buffer);
- OT::hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
- machine.kern (font, buffer, plan->kern_mask, false);
+ if (x_kern)
+ {
+ hb_position_t kern1 = x_kern >> 1;
+ hb_position_t kern2 = x_kern - kern1;
+ pos[idx].x_advance += kern1;
+ pos[skippy_iter.idx].x_advance += kern2;
+ pos[skippy_iter.idx].x_offset += kern2;
+ }
- if (reverse)
- buffer->reverse ();
+ if (y_kern)
+ {
+ hb_position_t kern1 = y_kern >> 1;
+ hb_position_t kern2 = y_kern - kern1;
+ pos[idx].y_advance += kern1;
+ pos[skippy_iter.idx].y_advance += kern2;
+ pos[skippy_iter.idx].y_offset += kern2;
+ }
- (void) buffer->message (font, "end fallback kern");
-#endif
+ idx = skippy_iter.idx;
+ }
}
/* Adjusts width of various spaces. */
void
-_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
+_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+ return;
+
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
- bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i]))
{
- /* If font had no ASCII space and we used the invisible glyph, give it a 1/4 EM default advance. */
- if (buffer->invisible && info[i].codepoint == buffer->invisible)
- {
- if (horizontal)
- pos[i].x_advance = +font->x_scale / 4;
- else
- pos[i].y_advance = -font->y_scale / 4;
- }
-
hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]);
hb_codepoint_t glyph;
typedef hb_unicode_funcs_t t;
@@ -560,56 +520,37 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
case t::SPACE_EM_5:
case t::SPACE_EM_6:
case t::SPACE_EM_16:
- if (horizontal)
- pos[i].x_advance = +(font->x_scale + ((int) space_type)/2) / (int) space_type;
- else
- pos[i].y_advance = -(font->y_scale + ((int) space_type)/2) / (int) space_type;
+ pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type;
break;
case t::SPACE_4_EM_18:
- if (horizontal)
- pos[i].x_advance = (int64_t) +font->x_scale * 4 / 18;
- else
- pos[i].y_advance = (int64_t) -font->y_scale * 4 / 18;
+ pos[i].x_advance = font->x_scale * 4 / 18;
break;
case t::SPACE_FIGURE:
for (char u = '0'; u <= '9'; u++)
if (font->get_nominal_glyph (u, &glyph))
{
- if (horizontal)
- pos[i].x_advance = font->get_glyph_h_advance (glyph);
- else
- pos[i].y_advance = font->get_glyph_v_advance (glyph);
+ pos[i].x_advance = font->get_glyph_h_advance (glyph);
break;
}
break;
case t::SPACE_PUNCTUATION:
- if (font->get_nominal_glyph ('.', &glyph) ||
- font->get_nominal_glyph (',', &glyph))
- {
- if (horizontal)
- pos[i].x_advance = font->get_glyph_h_advance (glyph);
- else
- pos[i].y_advance = font->get_glyph_v_advance (glyph);
- }
+ if (font->get_nominal_glyph ('.', &glyph))
+ pos[i].x_advance = font->get_glyph_h_advance (glyph);
+ else if (font->get_nominal_glyph (',', &glyph))
+ pos[i].x_advance = font->get_glyph_h_advance (glyph);
break;
case t::SPACE_NARROW:
/* Half-space?
- * Unicode doc https://unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM.
+ * Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM.
* However, in my testing, many fonts have their regular space being about that
* size. To me, a percentage of the space width makes more sense. Half is as
* good as any. */
- if (horizontal)
- pos[i].x_advance /= 2;
- else
- pos[i].y_advance /= 2;
+ pos[i].x_advance /= 2;
break;
}
}
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
index 12c78a2352c..c744e26451d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -24,10 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPE_NORMALIZE_HH
-#define HB_OT_SHAPE_NORMALIZE_HH
+#ifndef HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
+#define HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
/* buffer var allocations, used during the normalization process */
@@ -38,11 +38,10 @@ struct hb_ot_shape_plan_t;
enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
- HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
};
HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
@@ -56,7 +55,6 @@ struct hb_ot_shape_normalize_context_t
hb_buffer_t *buffer;
hb_font_t *font;
hb_unicode_funcs_t *unicode;
- const hb_codepoint_t not_found;
bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
hb_codepoint_t *a,
@@ -68,4 +66,4 @@ struct hb_ot_shape_normalize_context_t
};
-#endif /* HB_OT_SHAPE_NORMALIZE_HH */
+#endif /* HB_OT_SHAPE_NORMALIZE_PRIVATE_HH */
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 897377aa158..fd9e7c2a8df 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -24,13 +24,9 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shape-normalize.hh"
-#include "hb-ot-shaper.hh"
-#include "hb-ot-shape.hh"
+#include "hb-ot-shape-normalize-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh"
/*
@@ -69,7 +65,7 @@
* - When a font does not support a character but supports its canonical
* decomposition, well, use the decomposition.
*
- * - The shapers can customize the compose and decompose functions to
+ * - The complex shapers can customize the compose and decompose functions to
* offload some of their requirements to the normalizer. For example, the
* Indic shaper may want to disallow recomposing of two matras.
*/
@@ -101,9 +97,8 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font)
static inline void
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
{
- /* This is very confusing indeed. */
buffer->cur().glyph_index() = glyph;
- (void) buffer->output_glyph (unichar);
+ buffer->output_glyph (unichar); /* This is very confusing indeed. */
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
}
@@ -111,7 +106,7 @@ static inline void
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
{
buffer->cur().glyph_index() = glyph;
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
static inline void
@@ -124,7 +119,7 @@ skip_char (hb_buffer_t *buffer)
static inline unsigned int
decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
{
- hb_codepoint_t a = 0, b = 0, a_glyph = 0, b_glyph = 0;
+ hb_codepoint_t a, b, a_glyph, b_glyph;
hb_buffer_t * const buffer = c->buffer;
hb_font_t * const font = c->font;
@@ -143,7 +138,8 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint
return 1;
}
- if (unsigned ret = decompose (c, shortest, a)) {
+ unsigned int ret;
+ if ((ret = decompose (c, shortest, a))) {
if (b) {
output_char (buffer, b, b_glyph);
return ret + 1;
@@ -168,9 +164,9 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
{
hb_buffer_t * const buffer = c->buffer;
hb_codepoint_t u = buffer->cur().codepoint;
- hb_codepoint_t glyph = 0;
+ hb_codepoint_t glyph;
- if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
+ if (shortest && c->font->get_nominal_glyph (u, &glyph))
{
next_char (buffer, glyph);
return;
@@ -182,7 +178,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
return;
}
- if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
+ if (!shortest && c->font->get_nominal_glyph (u, &glyph))
{
next_char (buffer, glyph);
return;
@@ -192,8 +188,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
{
hb_codepoint_t space_glyph;
hb_unicode_funcs_t::space_t space_type = buffer->unicode->space_fallback_type (u);
- if (space_type != hb_unicode_funcs_t::NOT_SPACE &&
- (c->font->get_nominal_glyph (0x0020, &space_glyph) || (space_glyph = buffer->invisible)))
+ if (space_type != hb_unicode_funcs_t::NOT_SPACE && c->font->get_nominal_glyph (0x0020u, &space_glyph))
{
_hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type);
next_char (buffer, space_glyph);
@@ -218,47 +213,40 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
}
static inline void
-handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
- unsigned int end,
- bool short_circuit HB_UNUSED)
+handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
- /* Currently if there's a variation-selector we give-up on normalization, it's just too hard. */
+ /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
hb_buffer_t * const buffer = c->buffer;
hb_font_t * const font = c->font;
- for (; buffer->idx < end - 1 && buffer->successful;) {
+ for (; buffer->idx < end - 1 && !buffer->in_error;) {
if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
+ /* The next two lines are some ugly lines... But work. */
if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
{
- hb_codepoint_t unicode = buffer->cur().codepoint;
- (void) buffer->replace_glyphs (2, 1, &unicode);
+ buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
}
else
{
- /* Just pass on the two characters separately, let GSUB do its magic. */
+ /* Just pass on the two characters separately, let GSUB do its magic. */
set_glyph (buffer->cur(), font);
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
set_glyph (buffer->cur(), font);
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
/* Skip any further variation selectors. */
- while (buffer->idx < end &&
- buffer->successful &&
- unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
+ while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
{
set_glyph (buffer->cur(), font);
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
- }
- else
- {
+ } else {
set_glyph (buffer->cur(), font);
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
}
- if (likely (buffer->idx < end))
- {
+ if (likely (buffer->idx < end)) {
set_glyph (buffer->cur(), font);
- (void) buffer->next_glyph ();
+ buffer->next_glyph ();
}
}
@@ -266,16 +254,25 @@ static inline void
decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
hb_buffer_t * const buffer = c->buffer;
- for (unsigned int i = buffer->idx; i < end && buffer->successful; i++)
+ for (unsigned int i = buffer->idx; i < end && !buffer->in_error; i++)
if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
handle_variation_selector_cluster (c, end, short_circuit);
return;
}
- while (buffer->idx < end && buffer->successful)
+ while (buffer->idx < end && !buffer->in_error)
decompose_current_character (c, short_circuit);
}
+static inline void
+decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
+{
+ if (likely (c->buffer->idx + 1 == end))
+ decompose_current_character (c, might_short_circuit);
+ else
+ decompose_multi_char_cluster (c, end, always_short_circuit);
+}
+
static int
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
@@ -297,22 +294,11 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
_hb_buffer_assert_unicode_vars (buffer);
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
- if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_AUTO)
- {
- if (plan->has_gpos_mark)
- // https://github.com/harfbuzz/harfbuzz/issues/653#issuecomment-423905920
- //mode = HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED;
- mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
- else
- mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
- }
-
const hb_ot_shape_normalize_context_t c = {
plan,
buffer,
font,
buffer->unicode,
- buffer->not_found,
plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
plan->shaper->compose ? plan->shaper->compose : compose_unicode
};
@@ -332,154 +318,114 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* First round, decompose */
- bool all_simple = true;
+ buffer->clear_output ();
+ count = buffer->len;
+ for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
{
- buffer->clear_output ();
- count = buffer->len;
- buffer->idx = 0;
- do
- {
- unsigned int end;
- for (end = buffer->idx + 1; end < count; end++)
- if (_hb_glyph_info_is_unicode_mark (&buffer->info[end]))
- break;
-
- if (end < count)
- end--; /* Leave one base for the marks to cluster with. */
-
- /* From idx to end are simple clusters. */
- if (might_short_circuit)
- {
- unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
- &buffer->cur().codepoint,
- sizeof (buffer->info[0]),
- &buffer->cur().glyph_index(),
- sizeof (buffer->info[0]));
- if (unlikely (!buffer->next_glyphs (done))) break;
- }
- while (buffer->idx < end && buffer->successful)
- decompose_current_character (&c, might_short_circuit);
+ unsigned int end;
+ for (end = buffer->idx + 1; end < count; end++)
+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
+ break;
- if (buffer->idx == count || !buffer->successful)
- break;
-
- all_simple = false;
-
- /* Find all the marks now. */
- for (end = buffer->idx + 1; end < count; end++)
- if (!_hb_glyph_info_is_unicode_mark(&buffer->info[end]))
- break;
-
- /* idx to end is one non-simple cluster. */
- decompose_multi_char_cluster (&c, end, always_short_circuit);
- }
- while (buffer->idx < count && buffer->successful);
- buffer->sync ();
+ decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
}
+ buffer->swap_buffers ();
/* Second round, reorder (inplace) */
- if (!all_simple && buffer->message(font, "start reorder"))
+ count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
{
- count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
- continue;
+ if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+ continue;
- unsigned int end;
- for (end = i + 1; end < count; end++)
- if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
- break;
+ unsigned int end;
+ for (end = i + 1; end < count; end++)
+ 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 > HB_OT_SHAPE_MAX_COMBINING_MARKS) {
- i = end;
- continue;
- }
+ /* 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);
+ buffer->sort (i, end, compare_combining_class);
- if (plan->shaper->reorder_marks)
- plan->shaper->reorder_marks (plan, buffer, i, end);
+ if (plan->shaper->reorder_marks)
+ plan->shaper->reorder_marks (plan, buffer, i, end);
- i = end;
- }
- (void) buffer->message(font, "end reorder");
- }
- if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
- {
- /* For all CGJ, check if it prevented any reordering at all.
- * If it did NOT, then make it skippable.
- * https://github.com/harfbuzz/harfbuzz/issues/554
- */
- for (unsigned int i = 1; i + 1 < buffer->len; i++)
- if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
- (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
- {
- _hb_glyph_info_unhide (&buffer->info[i]);
- }
+ i = end;
}
+ if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
+ mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
+ return;
+
/* Third round, recompose */
- if (!all_simple &&
- buffer->successful &&
- (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
- mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT))
+ /* As noted in the comment earlier, we don't try to combine
+ * ccc=0 chars with their previous Starter. */
+
+ buffer->clear_output ();
+ count = buffer->len;
+ unsigned int starter = 0;
+ bool combine = true;
+ buffer->next_glyph ();
+ while (buffer->idx < count && !buffer->in_error)
{
- /* As noted in the comment earlier, we don't try to combine
- * ccc=0 chars with their previous Starter. */
-
- buffer->clear_output ();
- count = buffer->len;
- unsigned int starter = 0;
- (void) buffer->next_glyph ();
- while (buffer->idx < count /* No need for: && buffer->successful */)
+ hb_codepoint_t composed, glyph;
+ 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())))
{
- hb_codepoint_t composed, glyph;
- if (/* We don't try to compose a non-mark character with it's preceding starter.
- * This is both an optimization to avoid trying to compose every two neighboring
- * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
- * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
- _hb_glyph_info_is_unicode_mark(&buffer->cur()))
+ 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))
{
- 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. */
- if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */
- 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;
- }
+ /* 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. */
- if (unlikely (!buffer->next_glyph ())) break;
+ /* Blocked, or doesn't compose. */
+ buffer->next_glyph ();
- if (info_cc (buffer->prev()) == 0)
- starter = buffer->out_len - 1;
+ if (info_cc (buffer->prev()) == 0)
+ {
+ starter = buffer->out_len - 1;
+ combine = true;
}
- buffer->sync ();
}
-}
+ buffer->swap_buffers ();
-
-#endif
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
new file mode 100644
index 00000000000..fe5d2b7f333
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2010 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_PRIVATE_HH
+#define HB_OT_SHAPE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-map-private.hh"
+#include "hb-ot-layout-private.hh"
+
+
+
+struct hb_ot_shape_plan_t
+{
+ hb_segment_properties_t props;
+ const struct hb_ot_complex_shaper_t *shaper;
+ hb_ot_map_t map;
+ const void *data;
+ hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
+ hb_mask_t kern_mask;
+ unsigned int has_frac : 1;
+ unsigned int has_kern : 1;
+ unsigned int has_mark : 1;
+
+ inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
+ {
+ unsigned int table_index;
+ switch (table_tag) {
+ case HB_OT_TAG_GSUB: table_index = 0; break;
+ case HB_OT_TAG_GPOS: table_index = 1; break;
+ default: return;
+ }
+ map.collect_lookups (table_index, lookups);
+ }
+ inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
+ inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
+
+ void finish (void) { map.finish (); }
+};
+
+struct hb_ot_shape_planner_t
+{
+ /* In the order that they are filled in. */
+ hb_face_t *face;
+ hb_segment_properties_t props;
+ const struct hb_ot_complex_shaper_t *shaper;
+ hb_ot_map_builder_t map;
+
+ hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
+ face (master_plan->face_unsafe),
+ props (master_plan->props),
+ shaper (nullptr),
+ map (face, &props) {}
+ ~hb_ot_shape_planner_t (void) { map.finish (); }
+
+ inline void compile (hb_ot_shape_plan_t &plan,
+ const int *coords,
+ unsigned int num_coords)
+ {
+ plan.props = props;
+ plan.shaper = shaper;
+ map.compile (plan.map, coords, num_coords);
+
+ plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
+ plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
+ plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
+ plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
+
+ plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+ HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+
+ plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+ plan.has_kern = !!plan.kern_mask;
+ plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
+ }
+
+ private:
+ /* 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 &);
+};
+
+
+#endif /* HB_OT_SHAPE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index 3d207e06815..2f28b5620da 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -26,305 +26,60 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#ifdef HB_NO_OT_LAYOUT
-#error "Cannot compile 'ot' shaper with HB_NO_OT_LAYOUT."
-#endif
-
-#include "hb-shaper-impl.hh"
-
-#include "hb-ot-shape.hh"
-#include "hb-ot-shaper.hh"
-#include "hb-ot-shape-fallback.hh"
-#include "hb-ot-shape-normalize.hh"
-
-#include "hb-ot-face.hh"
-
-#include "hb-set.hh"
-
-#include "hb-aat-layout.hh"
+#define HB_SHAPER ot
+#define hb_ot_shaper_face_data_t hb_ot_layout_t
+#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
+
+#include "hb-ot-layout-private.hh"
+#include "hb-unicode-private.hh"
+#include "hb-set-private.hh"
+
+
+static hb_tag_t common_features[] = {
+ HB_TAG('c','c','m','p'),
+ HB_TAG('l','o','c','l'),
+ HB_TAG('m','a','r','k'),
+ HB_TAG('m','k','m','k'),
+ HB_TAG('r','l','i','g'),
+};
-static inline bool
-_hb_codepoint_is_regional_indicator (hb_codepoint_t u)
-{ return hb_in_range<hb_codepoint_t> (u, 0x1F1E6u, 0x1F1FFu); }
-#ifndef HB_NO_AAT_SHAPE
-static inline bool
-_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t &props)
-{
- /* https://github.com/harfbuzz/harfbuzz/issues/2124 */
- return hb_aat_layout_has_substitution (face) &&
- (HB_DIRECTION_IS_HORIZONTAL (props.direction) || !hb_ot_layout_has_substitution (face));
-}
-#endif
+static hb_tag_t horizontal_features[] = {
+ HB_TAG('c','a','l','t'),
+ HB_TAG('c','l','i','g'),
+ HB_TAG('c','u','r','s'),
+ HB_TAG('k','e','r','n'),
+ HB_TAG('l','i','g','a'),
+ HB_TAG('r','c','l','t'),
+};
-/**
- * SECTION:hb-ot-shape
- * @title: hb-ot-shape
- * @short_description: OpenType shaping support
- * @include: hb-ot.h
- *
- * Support functions for OpenType shaping related queries.
- **/
static void
hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
+ const hb_segment_properties_t *props,
const hb_feature_t *user_features,
- unsigned int num_user_features);
-
-hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face,
- const hb_segment_properties_t &props) :
- face (face),
- props (props),
- map (face, props)
-#ifndef HB_NO_AAT_SHAPE
- , apply_morx (_hb_apply_morx (face, props))
-#endif
-{
- shaper = hb_ot_shaper_categorize (this);
-
- script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
- script_fallback_mark_positioning = shaper->fallback_position;
-
-#ifndef HB_NO_AAT_SHAPE
- /* https://github.com/harfbuzz/harfbuzz/issues/1528 */
- if (apply_morx && shaper != &_hb_ot_shaper_default)
- shaper = &_hb_ot_shaper_dumber;
-#endif
-}
-
-void
-hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
- const hb_ot_shape_plan_key_t &key)
-{
- plan.props = props;
- plan.shaper = shaper;
- map.compile (plan.map, key);
-
-#ifndef HB_NO_OT_SHAPE_FRACTIONS
- plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
- plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
- plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
- plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
-#endif
-
- plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
- plan.has_vert = !!plan.map.get_1_mask (HB_TAG ('v','e','r','t'));
-
- hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
- HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
-#ifndef HB_NO_OT_KERN
- plan.kern_mask = plan.map.get_mask (kern_tag);
- plan.requested_kerning = !!plan.kern_mask;
-#endif
-#ifndef HB_NO_AAT_SHAPE
- plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
- plan.requested_tracking = !!plan.trak_mask;
-#endif
-
- bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
- bool disable_gpos = plan.shaper->gpos_tag &&
- plan.shaper->gpos_tag != plan.map.chosen_script[1];
-
- /*
- * Decide who provides glyph classes. GDEF or Unicode.
- */
-
- if (!hb_ot_layout_has_glyph_classes (face))
- plan.fallback_glyph_classes = true;
-
- /*
- * Decide who does substitutions. GSUB, morx, or fallback.
- */
-
-#ifndef HB_NO_AAT_SHAPE
- plan.apply_morx = apply_morx;
-#endif
-
- /*
- * Decide who does positioning. GPOS, kerx, kern, or fallback.
- */
-
-#ifndef HB_NO_AAT_SHAPE
- bool has_kerx = hb_aat_layout_has_positioning (face);
- bool has_gsub = !apply_morx && hb_ot_layout_has_substitution (face);
-#endif
- bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
- if (false)
- ;
-#ifndef HB_NO_AAT_SHAPE
- /* Prefer GPOS over kerx if GSUB is present;
- * https://github.com/harfbuzz/harfbuzz/issues/3008 */
- else if (has_kerx && !(has_gsub && has_gpos))
- plan.apply_kerx = true;
-#endif
- else if (has_gpos)
- plan.apply_gpos = true;
-
- if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos))
- {
-#ifndef HB_NO_AAT_SHAPE
- if (has_kerx)
- plan.apply_kerx = true;
- else
-#endif
-#ifndef HB_NO_OT_KERN
- if (hb_ot_layout_has_kerning (face))
- plan.apply_kern = true;
-#endif
- }
-
- plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern);
-
- plan.zero_marks = script_zero_marks &&
- !plan.apply_kerx &&
- (!plan.apply_kern
-#ifndef HB_NO_OT_KERN
- || !hb_ot_layout_has_machine_kerning (face)
-#endif
- );
- plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
-
- plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
- !plan.apply_kerx &&
- (!plan.apply_kern
-#ifndef HB_NO_OT_KERN
- || !hb_ot_layout_has_cross_kerning (face)
-#endif
- );
-
- plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
- script_fallback_mark_positioning;
-
-#ifndef HB_NO_AAT_SHAPE
- /* If we're using morx shaping, we cancel mark position adjustment because
- Apple Color Emoji assumes this will NOT be done when forming emoji sequences;
- https://github.com/harfbuzz/harfbuzz/issues/2967. */
- if (plan.apply_morx)
- plan.adjust_mark_positioning_when_zeroing = false;
-
- /* Currently we always apply trak. */
- plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
-#endif
-}
-
-bool
-hb_ot_shape_plan_t::init0 (hb_face_t *face,
- const hb_shape_plan_key_t *key)
-{
- map.init ();
-
- hb_ot_shape_planner_t planner (face,
- key->props);
-
- hb_ot_shape_collect_features (&planner,
- key->user_features,
- key->num_user_features);
-
- planner.compile (*this, key->ot);
-
- if (shaper->data_create)
- {
- data = shaper->data_create (this);
- if (unlikely (!data))
- {
- map.fini ();
- return false;
- }
- }
-
- return true;
-}
-
-void
-hb_ot_shape_plan_t::fini ()
-{
- if (shaper->data_destroy)
- shaper->data_destroy (const_cast<void *> (data));
-
- map.fini ();
-}
-
-void
-hb_ot_shape_plan_t::substitute (hb_font_t *font,
- hb_buffer_t *buffer) const
-{
- map.substitute (this, font, buffer);
-}
-
-void
-hb_ot_shape_plan_t::position (hb_font_t *font,
- hb_buffer_t *buffer) const
-{
- if (this->apply_gpos)
- map.position (this, font, buffer);
-#ifndef HB_NO_AAT_SHAPE
- else if (this->apply_kerx)
- hb_aat_layout_position (this, font, buffer);
-#endif
-
-#ifndef HB_NO_OT_KERN
- if (this->apply_kern)
- hb_ot_layout_kern (this, font, buffer);
-#endif
- else if (this->apply_fallback_kern)
- _hb_ot_shape_fallback_kern (this, font, buffer);
-
-#ifndef HB_NO_AAT_SHAPE
- if (this->apply_trak)
- hb_aat_layout_track (this, font, buffer);
-#endif
-}
-
-
-static const hb_ot_map_feature_t
-common_features[] =
-{
- {HB_TAG('a','b','v','m'), F_GLOBAL},
- {HB_TAG('b','l','w','m'), F_GLOBAL},
- {HB_TAG('c','c','m','p'), F_GLOBAL},
- {HB_TAG('l','o','c','l'), F_GLOBAL},
- {HB_TAG('m','a','r','k'), F_GLOBAL_MANUAL_JOINERS},
- {HB_TAG('m','k','m','k'), F_GLOBAL_MANUAL_JOINERS},
- {HB_TAG('r','l','i','g'), F_GLOBAL},
-};
-
-
-static const hb_ot_map_feature_t
-horizontal_features[] =
-{
- {HB_TAG('c','a','l','t'), F_GLOBAL},
- {HB_TAG('c','l','i','g'), F_GLOBAL},
- {HB_TAG('c','u','r','s'), F_GLOBAL},
- {HB_TAG('d','i','s','t'), F_GLOBAL},
- {HB_TAG('k','e','r','n'), F_GLOBAL_HAS_FALLBACK},
- {HB_TAG('l','i','g','a'), F_GLOBAL},
- {HB_TAG('r','c','l','t'), F_GLOBAL},
-};
-
-static void
-hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
+ unsigned int num_user_features)
{
hb_ot_map_builder_t *map = &planner->map;
- map->enable_feature (HB_TAG('r','v','r','n'));
+ map->add_global_bool_feature (HB_TAG('r','v','r','n'));
map->add_gsub_pause (nullptr);
- switch (planner->props.direction)
- {
+ switch (props->direction) {
case HB_DIRECTION_LTR:
- map->enable_feature (HB_TAG ('l','t','r','a'));
- map->enable_feature (HB_TAG ('l','t','r','m'));
+ map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
+ map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
break;
case HB_DIRECTION_RTL:
- map->enable_feature (HB_TAG ('r','t','l','a'));
- map->add_feature (HB_TAG ('r','t','l','m'));
+ map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
+ map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
@@ -333,62 +88,39 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
}
-#ifndef HB_NO_OT_SHAPE_FRACTIONS
- /* Automatic fractions. */
- map->add_feature (HB_TAG ('f','r','a','c'));
- map->add_feature (HB_TAG ('n','u','m','r'));
- map->add_feature (HB_TAG ('d','n','o','m'));
-#endif
-
- /* Random! */
- map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
-
-#ifndef HB_NO_AAT_SHAPE
- /* Tracking. We enable dummy feature here just to allow disabling
- * AAT 'trak' table using features.
- * https://github.com/harfbuzz/harfbuzz/issues/1303 */
- map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK);
-#endif
-
- map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */
- map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */
+ map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
+ map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
+ map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
if (planner->shaper->collect_features)
planner->shaper->collect_features (planner);
- map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */
- map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */
-
for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
- map->add_feature (common_features[i]);
+ map->add_global_bool_feature (common_features[i]);
- if (HB_DIRECTION_IS_HORIZONTAL (planner->props.direction))
+ if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
- map->add_feature (horizontal_features[i]);
+ map->add_feature (horizontal_features[i], 1, F_GLOBAL |
+ (horizontal_features[i] == HB_TAG('k','e','r','n') ?
+ F_HAS_FALLBACK : F_NONE));
else
{
- /* We only apply `vert` feature. See:
- * https://github.com/harfbuzz/harfbuzz/commit/d71c0df2d17f4590d5611239577a6cb532c26528
- * https://lists.freedesktop.org/archives/harfbuzz/2013-August/003490.html */
-
/* 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/harfbuzz/harfbuzz/issues/63 */
- map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH);
- }
-
- for (unsigned int i = 0; i < num_user_features; i++)
- {
- const hb_feature_t *feature = &user_features[i];
- map->add_feature (feature->tag,
- (feature->start == HB_FEATURE_GLOBAL_START &&
- feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE,
- feature->value);
+ map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH);
}
if (planner->shaper->override_features)
planner->shaper->override_features (planner);
+
+ for (unsigned int i = 0; i < num_user_features; i++) {
+ const hb_feature_t *feature = &user_features[i];
+ map->add_feature (feature->tag, feature->value,
+ (feature->start == 0 && feature->end == (unsigned int) -1) ?
+ F_GLOBAL : F_NONE);
+ }
}
@@ -396,17 +128,18 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
* shaper face data
*/
-struct hb_ot_face_data_t {};
+HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
-hb_ot_face_data_t *
+hb_ot_shaper_face_data_t *
_hb_ot_shaper_face_data_create (hb_face_t *face)
{
- return (hb_ot_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ return _hb_ot_layout_create (face);
}
void
-_hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
+_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
{
+ _hb_ot_layout_destroy (data);
}
@@ -414,17 +147,64 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
* shaper font data
*/
-struct hb_ot_font_data_t {};
+HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
-hb_ot_font_data_t *
+struct hb_ot_shaper_font_data_t {};
+
+hb_ot_shaper_font_data_t *
_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED)
{
- return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+hb_ot_shaper_shape_plan_data_t *
+_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const int *coords,
+ unsigned int num_coords)
+{
+ hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
+ if (unlikely (!plan))
+ return nullptr;
+
+ hb_ot_shape_planner_t planner (shape_plan);
+
+ planner.shaper = hb_ot_shape_complex_categorize (&planner);
+
+ hb_ot_shape_collect_features (&planner, &shape_plan->props,
+ user_features, num_user_features);
+
+ planner.compile (*plan, coords, num_coords);
+
+ if (plan->shaper->data_create) {
+ plan->data = plan->shaper->data_create (plan);
+ if (unlikely (!plan->data))
+ return nullptr;
+ }
+
+ return plan;
}
void
-_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED)
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
{
+ if (plan->shaper->data_destroy)
+ plan->shaper->data_destroy (const_cast<void *> (plan->data));
+
+ plan->finish ();
+
+ free (plan);
}
@@ -442,6 +222,8 @@ struct hb_ot_shape_context_t
unsigned int num_user_features;
/* Transient stuff */
+ bool fallback_positioning;
+ bool fallback_glyph_classes;
hb_direction_t target_direction;
};
@@ -455,76 +237,19 @@ struct hb_ot_shape_context_t
static void
hb_set_unicode_props (hb_buffer_t *buffer)
{
- /* Implement enough of Unicode Graphemes here that shaping
- * in reverse-direction wouldn't break graphemes. Namely,
- * we mark all marks and ZWJ and ZWJ,Extended_Pictographic
- * sequences as continuations. The foreach_grapheme()
- * macro uses this bit.
- *
- * https://www.unicode.org/reports/tr29/#Regex_Definitions
- */
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- {
_hb_glyph_info_set_unicode_props (&info[i], buffer);
-
- /* Marks are already set as continuation by the above line.
- * Handle Emoji_Modifier and ZWJ-continuation. */
- if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
- hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu)))
- {
- _hb_glyph_info_set_continuation (&info[i]);
- }
- /* Regional_Indicators are hairy as hell...
- * https://github.com/harfbuzz/harfbuzz/issues/2265 */
- else if (unlikely (i && _hb_codepoint_is_regional_indicator (info[i].codepoint)))
- {
- if (_hb_codepoint_is_regional_indicator (info[i - 1].codepoint) &&
- !_hb_glyph_info_is_continuation (&info[i - 1]))
- _hb_glyph_info_set_continuation (&info[i]);
- }
-#ifndef HB_NO_EMOJI_SEQUENCES
- else if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
- {
- _hb_glyph_info_set_continuation (&info[i]);
- if (i + 1 < count &&
- _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
- {
- i++;
- _hb_glyph_info_set_unicode_props (&info[i], buffer);
- _hb_glyph_info_set_continuation (&info[i]);
- }
- }
-#endif
- /* Or part of the Other_Grapheme_Extend that is not marks.
- * As of Unicode 15 that is just:
- *
- * 200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER
- * FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
- * E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG
- *
- * ZWNJ is special, we don't want to merge it as there's no need, and keeping
- * it separate results in more granular clusters.
- * Tags are used for Emoji sub-region flag sequences:
- * https://github.com/harfbuzz/harfbuzz/issues/1556
- * Katakana ones were requested:
- * https://github.com/harfbuzz/harfbuzz/issues/3844
- */
- else if (unlikely (hb_in_ranges<hb_codepoint_t> (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu)))
- _hb_glyph_info_set_continuation (&info[i]);
- }
}
static void
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
{
- if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
- return;
-
if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
buffer->context_len[0] ||
- !_hb_glyph_info_is_unicode_mark (&buffer->info[0]))
+ _hb_glyph_info_get_general_category (&buffer->info[0]) !=
+ HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
return;
if (!font->has_glyph (0x25CCu))
@@ -540,9 +265,11 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
hb_glyph_info_t info = dottedcircle;
info.cluster = buffer->cur().cluster;
info.mask = buffer->cur().mask;
- (void) buffer->output_info (info);
+ buffer->output_info (info);
+ while (buffer->idx < buffer->len && !buffer->in_error)
+ buffer->next_glyph ();
- buffer->sync ();
+ buffer->swap_buffers ();
}
static void
@@ -551,171 +278,93 @@ hb_form_clusters (hb_buffer_t *buffer)
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII))
return;
+ /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */
+ unsigned int base = 0;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 1; i < count; i++)
+ {
+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) &&
+ !_hb_glyph_info_is_joiner (&info[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;
+ }
+ }
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
- foreach_grapheme (buffer, start, end)
- buffer->merge_clusters (start, end);
+ buffer->merge_clusters (base, count);
else
- foreach_grapheme (buffer, start, end)
- buffer->unsafe_to_break (start, end);
+ buffer->unsafe_to_break (base, count);
}
static void
hb_ensure_native_direction (hb_buffer_t *buffer)
{
hb_direction_t direction = buffer->props.direction;
- hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script);
-
- /* Numeric runs in natively-RTL scripts are actually native-LTR, so we reset
- * the horiz_dir if the run contains at least one decimal-number char, and no
- * letter chars (ideally we should be checking for chars with strong
- * directionality but hb-unicode currently lacks bidi categories).
- *
- * This allows digit sequences in Arabic etc to be shaped in "native"
- * direction, so that features like ligatures will work as intended.
- *
- * https://github.com/harfbuzz/harfbuzz/issues/501
- *
- * Similar thing about Regional_Indicators; They are bidi=L, but Script=Common.
- * If they are present in a run of natively-RTL text, they get assigned a script
- * with natively RTL direction, which would result in wrong shaping if we
- * assign such native RTL direction to them then. Detect that as well.
- *
- * https://github.com/harfbuzz/harfbuzz/issues/3314
- */
- if (unlikely (horiz_dir == HB_DIRECTION_RTL && direction == HB_DIRECTION_LTR))
- {
- bool found_number = false, found_letter = false, found_ri = false;
- const auto* info = buffer->info;
- const auto count = buffer->len;
- for (unsigned i = 0; i < count; i++)
- {
- auto gc = _hb_glyph_info_get_general_category (&info[i]);
- if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
- found_number = true;
- else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc))
- {
- found_letter = true;
- break;
- }
- else if (_hb_codepoint_is_regional_indicator (info[i].codepoint))
- found_ri = true;
- }
- if ((found_number || found_ri) && !found_letter)
- horiz_dir = HB_DIRECTION_LTR;
- }
/* TODO vertical:
* The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
* Ogham fonts are supposed to be implemented BTT or not. Need to research that
* first. */
- if ((HB_DIRECTION_IS_HORIZONTAL (direction) &&
- direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) ||
- (HB_DIRECTION_IS_VERTICAL (direction) &&
- direction != HB_DIRECTION_TTB))
+ if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
+ (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB))
{
- _hb_ot_layout_reverse_graphemes (buffer);
- buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
- }
-}
+ /* Same loop as hb_form_clusters().
+ * Since form_clusters() merged clusters already, we don't merge. */
+ unsigned int base = 0;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 1; i < count; i++)
+ {
+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))))
+ {
+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+ buffer->merge_clusters (base, i);
+ buffer->reverse_range (base, i);
+ base = i;
+ }
+ }
+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+ buffer->merge_clusters (base, count);
+ buffer->reverse_range (base, count);
-/*
- * Substitute
- */
+ buffer->reverse ();
-#ifndef HB_NO_VERTICAL
-static hb_codepoint_t
-hb_vert_char_for (hb_codepoint_t u)
-{
- switch (u >> 8)
- {
- case 0x20: switch (u) {
- case 0x2013u: return 0xfe32u; // EN DASH
- case 0x2014u: return 0xfe31u; // EM DASH
- case 0x2025u: return 0xfe30u; // TWO DOT LEADER
- case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS
- } break;
- case 0x30: switch (u) {
- case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA
- case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP
- case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET
- case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET
- case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET
- case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET
- case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET
- case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET
- case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET
- case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET
- case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET
- case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET
- case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET
- case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET
- case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET
- case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET
- } break;
- case 0xfe: switch (u) {
- case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE
- } break;
- case 0xff: switch (u) {
- case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK
- case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS
- case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS
- case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA
- case 0xff1au: return 0xfe13u; // FULLWIDTH COLON
- case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON
- case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK
- case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET
- case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET
- case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE
- case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET
- case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET
- } break;
+ buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
}
-
- return u;
}
-#endif
+
+
+/* Substitute */
static inline void
-hb_ot_rotate_chars (const hb_ot_shape_context_t *c)
+hb_ot_mirror_chars (hb_ot_shape_context_t *c)
{
+ if (HB_DIRECTION_IS_FORWARD (c->target_direction))
+ return;
+
hb_buffer_t *buffer = c->buffer;
+ hb_unicode_funcs_t *unicode = buffer->unicode;
+ hb_mask_t rtlm_mask = c->plan->rtlm_mask;
+
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
-
- if (HB_DIRECTION_IS_BACKWARD (c->target_direction))
- {
- hb_unicode_funcs_t *unicode = buffer->unicode;
- hb_mask_t rtlm_mask = c->plan->rtlm_mask;
-
- for (unsigned int i = 0; i < count; i++) {
- hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
- if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint)))
- info[i].codepoint = codepoint;
- else
- info[i].mask |= rtlm_mask;
- }
- }
-
-#ifndef HB_NO_VERTICAL
- if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert)
- {
- for (unsigned int i = 0; i < count; i++) {
- hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint);
- if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint)))
- info[i].codepoint = codepoint;
- }
+ for (unsigned int i = 0; i < count; i++) {
+ hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+ if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint)))
+ info[i].mask |= rtlm_mask;
+ else
+ info[i].codepoint = codepoint;
}
-#endif
}
static inline void
-hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
{
-#ifdef HB_NO_OT_SHAPE_FRACTIONS
- return;
-#endif
-
if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
!c->plan->has_frac)
return;
@@ -744,19 +393,19 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
while (start &&
_hb_glyph_info_get_general_category (&info[start - 1]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
- start--;
+ start--;
while (end < count &&
_hb_glyph_info_get_general_category (&info[end]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
- end++;
+ end++;
buffer->unsafe_to_break (start, end);
for (unsigned int j = start; j < i; j++)
- info[j].mask |= pre_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 |= post_mask;
+ info[j].mask |= post_mask;
i = end - 1;
}
@@ -764,7 +413,7 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c)
+hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
@@ -774,7 +423,7 @@ hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
@@ -787,7 +436,7 @@ hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
for (unsigned int i = 0; i < c->num_user_features; i++)
{
const hb_feature_t *feature = &c->user_features[i];
- if (!(feature->start == HB_FEATURE_GLOBAL_START && feature->end == HB_FEATURE_GLOBAL_END)) {
+ if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
hb_mask_t mask = map->get_mask (feature->tag, &shift);
buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
@@ -796,11 +445,12 @@ hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
}
static void
-hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer)
+hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
{
+ hb_buffer_t *buffer = c->buffer;
+
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
- (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) ||
- (buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES))
+ (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
return;
unsigned int count = buffer->len;
@@ -813,29 +463,82 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer)
}
static void
-hb_ot_hide_default_ignorables (hb_buffer_t *buffer,
- hb_font_t *font)
+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
{
+ hb_buffer_t *buffer = c->buffer;
+
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
return;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
+ unsigned int i = 0;
+ for (i = 0; i < count; i++)
+ {
+ if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i])))
+ break;
+ }
+
+ /* No default-ignorables found; return. */
+ if (i == count)
+ return;
- hb_codepoint_t invisible = buffer->invisible;
- if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
- (invisible || font->get_nominal_glyph (' ', &invisible)))
+ hb_codepoint_t space;
+ if (c->font->get_nominal_glyph (' ', &space))
{
- /* Replace default-ignorables with a zero-advance invisible glyph. */
- for (unsigned int i = 0; i < count; i++)
+ /* Replace default-ignorables with a zero-advance space glyph. */
+ for (/*continue*/; i < count; i++)
{
if (_hb_glyph_info_is_default_ignorable (&info[i]))
- info[i].codepoint = invisible;
+ info[i].codepoint = space;
}
}
else
- buffer->delete_glyphs_inplace (_hb_glyph_info_is_default_ignorable);
+ {
+ /* Merge clusters and delete default-ignorables.
+ * NOTE! We can't use out-buffer as we have positioning data. */
+ unsigned int j = i;
+ for (; i < count; i++)
+ {
+ if (_hb_glyph_info_is_default_ignorable (&info[i]))
+ {
+ /* Merge clusters.
+ * Same logic as buffer->delete_glyph(), but for in-place removal. */
+
+ unsigned int cluster = info[i].cluster;
+ if (i + 1 < count && cluster == info[i + 1].cluster)
+ continue; /* Cluster survives; do nothing. */
+
+ if (j)
+ {
+ /* 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--)
+ buffer->set_cluster (info[k - 1], cluster, mask);
+ }
+ continue;
+ }
+
+ if (i + 1 < count)
+ buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+ continue;
+ }
+
+ if (j != i)
+ {
+ info[j] = info[i];
+ pos[j] = pos[i];
+ }
+ j++;
+ }
+ buffer->len = j;
+ }
}
@@ -852,10 +555,10 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
}
static inline void
-hb_synthesize_glyph_classes (hb_buffer_t *buffer)
+hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
{
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
+ unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
for (unsigned int i = 0; i < count; i++)
{
hb_ot_layout_glyph_props_flags_t klass;
@@ -878,11 +581,11 @@ hb_synthesize_glyph_classes (hb_buffer_t *buffer)
}
static inline void
-hb_ot_substitute_default (const hb_ot_shape_context_t *c)
+hb_ot_substitute_default (hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
- hb_ot_rotate_chars (c);
+ hb_ot_mirror_chars (c);
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
@@ -891,8 +594,8 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
hb_ot_shape_setup_masks (c);
/* This is unfortunate to go here, but necessary... */
- if (c->plan->fallback_mark_positioning)
- _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer);
+ if (c->fallback_positioning)
+ _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
hb_ot_map_glyphs_fast (buffer);
@@ -900,60 +603,31 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_substitute_plan (const hb_ot_shape_context_t *c)
+hb_ot_substitute_complex (hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
hb_ot_layout_substitute_start (c->font, buffer);
- if (c->plan->fallback_glyph_classes)
- hb_synthesize_glyph_classes (c->buffer);
+ if (!hb_ot_layout_has_glyph_classes (c->face))
+ hb_synthesize_glyph_classes (c);
-#ifndef HB_NO_AAT_SHAPE
- if (unlikely (c->plan->apply_morx))
- hb_aat_layout_substitute (c->plan, c->font, c->buffer,
- c->user_features, c->num_user_features);
- else
-#endif
- c->plan->substitute (c->font, buffer);
+ c->plan->substitute (c->font, buffer);
+
+ return;
}
static inline void
-hb_ot_substitute_pre (const hb_ot_shape_context_t *c)
+hb_ot_substitute (hb_ot_shape_context_t *c)
{
hb_ot_substitute_default (c);
_hb_buffer_allocate_gsubgpos_vars (c->buffer);
- hb_ot_substitute_plan (c);
-
-#ifndef HB_NO_AAT_SHAPE
- if (c->plan->apply_morx && c->plan->apply_gpos)
- hb_aat_layout_remove_deleted_glyphs (c->buffer);
-#endif
-}
-
-static inline void
-hb_ot_substitute_post (const hb_ot_shape_context_t *c)
-{
-#ifndef HB_NO_AAT_SHAPE
- if (c->plan->apply_morx && !c->plan->apply_gpos)
- hb_aat_layout_remove_deleted_glyphs (c->buffer);
-#endif
-
- hb_ot_hide_default_ignorables (c->buffer, c->font);
-
- if (c->plan->shaper->postprocess_glyphs &&
- c->buffer->message(c->font, "start postprocess-glyphs")) {
- c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
- (void) c->buffer->message(c->font, "end postprocess-glyphs");
- }
+ hb_ot_substitute_complex (c);
}
-
-/*
- * Position
- */
+/* Position */
static inline void
adjust_mark_offsets (hb_glyph_position_t *pos)
@@ -978,13 +652,13 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
if (_hb_glyph_info_is_mark (&info[i]))
{
if (adjust_offsets)
- adjust_mark_offsets (&buffer->pos[i]);
+ adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
}
}
static inline void
-hb_ot_position_default (const hb_ot_shape_context_t *c)
+hb_ot_position_default (hb_ot_shape_context_t *c)
{
hb_direction_t direction = c->buffer->props.direction;
unsigned int count = c->buffer->len;
@@ -993,8 +667,8 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_HORIZONTAL (direction))
{
- c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]),
- &pos[0].x_advance, sizeof(pos[0]));
+ for (unsigned int i = 0; i < count; i++)
+ pos[i].x_advance = c->font->get_glyph_h_advance (info[i].codepoint);
/* 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++)
@@ -1004,10 +678,9 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
}
else
{
- c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]),
- &pos[0].y_advance, sizeof(pos[0]));
for (unsigned int i = 0; i < count; i++)
{
+ pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint);
c->font->subtract_glyph_v_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
@@ -1018,22 +691,23 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_position_plan (const hb_ot_shape_context_t *c)
+hb_ot_position_complex (hb_ot_shape_context_t *c)
{
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 direction is forward, then when
- * zeroing mark widths, we shift the mark with it, such that the
- * mark is positioned hanging over the previous glyph. When
+ /* If the font has no GPOS, AND, no fallback positioning will
+ * happen, AND, direction is forward, then when zeroing mark
+ * widths, we shift the mark with it, such that the mark
+ * is positioned hanging over the previous glyph. When
* direction is backward we don't shift and it will end up
* hanging over the next glyph after the final reordering.
- *
- * Note: If fallback positinoing happens, we don't care about
- * this as it will be overridden.
+ * If fallback positinoing happens or GPOS is present, we don't
+ * care.
*/
- bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
+ bool adjust_offsets_when_zeroing = c->fallback_positioning &&
+ !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. */
@@ -1047,41 +721,36 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c)
hb_ot_layout_position_start (c->font, c->buffer);
- if (c->plan->zero_marks)
- switch (c->plan->shaper->zero_width_marks)
- {
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
- zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
- break;
-
- default:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
- break;
- }
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+ break;
- c->plan->position (c->font, c->buffer);
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ break;
+ }
- if (c->plan->zero_marks)
- switch (c->plan->shaper->zero_width_marks)
- {
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
- zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
- break;
-
- default:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
- break;
- }
+ if (likely (!c->fallback_positioning))
+ c->plan->position (c->font, c->buffer);
- /* Finish off. Has to follow a certain order. */
+ switch (c->plan->shaper->zero_width_marks)
+ {
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+ zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+ break;
+
+ default:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+ case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+ break;
+ }
+
+ /* Finishing off GPOS has to follow a certain order. */
hb_ot_layout_position_finish_advances (c->font, c->buffer);
- hb_ot_zero_width_default_ignorables (c->buffer);
-#ifndef HB_NO_AAT_SHAPE
- if (c->plan->apply_morx)
- hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
-#endif
+ 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. */
@@ -1090,24 +759,28 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c)
c->font->subtract_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
-
- if (c->plan->fallback_mark_positioning)
- _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer,
- adjust_offsets_when_zeroing);
}
static inline void
-hb_ot_position (const hb_ot_shape_context_t *c)
+hb_ot_position (hb_ot_shape_context_t *c)
{
c->buffer->clear_positions ();
hb_ot_position_default (c);
- hb_ot_position_plan (c);
+ hb_ot_position_complex (c);
+
+ if (c->fallback_positioning && c->plan->shaper->fallback_position)
+ _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer);
+ /* Visual fallback goes here. */
+
+ if (c->fallback_positioning)
+ _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
+
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
}
@@ -1117,42 +790,23 @@ 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_GLYPH_FLAGS))
+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
return;
- /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things:
- *
- * - If the places that the Arabic shaper marked as SAFE_TO_INSERT_TATWEEL,
- * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL,
- * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK.
- *
- * We couldn't make this interaction earlier. It has to be done here.
- */
- bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL;
-
- bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0;
-
hb_glyph_info_t *info = buffer->info;
foreach_cluster (buffer, start, end)
{
unsigned int mask = 0;
for (unsigned int i = start; i < end; i++)
- mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED;
-
- if (flip_tatweel)
- {
- if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
- mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL;
- if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL)
- mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT;
- }
-
- if (clear_concat)
- mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT;
-
- for (unsigned int i = start; i < end; i++)
- info[i].mask = mask;
+ 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;
}
}
@@ -1161,11 +815,31 @@ hb_propagate_flags (hb_buffer_t *buffer)
static void
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_LEN_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);
+ c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c->face);
+ c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c->face);
+
/* Save the original direction, we use it later. */
c->target_direction = c->buffer->props.direction;
_hb_buffer_allocate_unicode_vars (c->buffer);
+ c->buffer->clear_output ();
+
hb_ot_shape_initialize_masks (c);
hb_set_unicode_props (c->buffer);
hb_insert_dotted_circle (c->buffer, c->font);
@@ -1174,16 +848,16 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ensure_native_direction (c->buffer);
- if (c->plan->shaper->preprocess_text &&
- c->buffer->message(c->font, "start preprocess-text"))
- {
+ if (c->plan->shaper->preprocess_text)
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
- (void) c->buffer->message(c->font, "end preprocess-text");
- }
- hb_ot_substitute_pre (c);
+ hb_ot_substitute (c);
hb_ot_position (c);
- hb_ot_substitute_post (c);
+
+ hb_ot_hide_default_ignorables (c);
+
+ if (c->plan->shaper->postprocess_glyphs)
+ c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
hb_propagate_flags (c->buffer);
@@ -1191,7 +865,9 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
c->buffer->props.direction = c->target_direction;
- c->buffer->leave ();
+ c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+ c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
+ c->buffer->deallocate_var_all ();
}
@@ -1202,7 +878,7 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- hb_ot_shape_context_t c = {&shape_plan->ot, font, font->face, buffer, features, num_features};
+ hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
hb_ot_shape_internal (&c);
return true;
@@ -1211,12 +887,6 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
/**
* hb_ot_shape_plan_collect_lookups:
- * @shape_plan: #hb_shape_plan_t to query
- * @table_tag: GSUB or GPOS
- * @lookup_indexes: (out): The #hb_set_t set of lookups returned
- *
- * Computes the complete set of GSUB or GPOS lookups that are applicable
- * under a given @shape_plan.
*
* Since: 0.9.7
**/
@@ -1225,7 +895,8 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
hb_tag_t table_tag,
hb_set_t *lookup_indexes /* OUT */)
{
- shape_plan->ot.collect_lookups (table_tag, lookup_indexes);
+ /* XXX Does the first part always succeed? */
+ HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
}
@@ -1251,15 +922,6 @@ add_char (hb_font_t *font,
/**
* hb_ot_shape_glyphs_closure:
- * @font: #hb_font_t to work upon
- * @buffer: The input buffer to compute from
- * @features: (array length=num_features): The features enabled on the buffer
- * @num_features: The number of features enabled on the buffer
- * @glyphs: (out): The #hb_set_t set of glyphs comprising the transitive closure of the query
- *
- * Computes the transitive closure of glyphs needed for a specified
- * input buffer under the given font and feature list. The closure is
- * computed as a set, not as a list.
*
* Since: 0.9.2
**/
@@ -1270,6 +932,8 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
unsigned int num_features,
hb_set_t *glyphs)
{
+ hb_ot_shape_plan_t plan;
+
const char *shapers[] = {"ot", nullptr};
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
features, num_features, shapers);
@@ -1283,12 +947,17 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_set_t *lookups = hb_set_create ();
hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups);
- hb_ot_layout_lookups_substitute_closure (font->face, lookups, glyphs);
+
+ /* And find transitive closure. */
+ hb_set_t *copy = hb_set_create ();
+ do {
+ 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));
+ hb_set_destroy (copy);
hb_set_destroy (lookups);
hb_shape_plan_destroy (shape_plan);
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h
index afdff728334..7b1bcc06378 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh
deleted file mode 100644
index f84aa5c49ef..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright © 2010 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPE_HH
-#define HB_OT_SHAPE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-map.hh"
-#include "hb-aat-map.hh"
-
-
-struct hb_ot_shape_plan_key_t
-{
- unsigned int variations_index[2];
-
- void init (hb_face_t *face,
- const int *coords,
- unsigned num_coords)
- {
- for (unsigned int table_index = 0; table_index < 2; table_index++)
- hb_ot_layout_table_find_feature_variations (face,
- table_tags[table_index],
- coords,
- num_coords,
- &variations_index[table_index]);
- }
-
- bool equal (const hb_ot_shape_plan_key_t *other)
- {
- return 0 == hb_memcmp (this, other, sizeof (*this));
- }
-};
-
-
-struct hb_shape_plan_key_t;
-
-struct hb_ot_shape_plan_t
-{
- ~hb_ot_shape_plan_t () { fini (); }
-
- hb_segment_properties_t props;
- const struct hb_ot_shaper_t *shaper;
- hb_ot_map_t map;
- const void *data;
-#ifndef HB_NO_OT_SHAPE_FRACTIONS
- hb_mask_t frac_mask, numr_mask, dnom_mask;
-#else
- static constexpr hb_mask_t frac_mask = 0;
- static constexpr hb_mask_t numr_mask = 0;
- static constexpr hb_mask_t dnom_mask = 0;
-#endif
- hb_mask_t rtlm_mask;
-#ifndef HB_NO_OT_KERN
- hb_mask_t kern_mask;
-#else
- static constexpr hb_mask_t kern_mask = 0;
-#endif
-#ifndef HB_NO_AAT_SHAPE
- hb_mask_t trak_mask;
-#else
- static constexpr hb_mask_t trak_mask = 0;
-#endif
-
-#ifndef HB_NO_OT_KERN
- bool requested_kerning : 1;
-#else
- static constexpr bool requested_kerning = false;
-#endif
-#ifndef HB_NO_AAT_SHAPE
- bool requested_tracking : 1;
-#else
- static constexpr bool requested_tracking = false;
-#endif
-#ifndef HB_NO_OT_SHAPE_FRACTIONS
- bool has_frac : 1;
-#else
- static constexpr bool has_frac = false;
-#endif
- bool has_vert : 1;
- bool has_gpos_mark : 1;
- bool zero_marks : 1;
- bool fallback_glyph_classes : 1;
- bool fallback_mark_positioning : 1;
- bool adjust_mark_positioning_when_zeroing : 1;
-
- bool apply_gpos : 1;
-#ifndef HB_NO_OT_KERN
- bool apply_kern : 1;
-#else
- static constexpr bool apply_kern = false;
-#endif
- bool apply_fallback_kern : 1;
-#ifndef HB_NO_AAT_SHAPE
- bool apply_kerx : 1;
- bool apply_morx : 1;
- bool apply_trak : 1;
-#else
- static constexpr bool apply_kerx = false;
- static constexpr bool apply_morx = false;
- static constexpr bool apply_trak = false;
-#endif
-
- void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
- {
- unsigned int table_index;
- switch (table_tag) {
- case HB_OT_TAG_GSUB: table_index = 0; break;
- case HB_OT_TAG_GPOS: table_index = 1; break;
- default: return;
- }
- map.collect_lookups (table_index, lookups);
- }
-
- HB_INTERNAL bool init0 (hb_face_t *face,
- const hb_shape_plan_key_t *key);
- HB_INTERNAL void fini ();
-
- HB_INTERNAL void substitute (hb_font_t *font, hb_buffer_t *buffer) const;
- HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const;
-};
-
-struct hb_shape_plan_t;
-
-struct hb_ot_shape_planner_t
-{
- /* In the order that they are filled in. */
- hb_face_t *face;
- hb_segment_properties_t props;
- hb_ot_map_builder_t map;
-#ifndef HB_NO_AAT_SHAPE
- bool apply_morx : 1;
-#else
- static constexpr bool apply_morx = false;
-#endif
- bool script_zero_marks : 1;
- bool script_fallback_mark_positioning : 1;
- const struct hb_ot_shaper_t *shaper;
-
- HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face,
- const hb_segment_properties_t &props);
-
- HB_INTERNAL void compile (hb_ot_shape_plan_t &plan,
- const hb_ot_shape_plan_key_t &key);
-};
-
-
-#endif /* HB_OT_SHAPE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-joining-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-joining-list.hh
deleted file mode 100644
index c7b57820afc..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-joining-list.hh
+++ /dev/null
@@ -1,47 +0,0 @@
-/* == Start of generated function == */
-/*
- * The following function is generated by running:
- *
- * ./gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt
- *
- * on files with these headers:
- *
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
- */
-
-#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
-#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
-
-static bool
-has_arabic_joining (hb_script_t script)
-{
- /* List of scripts that have data in arabic-table. */
- switch ((int) script)
- {
- case HB_SCRIPT_ADLAM:
- case HB_SCRIPT_ARABIC:
- case HB_SCRIPT_CHORASMIAN:
- case HB_SCRIPT_HANIFI_ROHINGYA:
- case HB_SCRIPT_MANDAIC:
- case HB_SCRIPT_MANICHAEAN:
- case HB_SCRIPT_MONGOLIAN:
- case HB_SCRIPT_NKO:
- case HB_SCRIPT_OLD_UYGHUR:
- case HB_SCRIPT_PHAGS_PA:
- case HB_SCRIPT_PSALTER_PAHLAVI:
- case HB_SCRIPT_SOGDIAN:
- case HB_SCRIPT_SYRIAC:
- return true;
-
- default:
- return false;
- }
-}
-
-
-#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */
-
-/* == End of generated function == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-pua.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-pua.hh
deleted file mode 100644
index ba86772f849..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-arabic-pua.hh
+++ /dev/null
@@ -1,118 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-arabic-pua.py
- *
- */
-
-#ifndef HB_OT_SHAPER_ARABIC_PUA_HH
-#define HB_OT_SHAPER_ARABIC_PUA_HH
-
-static const uint8_t
-_hb_arabic_u8[464] =
-{
- 84, 86, 85, 85, 85, 85, 85,213, 16, 34, 34, 34, 34, 34, 35, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 36, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 82, 16, 0, 0, 0, 0, 1, 2, 3, 4,
- 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7,
- 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 0, 0, 0, 22, 0, 23, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 16, 34, 34, 34, 35, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 66, 16, 50, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68,101, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,152,186, 76, 77, 68,254, 16, 50,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 5, 6,
- 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 10, 0,
- 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 23, 23, 29, 30, 31, 32, 33, 0, 0, 0, 0,
- 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 40,
- 41, 42, 0, 43, 44, 0, 0, 45, 46, 0, 47, 48, 49, 0, 0, 0,
- 0, 50, 0, 0, 51, 52, 0, 53, 54, 55, 56, 57, 58, 0, 0, 0,
- 0, 0, 59, 60, 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 66,
- 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
- 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
-};
-static const uint16_t
-_hb_arabic_u16[720] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0,61728,61729,61730, 0, 0,61733, 0, 0,
- 61736,61737,61738,61739,61790,61741,61742,61743,61872,61873,61874,61875,61876,61877,61878,61879,
- 61880,61881,61754,61755, 0,61757, 0,61759, 0, 0, 0,61787,61788,61789, 0, 0,
- 0, 0, 0,61731, 0, 0, 0, 0, 0, 0, 0,61732, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,61734, 0, 0, 0, 0, 0, 0, 0,61735,
- 0, 0, 0, 0,61740, 0, 0, 0, 0, 0, 0,61755, 0, 0, 0,61759,
- 0,61869,61765,61763,61883,61767,61882,61761,61770,61865,61772,61774,61777,61780,61783,61784,
- 61785,61786,61792,61794,61796,61798,61800,61801,61802,61806,61810,61696,61696,61696,61696,61696,
- 61791,61813,61816,61818,61820,61822,61921,61860,61861,61868,61864,61895,61896,61899,61892,61893,
- 61898,61897,61894,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696,61696, 0,
- 61744,61745,61746,61747,61748,61749,61750,61751,61752,61753, 0,61790,61790, 0, 0, 0,
- 0, 0, 0, 0,61708,61709,61710,61711,61756,61758, 0, 0, 0, 0, 0, 0,
- 0,61765,61766,61763,61764,61883,61883,61767,61768,61882,61871,61870,61870,61761,61762,61770,
- 61770,61769,61769,61865,61866,61772,61772,61771,61771,61774,61774,61773,61773,61777,61776,61775,
- 61775,61780,61779,61778,61778,61783,61782,61781,61781,61784,61784,61785,61785,61786,61786,61792,
- 61792,61794,61794,61793,61793,61796,61796,61795,61795,61798,61798,61797,61797,61800,61800,61799,
- 61799,61801,61801,61801,61801,61802,61802,61802,61802,61806,61805,61803,61804,61810,61809,61807,
- 61808,61813,61813,61811,61812,61816,61816,61814,61815,61818,61818,61817,61817,61820,61820,61819,
- 61819,61822,61822,61821,61821,61921,61921,61823,61823,61860,61859,61857,61858,61861,61861,61868,
- 61867,61864,61863,61862,61862,61888,61889,61886,61887,61890,61891,61885,61884, 0, 0, 0,
- 0, 0, 0, 0,61984,61985,61986, 0, 0,61989, 0, 0,61992,61993,61994,61995,
- 62046,61997,61998,61999, 0, 0,62010,62011, 0,62013, 0,62015, 0, 0, 0,62043,
- 0,62045, 0, 0, 0, 0, 0,61987, 0, 0, 0,61988, 0, 0, 0,61990,
- 0, 0, 0,61991,61996, 0, 0, 0, 0, 0, 0,62011, 0, 0, 0,62015,
- 0,62165,62021,62019,62170,62023,62169,62017,62028,62161,62032,62036,62040,62048,62052,62053,
- 62055,62057,62059,62064,62068,62072,62078,62114,62115,62122,62126,61952,61952,61952,61952,61952,
- 62047,62130,62134,62138,62142,62146,62150,62154,62155,62164,62160,62183,62184,62187,62180,62181,
- 62186,62185,62182,61952,61952,61952,61952, 0,62000,62001,62002,62003,62004,62005,62006,62007,
- 62008,62009, 0,62046,62046, 0, 0, 0,61964,61965,61966,61967,62012,62014, 0, 0,
- 61954, 0,61981, 0, 0, 0,61955, 0,61982, 0,61956, 0, 0, 0,62111, 0,
- 0, 0, 0,61970,61971,61972,61957, 0,61980, 0, 0, 0, 0, 0,61958, 0,
- 61983, 0, 0, 0, 0, 0,62191, 0,62188,62189,62192, 0, 0, 0,61973, 0,
- 0,62098, 0, 0,61974, 0, 0,62099, 0, 0,62101, 0, 0,61975, 0, 0,
- 62100, 0, 0, 0,62080,62081,62082,62102, 0,62083,62084,62085,62103, 0, 0, 0,
- 62106, 0,62107, 0,62108, 0, 0, 0,61976, 0, 0, 0, 0,62086,62087,62088,
- 62109,61978,62089,62090,62091,62110,62093,62094, 0,62104, 0, 0, 0, 0,62095,62096,
- 62097,62105, 0, 0,61977, 0, 0, 0, 0, 0,62075,62077,61968, 0, 0, 0,
- 0,62021,62022,62019,62020,62170,62171,62023,62024,62169,62168,62166,62167,62017,62018,62028,
- 62027,62025,62026,62161,62162,62032,62031,62029,62030,62036,62035,62033,62034,62040,62039,62037,
- 62038,62048,62044,62041,62042,62052,62051,62049,62050,62053,62054,62055,62056,62057,62058,62059,
- 62060,62064,62063,62061,62062,62068,62067,62065,62066,62072,62071,62069,62070,62078,62076,62073,
- 62074,62114,62113,62079,62193,62118,62117,62115,62116,62122,62121,62119,62120,62126,62125,62123,
- 62124,62130,62129,62127,62128,62134,62133,62131,62132,62138,62137,62135,62136,62142,62141,62139,
- 62140,62146,62145,62143,62144,62150,62149,62147,62148,62154,62153,62151,62152,62155,62156,62164,
- 62163,62160,62159,62157,62158,62176,62177,62174,62175,62178,62179,62172,62173, 0, 0, 0,
-};
-
-static inline unsigned
-_hb_arabic_b2 (const uint8_t* a, unsigned i)
-{
- return (a[i>>2]>>((i&3u)<<1))&3u;
-}
-static inline unsigned
-_hb_arabic_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline uint_fast16_t
-_hb_arabic_pua_simp_map (unsigned u)
-{
- return u<65277u?_hb_arabic_u16[((_hb_arabic_u8[40+(((_hb_arabic_b4(8+_hb_arabic_u8,((_hb_arabic_b2(_hb_arabic_u8,u>>3>>4>>4))<<4)+((u>>3>>4)&15u)))<<4)+((u>>3)&15u))])<<3)+((u)&7u)]:0;
-}
-static inline uint_fast16_t
-_hb_arabic_pua_trad_map (unsigned u)
-{
- return u<65277u?_hb_arabic_u16[320+(((_hb_arabic_u8[208+(((_hb_arabic_b4(168+_hb_arabic_u8,((_hb_arabic_b4(136+_hb_arabic_u8,u>>2>>4>>4))<<4)+((u>>2>>4)&15u)))<<4)+((u>>2)&15u))])<<2)+((u)&3u))]:0;
-}
-
-#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */
-
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
deleted file mode 100644
index 7dd47755af0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
+++ /dev/null
@@ -1,627 +0,0 @@
-
-#line 1 "hb-ot-shaper-indic-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPER_INDIC_MACHINE_HH
-#define HB_OT_SHAPER_INDIC_MACHINE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-layout.hh"
-#include "hb-ot-shaper-indic.hh"
-
-/* buffer var allocations */
-#define indic_category() ot_shaper_var_u8_category() /* indic_category_t */
-#define indic_position() ot_shaper_var_u8_auxiliary() /* indic_position_t */
-
-using indic_category_t = unsigned;
-using indic_position_t = ot_position_t;
-
-#define I_Cat(Cat) indic_syllable_machine_ex_##Cat
-
-enum indic_syllable_type_t {
- indic_consonant_syllable,
- indic_vowel_syllable,
- indic_standalone_cluster,
- indic_symbol_cluster,
- indic_broken_cluster,
- indic_non_indic_cluster,
-};
-
-
-#line 54 "hb-ot-shaper-indic-machine.hh"
-#define indic_syllable_machine_ex_A 9u
-#define indic_syllable_machine_ex_C 1u
-#define indic_syllable_machine_ex_CM 16u
-#define indic_syllable_machine_ex_CS 18u
-#define indic_syllable_machine_ex_DOTTEDCIRCLE 11u
-#define indic_syllable_machine_ex_H 4u
-#define indic_syllable_machine_ex_M 7u
-#define indic_syllable_machine_ex_MPst 13u
-#define indic_syllable_machine_ex_N 3u
-#define indic_syllable_machine_ex_PLACEHOLDER 10u
-#define indic_syllable_machine_ex_RS 12u
-#define indic_syllable_machine_ex_Ra 15u
-#define indic_syllable_machine_ex_Repha 14u
-#define indic_syllable_machine_ex_SM 8u
-#define indic_syllable_machine_ex_Symbol 17u
-#define indic_syllable_machine_ex_V 2u
-#define indic_syllable_machine_ex_VD 9u
-#define indic_syllable_machine_ex_X 0u
-#define indic_syllable_machine_ex_ZWJ 6u
-#define indic_syllable_machine_ex_ZWNJ 5u
-
-
-#line 75 "hb-ot-shaper-indic-machine.hh"
-static const unsigned char _indic_syllable_machine_trans_keys[] = {
- 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
- 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
- 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u,
- 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u,
- 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u,
- 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u,
- 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u,
- 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u,
- 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u,
- 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u,
- 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u,
- 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u,
- 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u,
- 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u,
- 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u,
- 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u,
- 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u,
- 5u, 9u, 1u, 15u, 0
-};
-
-static const char _indic_syllable_machine_key_spans[] = {
- 1, 10, 9, 9, 1, 10, 10, 10,
- 1, 9, 9, 1, 10, 10, 10, 10,
- 1, 9, 9, 1, 10, 10, 10, 1,
- 9, 9, 1, 10, 10, 9, 1, 18,
- 14, 14, 13, 15, 5, 5, 1, 5,
- 15, 15, 15, 11, 10, 9, 9, 10,
- 5, 7, 5, 14, 14, 14, 14, 13,
- 15, 14, 14, 13, 15, 5, 1, 5,
- 15, 15, 11, 10, 9, 9, 10, 5,
- 5, 7, 5, 14, 14, 10, 14, 14,
- 13, 15, 14, 15, 5, 1, 5, 15,
- 15, 11, 10, 9, 9, 14, 10, 5,
- 5, 7, 5, 14, 10, 10, 14, 14,
- 13, 15, 14, 15, 5, 1, 5, 15,
- 15, 11, 10, 9, 9, 14, 10, 5,
- 5, 7, 5, 16, 14, 16, 10, 9,
- 9, 1, 5, 15, 7, 5, 5, 1,
- 5, 15
-};
-
-static const short _indic_syllable_machine_index_offsets[] = {
- 0, 2, 13, 23, 33, 35, 46, 57,
- 68, 70, 80, 90, 92, 103, 114, 125,
- 136, 138, 148, 158, 160, 171, 182, 193,
- 195, 205, 215, 217, 228, 239, 249, 251,
- 270, 285, 300, 314, 330, 336, 342, 344,
- 350, 366, 382, 398, 410, 421, 431, 441,
- 452, 458, 466, 472, 487, 502, 517, 532,
- 546, 562, 577, 592, 606, 622, 628, 630,
- 636, 652, 668, 680, 691, 701, 711, 722,
- 728, 734, 742, 748, 763, 778, 789, 804,
- 819, 833, 849, 864, 880, 886, 888, 894,
- 910, 926, 938, 949, 959, 969, 984, 995,
- 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073,
- 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163,
- 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264,
- 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350,
- 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414,
- 1416, 1422
-};
-
-static const unsigned char _indic_syllable_machine_indicies[] = {
- 1, 0, 2, 3, 3, 4, 5, 0,
- 0, 0, 0, 4, 0, 3, 3, 4,
- 6, 0, 0, 0, 0, 4, 0, 3,
- 3, 4, 5, 0, 0, 0, 0, 4,
- 0, 4, 0, 7, 3, 3, 4, 5,
- 0, 0, 0, 0, 4, 0, 2, 3,
- 3, 4, 5, 0, 0, 0, 8, 4,
- 0, 10, 11, 11, 12, 13, 9, 9,
- 9, 9, 12, 9, 14, 9, 11, 11,
- 12, 15, 9, 9, 9, 9, 12, 9,
- 11, 11, 12, 13, 9, 9, 9, 9,
- 12, 9, 12, 9, 16, 11, 11, 12,
- 13, 9, 9, 9, 9, 12, 9, 10,
- 11, 11, 12, 13, 9, 9, 9, 17,
- 12, 9, 10, 11, 11, 12, 13, 9,
- 9, 9, 18, 12, 9, 20, 21, 21,
- 22, 23, 19, 19, 19, 24, 22, 19,
- 25, 19, 21, 21, 22, 27, 26, 26,
- 26, 26, 22, 26, 21, 21, 22, 23,
- 19, 19, 19, 19, 22, 19, 22, 26,
- 20, 21, 21, 22, 23, 19, 19, 19,
- 19, 22, 19, 28, 21, 21, 22, 23,
- 19, 19, 19, 19, 22, 19, 30, 31,
- 31, 32, 33, 29, 29, 29, 34, 32,
- 29, 35, 29, 31, 31, 32, 36, 29,
- 29, 29, 29, 32, 29, 31, 31, 32,
- 33, 29, 29, 29, 29, 32, 29, 32,
- 29, 30, 31, 31, 32, 33, 29, 29,
- 29, 29, 32, 29, 37, 31, 31, 32,
- 33, 29, 29, 29, 29, 32, 29, 21,
- 21, 22, 38, 0, 0, 0, 0, 22,
- 0, 40, 39, 42, 43, 44, 45, 46,
- 47, 22, 23, 48, 49, 49, 24, 22,
- 50, 51, 52, 53, 54, 41, 56, 57,
- 58, 59, 4, 5, 60, 55, 55, 8,
- 4, 55, 55, 61, 55, 62, 57, 63,
- 63, 4, 5, 60, 55, 55, 55, 4,
- 55, 55, 61, 55, 57, 63, 63, 4,
- 5, 60, 55, 55, 55, 4, 55, 55,
- 61, 55, 42, 55, 55, 55, 64, 65,
- 55, 1, 60, 55, 55, 55, 55, 55,
- 42, 55, 66, 66, 55, 1, 60, 55,
- 60, 55, 55, 67, 60, 55, 60, 55,
- 60, 55, 55, 55, 60, 55, 42, 55,
- 68, 55, 66, 66, 55, 1, 60, 55,
- 55, 55, 55, 55, 42, 55, 42, 55,
- 55, 55, 66, 66, 55, 1, 60, 55,
- 55, 55, 55, 55, 42, 55, 42, 55,
- 55, 55, 66, 65, 55, 1, 60, 55,
- 55, 55, 55, 55, 42, 55, 69, 70,
- 71, 71, 4, 5, 60, 55, 55, 55,
- 4, 55, 70, 71, 71, 4, 5, 60,
- 55, 55, 55, 4, 55, 71, 71, 4,
- 5, 60, 55, 55, 55, 4, 55, 60,
- 55, 55, 67, 60, 55, 55, 55, 4,
- 55, 72, 73, 73, 4, 5, 60, 55,
- 55, 55, 4, 55, 64, 74, 55, 1,
- 60, 55, 64, 55, 66, 66, 55, 1,
- 60, 55, 66, 74, 55, 1, 60, 55,
- 56, 57, 63, 63, 4, 5, 60, 55,
- 55, 55, 4, 55, 55, 61, 55, 56,
- 57, 58, 63, 4, 5, 60, 55, 55,
- 8, 4, 55, 55, 61, 55, 76, 77,
- 78, 79, 12, 13, 80, 75, 75, 18,
- 12, 75, 75, 81, 75, 82, 77, 83,
- 79, 12, 13, 80, 75, 75, 75, 12,
- 75, 75, 81, 75, 77, 83, 79, 12,
- 13, 80, 75, 75, 75, 12, 75, 75,
- 81, 75, 84, 75, 75, 75, 85, 86,
- 75, 14, 80, 75, 75, 75, 75, 75,
- 84, 75, 87, 77, 88, 89, 12, 13,
- 80, 75, 75, 17, 12, 75, 75, 81,
- 75, 90, 77, 83, 83, 12, 13, 80,
- 75, 75, 75, 12, 75, 75, 81, 75,
- 77, 83, 83, 12, 13, 80, 75, 75,
- 75, 12, 75, 75, 81, 75, 84, 75,
- 75, 75, 91, 86, 75, 14, 80, 75,
- 75, 75, 75, 75, 84, 75, 80, 75,
- 75, 92, 80, 75, 80, 75, 80, 75,
- 75, 75, 80, 75, 84, 75, 93, 75,
- 91, 91, 75, 14, 80, 75, 75, 75,
- 75, 75, 84, 75, 84, 75, 75, 75,
- 91, 91, 75, 14, 80, 75, 75, 75,
- 75, 75, 84, 75, 94, 95, 96, 96,
- 12, 13, 80, 75, 75, 75, 12, 75,
- 95, 96, 96, 12, 13, 80, 75, 75,
- 75, 12, 75, 96, 96, 12, 13, 80,
- 75, 75, 75, 12, 75, 80, 75, 75,
- 92, 80, 75, 75, 75, 12, 75, 97,
- 98, 98, 12, 13, 80, 75, 75, 75,
- 12, 75, 85, 99, 75, 14, 80, 75,
- 91, 91, 75, 14, 80, 75, 85, 75,
- 91, 91, 75, 14, 80, 75, 91, 99,
- 75, 14, 80, 75, 87, 77, 83, 83,
- 12, 13, 80, 75, 75, 75, 12, 75,
- 75, 81, 75, 87, 77, 88, 83, 12,
- 13, 80, 75, 75, 17, 12, 75, 75,
- 81, 75, 10, 11, 11, 12, 13, 75,
- 75, 75, 75, 12, 75, 76, 77, 83,
- 79, 12, 13, 80, 75, 75, 75, 12,
- 75, 75, 81, 75, 101, 45, 102, 102,
- 22, 23, 48, 100, 100, 100, 22, 100,
- 100, 52, 100, 45, 102, 102, 22, 23,
- 48, 100, 100, 100, 22, 100, 100, 52,
- 100, 103, 100, 100, 100, 104, 105, 100,
- 25, 48, 100, 100, 100, 100, 100, 103,
- 100, 44, 45, 106, 107, 22, 23, 48,
- 100, 100, 24, 22, 100, 100, 52, 100,
- 103, 100, 100, 100, 108, 105, 100, 25,
- 48, 100, 100, 100, 100, 100, 103, 100,
- 48, 100, 100, 109, 48, 100, 48, 100,
- 48, 100, 100, 100, 48, 100, 103, 100,
- 110, 100, 108, 108, 100, 25, 48, 100,
- 100, 100, 100, 100, 103, 100, 103, 100,
- 100, 100, 108, 108, 100, 25, 48, 100,
- 100, 100, 100, 100, 103, 100, 111, 112,
- 113, 113, 22, 23, 48, 100, 100, 100,
- 22, 100, 112, 113, 113, 22, 23, 48,
- 100, 100, 100, 22, 100, 113, 113, 22,
- 23, 48, 100, 100, 100, 22, 100, 48,
- 100, 100, 109, 48, 100, 100, 100, 22,
- 100, 44, 45, 102, 102, 22, 23, 48,
- 100, 100, 100, 22, 100, 100, 52, 100,
- 114, 115, 115, 22, 23, 48, 100, 100,
- 100, 22, 100, 104, 116, 100, 25, 48,
- 100, 108, 108, 100, 25, 48, 100, 104,
- 100, 108, 108, 100, 25, 48, 100, 108,
- 116, 100, 25, 48, 100, 44, 45, 106,
- 102, 22, 23, 48, 100, 100, 24, 22,
- 100, 100, 52, 100, 20, 21, 21, 22,
- 23, 117, 117, 117, 24, 22, 117, 20,
- 21, 21, 22, 23, 117, 117, 117, 117,
- 22, 117, 119, 120, 121, 122, 32, 33,
- 123, 118, 118, 34, 32, 118, 118, 124,
- 118, 125, 120, 122, 122, 32, 33, 123,
- 118, 118, 118, 32, 118, 118, 124, 118,
- 120, 122, 122, 32, 33, 123, 118, 118,
- 118, 32, 118, 118, 124, 118, 126, 118,
- 118, 118, 127, 128, 118, 35, 123, 118,
- 118, 118, 118, 118, 126, 118, 119, 120,
- 121, 49, 32, 33, 123, 118, 118, 34,
- 32, 118, 118, 124, 118, 126, 118, 118,
- 118, 129, 128, 118, 35, 123, 118, 118,
- 118, 118, 118, 126, 118, 123, 118, 118,
- 130, 123, 118, 123, 118, 123, 118, 118,
- 118, 123, 118, 126, 118, 131, 118, 129,
- 129, 118, 35, 123, 118, 118, 118, 118,
- 118, 126, 118, 126, 118, 118, 118, 129,
- 129, 118, 35, 123, 118, 118, 118, 118,
- 118, 126, 118, 132, 133, 134, 134, 32,
- 33, 123, 118, 118, 118, 32, 118, 133,
- 134, 134, 32, 33, 123, 118, 118, 118,
- 32, 118, 134, 134, 32, 33, 123, 118,
- 118, 118, 32, 118, 123, 118, 118, 130,
- 123, 118, 118, 118, 32, 118, 119, 120,
- 122, 122, 32, 33, 123, 118, 118, 118,
- 32, 118, 118, 124, 118, 135, 136, 136,
- 32, 33, 123, 118, 118, 118, 32, 118,
- 127, 137, 118, 35, 123, 118, 129, 129,
- 118, 35, 123, 118, 127, 118, 129, 129,
- 118, 35, 123, 118, 129, 137, 118, 35,
- 123, 118, 42, 43, 44, 45, 106, 102,
- 22, 23, 48, 49, 49, 24, 22, 100,
- 42, 52, 100, 56, 138, 58, 59, 4,
- 5, 60, 55, 55, 8, 4, 55, 55,
- 61, 55, 42, 43, 44, 45, 139, 140,
- 22, 141, 142, 55, 49, 24, 22, 55,
- 42, 52, 55, 20, 143, 143, 22, 141,
- 60, 55, 55, 24, 22, 55, 60, 55,
- 55, 67, 60, 55, 55, 55, 22, 55,
- 142, 55, 55, 144, 142, 55, 55, 55,
- 22, 55, 142, 55, 142, 55, 55, 55,
- 142, 55, 42, 55, 68, 20, 143, 143,
- 22, 141, 60, 55, 55, 55, 22, 55,
- 42, 55, 146, 145, 147, 147, 145, 40,
- 148, 145, 147, 147, 145, 40, 148, 145,
- 148, 145, 145, 149, 148, 145, 148, 145,
- 148, 145, 145, 145, 148, 145, 42, 117,
- 117, 117, 117, 117, 117, 117, 117, 49,
- 117, 117, 117, 117, 42, 117, 0
-};
-
-static const unsigned char _indic_syllable_machine_trans_targs[] = {
- 31, 37, 42, 2, 43, 46, 4, 50,
- 51, 31, 60, 9, 66, 69, 61, 11,
- 74, 75, 78, 31, 83, 17, 89, 92,
- 93, 84, 31, 19, 98, 31, 107, 24,
- 113, 116, 117, 108, 26, 122, 127, 31,
- 134, 31, 32, 53, 79, 81, 100, 101,
- 85, 102, 123, 124, 94, 132, 137, 31,
- 33, 35, 6, 52, 38, 47, 34, 1,
- 36, 40, 0, 39, 41, 44, 45, 3,
- 48, 5, 49, 31, 54, 56, 14, 77,
- 62, 70, 55, 7, 57, 72, 64, 58,
- 13, 76, 59, 8, 63, 65, 67, 68,
- 10, 71, 12, 73, 31, 80, 20, 82,
- 96, 87, 15, 99, 16, 86, 88, 90,
- 91, 18, 95, 21, 97, 31, 31, 103,
- 105, 22, 27, 109, 118, 104, 106, 120,
- 111, 23, 110, 112, 114, 115, 25, 119,
- 28, 121, 125, 126, 131, 128, 129, 29,
- 130, 31, 133, 30, 135, 136
-};
-
-static const char _indic_syllable_machine_trans_actions[] = {
- 1, 0, 2, 0, 2, 0, 0, 2,
- 2, 3, 2, 0, 2, 0, 0, 0,
- 2, 2, 2, 4, 2, 0, 5, 0,
- 5, 0, 6, 0, 2, 7, 2, 0,
- 2, 0, 2, 0, 0, 2, 0, 8,
- 0, 11, 2, 2, 5, 0, 12, 12,
- 0, 2, 5, 2, 5, 2, 0, 13,
- 2, 0, 0, 2, 0, 2, 2, 0,
- 2, 2, 0, 0, 2, 2, 2, 0,
- 0, 0, 2, 14, 2, 0, 0, 2,
- 0, 2, 2, 0, 2, 2, 2, 2,
- 0, 2, 2, 0, 0, 2, 2, 2,
- 0, 0, 0, 2, 15, 5, 0, 5,
- 2, 2, 0, 5, 0, 0, 2, 5,
- 5, 0, 0, 0, 2, 16, 17, 2,
- 0, 0, 0, 0, 2, 2, 2, 2,
- 2, 0, 0, 2, 2, 2, 0, 0,
- 0, 2, 0, 18, 18, 0, 0, 0,
- 0, 19, 2, 0, 0, 0
-};
-
-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, 9,
- 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, 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, 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, 0
-};
-
-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, 10,
- 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, 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, 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, 0
-};
-
-static const short _indic_syllable_machine_eof_trans[] = {
- 1, 1, 1, 1, 1, 1, 1, 10,
- 10, 10, 10, 10, 10, 10, 10, 20,
- 20, 27, 20, 27, 20, 20, 30, 30,
- 30, 30, 30, 30, 30, 1, 40, 0,
- 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 76, 76, 76,
- 76, 76, 76, 76, 76, 76, 76, 76,
- 76, 76, 76, 76, 76, 76, 76, 76,
- 76, 76, 76, 76, 76, 76, 76, 101,
- 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, 118, 118, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 119, 119, 119, 119, 119,
- 119, 119, 119, 101, 56, 56, 56, 56,
- 56, 56, 56, 56, 146, 146, 146, 146,
- 146, 118
-};
-
-static const int indic_syllable_machine_start = 31;
-static const int indic_syllable_machine_first_final = 31;
-static const int indic_syllable_machine_error = -1;
-
-static const int indic_syllable_machine_en_main = 31;
-
-
-#line 58 "hb-ot-shaper-indic-machine.rl"
-
-
-
-#line 118 "hb-ot-shaper-indic-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (syllable_serial == 16) syllable_serial = 1; \
- } HB_STMT_END
-
-inline void
-find_syllables_indic (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 453 "hb-ot-shaper-indic-machine.hh"
- {
- cs = indic_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 138 "hb-ot-shaper-indic-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 465 "hb-ot-shaper-indic-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const unsigned char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _indic_syllable_machine_from_state_actions[cs] ) {
- case 10:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 477 "hb-ot-shaper-indic-machine.hh"
- }
-
- _keys = _indic_syllable_machine_trans_keys + (cs<<1);
- _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
-
- _slen = _indic_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
- ( info[p].indic_category()) <= _keys[1] ?
- ( info[p].indic_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _indic_syllable_machine_trans_targs[_trans];
-
- if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _indic_syllable_machine_trans_actions[_trans] ) {
- case 2:
-#line 1 "NONE"
- {te = p+1;}
- break;
- case 11:
-#line 114 "hb-ot-shaper-indic-machine.rl"
- {te = p+1;{ found_syllable (indic_non_indic_cluster); }}
- break;
- case 13:
-#line 109 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_consonant_syllable); }}
- break;
- case 14:
-#line 110 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_vowel_syllable); }}
- break;
- case 17:
-#line 111 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_standalone_cluster); }}
- break;
- case 19:
-#line 112 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_symbol_cluster); }}
- break;
- case 15:
-#line 113 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 16:
-#line 114 "hb-ot-shaper-indic-machine.rl"
- {te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
- break;
- case 1:
-#line 109 "hb-ot-shaper-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
- break;
- case 3:
-#line 110 "hb-ot-shaper-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
- break;
- case 7:
-#line 111 "hb-ot-shaper-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
- break;
- case 8:
-#line 112 "hb-ot-shaper-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
- break;
- case 4:
-#line 113 "hb-ot-shaper-indic-machine.rl"
- {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 6:
-#line 1 "NONE"
- { switch( act ) {
- case 1:
- {{p = ((te))-1;} found_syllable (indic_consonant_syllable); }
- break;
- case 5:
- {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
- break;
- case 6:
- {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); }
- break;
- }
- }
- break;
- case 18:
-#line 1 "NONE"
- {te = p+1;}
-#line 109 "hb-ot-shaper-indic-machine.rl"
- {act = 1;}
- break;
- case 5:
-#line 1 "NONE"
- {te = p+1;}
-#line 113 "hb-ot-shaper-indic-machine.rl"
- {act = 5;}
- break;
- case 12:
-#line 1 "NONE"
- {te = p+1;}
-#line 114 "hb-ot-shaper-indic-machine.rl"
- {act = 6;}
- break;
-#line 559 "hb-ot-shaper-indic-machine.hh"
- }
-
-_again:
- switch ( _indic_syllable_machine_to_state_actions[cs] ) {
- case 9:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 566 "hb-ot-shaper-indic-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _indic_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 146 "hb-ot-shaper-indic-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPER_INDIC_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-table.cc
deleted file mode 100644
index d9fb0510e44..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-table.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
- *
- * on files with these headers:
- *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-indic.hh"
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-macros"
-
-#include "hb-ot-shaper-indic-machine.hh"
-#include "hb-ot-shaper-khmer-machine.hh"
-#include "hb-ot-shaper-myanmar-machine.hh"
-
-/* indic */
-#define OT_X I_Cat(X)
-#define OT_C I_Cat(C)
-#define OT_V I_Cat(V)
-#define OT_N I_Cat(N)
-#define OT_H I_Cat(H)
-#define OT_ZWNJ I_Cat(ZWNJ)
-#define OT_ZWJ I_Cat(ZWJ)
-#define OT_M I_Cat(M)
-#define OT_SM I_Cat(SM)
-#define OT_A I_Cat(A)
-#define OT_VD I_Cat(VD)
-#define OT_PLACEHOLDER I_Cat(PLACEHOLDER)
-#define OT_DOTTEDCIRCLE I_Cat(DOTTEDCIRCLE)
-#define OT_RS I_Cat(RS)
-#define OT_MPst I_Cat(MPst)
-#define OT_Repha I_Cat(Repha)
-#define OT_Ra I_Cat(Ra)
-#define OT_CM I_Cat(CM)
-#define OT_Symbol I_Cat(Symbol)
-#define OT_CS I_Cat(CS)
-/* khmer */
-#define OT_VAbv K_Cat(VAbv)
-#define OT_VBlw K_Cat(VBlw)
-#define OT_VPre K_Cat(VPre)
-#define OT_VPst K_Cat(VPst)
-#define OT_Robatic K_Cat(Robatic)
-#define OT_Xgroup K_Cat(Xgroup)
-#define OT_Ygroup K_Cat(Ygroup)
-/* myanmar */
-static_assert (OT_VAbv == M_Cat(VAbv), "");
-static_assert (OT_VBlw == M_Cat(VBlw), "");
-static_assert (OT_VPre == M_Cat(VPre), "");
-static_assert (OT_VPst == M_Cat(VPst), "");
-#define OT_IV M_Cat(IV)
-#define OT_As M_Cat(As)
-#define OT_DB M_Cat(DB)
-#define OT_GB M_Cat(GB)
-#define OT_MH M_Cat(MH)
-#define OT_MR M_Cat(MR)
-#define OT_MW M_Cat(MW)
-#define OT_MY M_Cat(MY)
-#define OT_PT M_Cat(PT)
-#define OT_VS M_Cat(VS)
-#define OT_ML M_Cat(ML)
-
-
-#define _OT_A OT_A /* 53 chars; A */
-#define _OT_As OT_As /* 1 chars; As */
-#define _OT_C OT_C /* 478 chars; C */
-#define _OT_CM OT_CM /* 1 chars; CM */
-#define _OT_CS OT_CS /* 2 chars; CS */
-#define _OT_DC OT_DOTTEDCIRCLE /* 1 chars; DOTTEDCIRCLE */
-#define _OT_H OT_H /* 11 chars; H */
-#define _OT_M OT_M /* 142 chars; M */
-#define _OT_MH OT_MH /* 1 chars; MH */
-#define _OT_ML OT_ML /* 1 chars; ML */
-#define _OT_MP OT_MPst /* 1 chars; MPst */
-#define _OT_MR OT_MR /* 1 chars; MR */
-#define _OT_MW OT_MW /* 2 chars; MW */
-#define _OT_MY OT_MY /* 3 chars; MY */
-#define _OT_N OT_N /* 17 chars; N */
-#define _OT_GB OT_PLACEHOLDER /* 165 chars; PLACEHOLDER */
-#define _OT_PT OT_PT /* 8 chars; PT */
-#define _OT_R OT_Ra /* 14 chars; Ra */
-#define _OT_Rf OT_Repha /* 1 chars; Repha */
-#define _OT_Rt OT_Robatic /* 3 chars; Robatic */
-#define _OT_SM OT_SM /* 56 chars; SM */
-#define _OT_S OT_Symbol /* 22 chars; Symbol */
-#define _OT_V OT_V /* 172 chars; V */
-#define _OT_VA OT_VAbv /* 18 chars; VAbv */
-#define _OT_VB OT_VBlw /* 7 chars; VBlw */
-#define _OT_VL OT_VPre /* 5 chars; VPre */
-#define _OT_VR OT_VPst /* 13 chars; VPst */
-#define _OT_VS OT_VS /* 16 chars; VS */
-#define _OT_X OT_X /* 2 chars; X */
-#define _OT_Xg OT_Xgroup /* 7 chars; Xgroup */
-#define _OT_Yg OT_Ygroup /* 4 chars; Ygroup */
-#define _OT_ZWJ OT_ZWJ /* 1 chars; ZWJ */
-#define _OT_ZWNJ OT_ZWNJ /* 1 chars; ZWNJ */
-
-#define _POS_T POS_ABOVE_C /* 22 chars; ABOVE_C */
-#define _POS_A POS_AFTER_MAIN /* 3 chars; AFTER_MAIN */
-#define _POS_AP POS_AFTER_POST /* 50 chars; AFTER_POST */
-#define _POS_AS POS_AFTER_SUB /* 51 chars; AFTER_SUB */
-#define _POS_C POS_BASE_C /* 833 chars; BASE_C */
-#define _POS_BS POS_BEFORE_SUB /* 25 chars; BEFORE_SUB */
-#define _POS_B POS_BELOW_C /* 13 chars; BELOW_C */
-#define _POS_X POS_END /* 71 chars; END */
-#define _POS_R POS_POST_C /* 13 chars; POST_C */
-#define _POS_L POS_PRE_C /* 5 chars; PRE_C */
-#define _POS_LM POS_PRE_M /* 14 chars; PRE_M */
-#define _POS_SM POS_SMVD /* 130 chars; SMVD */
-
-#pragma GCC diagnostic pop
-
-#define INDIC_COMBINE_CATEGORIES(S,M) ((S) | ((M) << 8))
-
-#define _(S,M) INDIC_COMBINE_CATEGORIES (_OT_##S, _POS_##M)
-
-
-static const uint16_t indic_table[] = {
-
-
-#define indic_offset_0x0028u 0
-
-
- /* Basic Latin */
-
- /* 0028 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X),
- /* 0030 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0038 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x00b0u 24
-
-
- /* Latin-1 Supplement */
-
- /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 00B8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 00C0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 00C8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 00D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C),
-
-#define indic_offset_0x0900u 64
-
-
- /* Devanagari */
-
- /* 0900 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 0908 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 0910 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0918 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0920 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0928 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0930 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0938 */ _(C,C), _(C,C), _(M,AS), _(M,AS), _(N,X), _(S,SM), _(M,AS), _(M,LM),
- /* 0940 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS),
- /* 0948 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(H,B), _(M,LM), _(M,AS),
- /* 0950 */ _(X,X), _(A,SM), _(A,SM),_(SM,SM),_(SM,SM), _(M,AS), _(M,AS), _(M,AS),
- /* 0958 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0960 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0968 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0970 */ _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 0978 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
-
- /* Bengali */
-
- /* 0980 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0988 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C),
- /* 0990 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0998 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 09A0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 09A8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 09B0 */ _(R,C), _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C),
- /* 09B8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM),
- /* 09C0 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM),
- /* 09C8 */ _(M,LM), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(C,C), _(X,X),
- /* 09D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
- /* 09D8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C),
- /* 09E0 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 09E8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 09F0 */ _(R,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 09F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X),_(SM,SM), _(X,X),
-
- /* Gurmukhi */
-
- /* 0A00 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0A08 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C),
- /* 0A10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0A18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0A20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X),
- /* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM),
- /* 0A40 */_(MP,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
- /* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
- /* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X),
- /* 0A60 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0A68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0A70 */_(SM,SM),_(SM,SM), _(C,C), _(C,C), _(X,X), _(CM,C), _(X,X), _(X,X),
- /* 0A78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
- /* Gujarati */
-
- /* 0A80 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0A88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C),
- /* 0A90 */ _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0A98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0AA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0AA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0AB0 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
- /* 0AB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM),
- /* 0AC0 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AS), _(X,X), _(M,AS),
- /* 0AC8 */ _(M,AS), _(M,AP), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
- /* 0AD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0AD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0AE0 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0AE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0AF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0AF8 */ _(X,X), _(C,C), _(A,SM), _(N,X), _(A,SM), _(N,X), _(N,X), _(N,X),
-
- /* Oriya */
-
- /* 0B00 */ _(X,X),_(SM,BS),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0B08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C),
- /* 0B10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0B18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0B20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0B28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0B30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
- /* 0B38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,A),
- /* 0B40 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM),
- /* 0B48 */ _(M,A), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X),
- /* 0B50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(N,X), _(M,A), _(M,AP),
- /* 0B58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C),
- /* 0B60 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0B68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0B70 */ _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0B78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
- /* Tamil */
-
- /* 0B80 */ _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0B88 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(V,C), _(V,C),
- /* 0B90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(X,X), _(X,X),
- /* 0B98 */ _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), _(C,C), _(C,C),
- /* 0BA0 */ _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X),
- /* 0BA8 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C),
- /* 0BB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0BB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), _(M,AP),
- /* 0BC0 */ _(M,AS), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(M,LM), _(M,LM),
- /* 0BC8 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(X,X), _(X,X),
- /* 0BD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP),
- /* 0BD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0BE0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0BE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0BF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0BF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
- /* Telugu */
-
- /* 0C00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C),
- /* 0C08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
- /* 0C10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0C18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0C20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0C28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0C30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0C38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS),
- /* 0C40 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,BS),
- /* 0C48 */ _(M,BS), _(X,X), _(M,BS), _(M,BS), _(M,BS), _(H,T), _(X,X), _(X,X),
- /* 0C50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,BS), _(M,BS), _(X,X),
- /* 0C58 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(C,C), _(X,X), _(X,X),
- /* 0C60 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0C68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0C70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0C78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
- /* Kannada */
-
- /* 0C80 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C),
- /* 0C88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
- /* 0C90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0C98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0CA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0CA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0CB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C),
- /* 0CB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS),
- /* 0CC0 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,AS),
- /* 0CC8 */ _(M,AS), _(X,X), _(M,AS), _(M,AS), _(M,BS), _(H,T), _(X,X), _(X,X),
- /* 0CD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AS), _(M,AS), _(X,X),
- /* 0CD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X),
- /* 0CE0 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0CE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0CF0 */ _(X,X), _(CS,C), _(CS,C),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0CF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
- /* Malayalam */
-
- /* 0D00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(GB,C), _(V,C), _(V,C), _(V,C),
- /* 0D08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C),
- /* 0D10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C),
- /* 0D18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0D20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0D28 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0D30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 0D38 */ _(C,C), _(C,C), _(C,C), _(M,AS), _(M,AS), _(S,SM), _(M,AP), _(M,AP),
- /* 0D40 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(X,X), _(M,LM), _(M,LM),
- /* 0D48 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(Rf,X), _(X,X),
- /* 0D50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(M,AP),
- /* 0D58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C),
- /* 0D60 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C),
- /* 0D68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 0D70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 0D78 */ _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
-
-#define indic_offset_0x1000u 1216
-
-
- /* Myanmar */
-
- /* 1000 */ _(C,C), _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C),
- /* 1008 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1010 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1018 */ _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1020 */ _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 1028 */ _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), _(VA,T), _(VA,T), _(VB,B),
- /* 1030 */ _(VB,B), _(VL,L), _(A,SM), _(VA,T), _(VA,T), _(VA,T), _(A,SM), _(N,X),
- /* 1038 */_(SM,SM), _(H,X), _(As,X), _(MY,X), _(MR,X), _(MW,X), _(MH,X), _(C,C),
- /* 1040 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 1048 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(C,C), _(X,X),
- /* 1050 */ _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R),
- /* 1058 */ _(VB,B), _(VB,B), _(R,C), _(C,C), _(C,C), _(C,C), _(MY,X), _(MY,X),
- /* 1060 */ _(ML,X), _(C,C), _(VR,R), _(PT,X), _(PT,X), _(C,C), _(C,C), _(VR,R),
- /* 1068 */ _(VR,R), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(C,C), _(C,C),
- /* 1070 */ _(C,C), _(VA,T), _(VA,T), _(VA,T), _(VA,T), _(C,C), _(C,C), _(C,C),
- /* 1078 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1080 */ _(C,C), _(C,C), _(MW,X), _(VR,R), _(VL,L), _(VA,T), _(VA,T),_(SM,SM),
- /* 1088 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(C,C),_(SM,SM),
- /* 1090 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 1098 */ _(GB,C), _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(VA,T), _(X,X), _(X,X),
-
-#define indic_offset_0x1780u 1376
-
-
- /* Khmer */
-
- /* 1780 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1788 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1790 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 1798 */ _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* 17A0 */ _(C,C), _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 17A8 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C),
- /* 17B0 */ _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(VR,R), _(VA,T),
- /* 17B8 */ _(VA,T), _(VA,T), _(VA,T), _(VB,B), _(VB,B), _(VB,B), _(VA,T), _(VR,R),
- /* 17C0 */ _(VR,R), _(VL,L), _(VL,L), _(VL,L), _(VR,R), _(VR,R), _(Xg,X), _(Yg,X),
- /* 17C8 */ _(Yg,X), _(Rt,X), _(Rt,X), _(Xg,X), _(Rt,X), _(Xg,X), _(Xg,X), _(Xg,X),
- /* 17D0 */ _(Xg,X), _(Xg,X), _(H,X), _(Yg,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 17D8 */ _(X,X), _(GB,C), _(X,X), _(X,X), _(S,SM), _(Yg,X), _(X,X), _(X,X),
- /* 17E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* 17E8 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x1cd0u 1488
-
-
- /* Vedic Extensions */
-
- /* 1CD0 */ _(A,SM), _(A,SM), _(A,SM), _(X,X), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
- /* 1CD8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
- /* 1CE0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
- /* 1CE8 */ _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(A,SM), _(S,SM), _(S,SM),
- /* 1CF0 */ _(S,SM), _(S,SM), _(C,C), _(C,C), _(A,SM), _(C,C), _(C,C), _(A,SM),
- /* 1CF8 */ _(A,SM), _(A,SM), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x2008u 1536
-
-
- /* General Punctuation */
-
- /* 2008 */ _(X,X), _(X,X), _(X,X), _(X,X),_(ZWNJ,X),_(ZWJ,X), _(X,X), _(X,X),
- /* 2010 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X),
- /* 2018 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 2020 */ _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x2070u 1568
-
-
- /* Superscripts and Subscripts */
-
- /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(X,X),
- /* 2078 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X),
- /* 2080 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x25f8u 1592
-
-
- /* Geometric Shapes */
-
- /* 25F8 */ _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X),
-
-#define indic_offset_0xa8e0u 1600
-
-
- /* Devanagari Extended */
-
- /* A8E0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
- /* A8E8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM),
- /* A8F0 */ _(A,SM), _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM),
- /* A8F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), _(M,AS),
-
-#define indic_offset_0xa9e0u 1632
-
-
- /* Myanmar Extended-B */
-
- /* A9E0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(VA,T), _(X,X), _(C,C),
- /* A9E8 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* A9F0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C),
- /* A9F8 */ _(GB,C), _(GB,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X),
-
-#define indic_offset_0xaa60u 1664
-
-
- /* Myanmar Extended-A */
-
- /* AA60 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* AA68 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C),
- /* AA70 */ _(X,X), _(C,C), _(C,C), _(C,C), _(GB,C), _(GB,C), _(GB,C), _(X,X),
- /* AA78 */ _(X,X), _(X,X), _(C,C), _(PT,X), _(N,X), _(N,X), _(C,C), _(C,C),
-
-#define indic_offset_0xfe00u 1696
-
-
- /* Variation Selectors */
-
- /* FE00 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X),
- /* FE08 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X),
-
-#define indic_offset_0x11300u 1712
-
-
- /* Grantha */
-
- /* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X),
-
-#define indic_offset_0x11338u 1720
-
- /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X),
-
-}; /* Table items: 1728; occupancy: 71% */
-
-uint16_t
-hb_indic_get_categories (hb_codepoint_t u)
-{
- switch (u >> 12)
- {
- case 0x0u:
- if (unlikely (u == 0x00A0u)) return _(GB,C);
- 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, 0x0D7Fu)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
- break;
-
- case 0x1u:
- 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 (unlikely (u == 0x25CCu)) return _(DC,C);
- if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2027u)) 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 (hb_in_range<hb_codepoint_t> (u, 0x25F8u, 0x25FFu)) return indic_table[u - 0x25F8u + indic_offset_0x25f8u];
- break;
-
- case 0xAu:
- if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8FFu)) 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;
-
- case 0xFu:
- if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return indic_table[u - 0xFE00u + indic_offset_0xfe00u];
- break;
-
- case 0x11u:
- if (hb_in_range<hb_codepoint_t> (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u];
- if (hb_in_range<hb_codepoint_t> (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u];
- break;
-
- default:
- break;
- }
- return _(X,X);
-}
-
-#undef _
-#undef INDIC_COMBINE_CATEGORIES
-
-#undef _OT_A
-#undef _OT_As
-#undef _OT_C
-#undef _OT_CM
-#undef _OT_CS
-#undef _OT_DC
-#undef _OT_H
-#undef _OT_M
-#undef _OT_MH
-#undef _OT_ML
-#undef _OT_MP
-#undef _OT_MR
-#undef _OT_MW
-#undef _OT_MY
-#undef _OT_N
-#undef _OT_GB
-#undef _OT_PT
-#undef _OT_R
-#undef _OT_Rf
-#undef _OT_Rt
-#undef _OT_SM
-#undef _OT_S
-#undef _OT_V
-#undef _OT_VA
-#undef _OT_VB
-#undef _OT_VL
-#undef _OT_VR
-#undef _OT_VS
-#undef _OT_X
-#undef _OT_Xg
-#undef _OT_Yg
-#undef _OT_ZWJ
-#undef _OT_ZWNJ
-
-#undef _POS_T
-#undef _POS_A
-#undef _POS_AP
-#undef _POS_AS
-#undef _POS_C
-#undef _POS_BS
-#undef _POS_B
-#undef _POS_X
-#undef _POS_R
-#undef _POS_L
-#undef _POS_LM
-#undef _POS_SM
-
-#endif
-
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh
deleted file mode 100644
index 848ed231f71..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh
+++ /dev/null
@@ -1,428 +0,0 @@
-
-#line 1 "hb-ot-shaper-khmer-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPER_KHMER_MACHINE_HH
-#define HB_OT_SHAPER_KHMER_MACHINE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-layout.hh"
-#include "hb-ot-shaper-indic.hh"
-
-/* buffer var allocations */
-#define khmer_category() ot_shaper_var_u8_category() /* khmer_category_t */
-
-using khmer_category_t = unsigned;
-
-#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat
-
-enum khmer_syllable_type_t {
- khmer_consonant_syllable,
- khmer_broken_cluster,
- khmer_non_khmer_cluster,
-};
-
-
-#line 49 "hb-ot-shaper-khmer-machine.hh"
-#define khmer_syllable_machine_ex_C 1u
-#define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
-#define khmer_syllable_machine_ex_H 4u
-#define khmer_syllable_machine_ex_PLACEHOLDER 10u
-#define khmer_syllable_machine_ex_Ra 15u
-#define khmer_syllable_machine_ex_Robatic 25u
-#define khmer_syllable_machine_ex_V 2u
-#define khmer_syllable_machine_ex_VAbv 20u
-#define khmer_syllable_machine_ex_VBlw 21u
-#define khmer_syllable_machine_ex_VPre 22u
-#define khmer_syllable_machine_ex_VPst 23u
-#define khmer_syllable_machine_ex_Xgroup 26u
-#define khmer_syllable_machine_ex_Ygroup 27u
-#define khmer_syllable_machine_ex_ZWJ 6u
-#define khmer_syllable_machine_ex_ZWNJ 5u
-
-
-#line 65 "hb-ot-shaper-khmer-machine.hh"
-static const unsigned char _khmer_syllable_machine_trans_keys[] = {
- 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
- 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
- 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 27u, 4u, 27u, 1u, 15u,
- 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u, 4u, 27u,
- 4u, 27u, 1u, 15u, 4u, 27u, 4u, 27u, 27u, 27u, 4u, 27u, 4u, 27u, 4u, 27u,
- 4u, 27u, 4u, 27u, 5u, 26u, 0
-};
-
-static const char _khmer_syllable_machine_key_spans[] = {
- 22, 22, 15, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 15, 22, 22,
- 22, 22, 22, 22, 22, 27, 24, 15,
- 24, 24, 1, 24, 24, 24, 24, 24,
- 24, 15, 24, 24, 1, 24, 24, 24,
- 24, 24, 22
-};
-
-static const short _khmer_syllable_machine_index_offsets[] = {
- 0, 23, 46, 62, 85, 108, 131, 154,
- 177, 200, 223, 246, 269, 292, 308, 331,
- 354, 377, 400, 423, 446, 469, 497, 522,
- 538, 563, 588, 590, 615, 640, 665, 690,
- 715, 740, 756, 781, 806, 808, 833, 858,
- 883, 908, 933
-};
-
-static const char _khmer_syllable_machine_indicies[] = {
- 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 0, 3, 4, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 4, 0, 5, 5,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 0, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 4, 0, 6, 6, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 2, 0, 7, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8, 0, 9, 9, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 2, 0, 0, 0, 0, 0,
- 10, 0, 9, 9, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 10,
- 0, 11, 11, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 0, 0, 0, 0, 0, 12, 0,
- 11, 11, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 12, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 0,
- 0, 0, 0, 13, 4, 0, 15, 15,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 16, 14, 14,
- 14, 14, 17, 18, 14, 15, 15, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 18, 19, 20, 20, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 20, 14, 15, 15, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 16, 14, 14, 14, 14,
- 14, 18, 14, 21, 21, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 16, 14, 22, 22, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 23,
- 14, 24, 24, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 16, 14, 14, 14, 14, 14, 25, 14,
- 24, 24, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 25, 14, 26,
- 26, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 16, 14,
- 14, 14, 14, 14, 27, 14, 26, 26,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 27, 14, 29, 29, 28,
- 30, 31, 31, 28, 28, 28, 13, 13,
- 28, 28, 28, 29, 28, 28, 28, 28,
- 16, 25, 27, 23, 28, 17, 18, 20,
- 28, 33, 34, 34, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 2, 10, 12, 8, 32, 13, 4,
- 5, 32, 35, 35, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 35, 32, 33, 36, 36, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 2, 10, 12, 8, 32, 3,
- 4, 5, 32, 37, 38, 38, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 2, 10, 12, 8, 32,
- 32, 4, 5, 32, 5, 32, 37, 6,
- 6, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 8, 32, 32, 2, 5, 32, 37,
- 7, 7, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 8, 5, 32,
- 37, 39, 39, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 2, 32, 32, 8, 32, 32, 10, 5,
- 32, 37, 40, 40, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 2, 10, 32, 8, 32, 32, 12,
- 5, 32, 33, 38, 38, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 2, 10, 12, 8, 32, 32,
- 4, 5, 32, 33, 38, 38, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 2, 10, 12, 8, 32,
- 3, 4, 5, 32, 42, 42, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 42, 41, 30, 43, 43, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 16, 25, 27, 23,
- 41, 17, 18, 20, 41, 44, 45, 45,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 16, 25, 27,
- 23, 41, 41, 18, 20, 41, 20, 41,
- 44, 21, 21, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 23, 41, 41, 16, 20,
- 41, 44, 22, 22, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 23,
- 20, 41, 44, 46, 46, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 16, 41, 41, 23, 41, 41,
- 25, 20, 41, 44, 47, 47, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 16, 25, 41, 23, 41,
- 41, 27, 20, 41, 30, 45, 45, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 16, 25, 27, 23,
- 41, 41, 18, 20, 41, 15, 15, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 16, 48, 48, 48,
- 48, 48, 18, 48, 0
-};
-
-static const char _khmer_syllable_machine_trans_targs[] = {
- 21, 1, 27, 31, 25, 26, 4, 5,
- 28, 7, 29, 9, 30, 32, 21, 12,
- 37, 41, 35, 21, 36, 15, 16, 38,
- 18, 39, 20, 40, 21, 22, 33, 42,
- 21, 23, 10, 24, 0, 2, 3, 6,
- 8, 21, 34, 11, 13, 14, 17, 19,
- 21
-};
-
-static const char _khmer_syllable_machine_trans_actions[] = {
- 1, 0, 2, 2, 2, 0, 0, 0,
- 2, 0, 2, 0, 2, 2, 3, 0,
- 2, 4, 4, 5, 0, 0, 0, 2,
- 0, 2, 0, 2, 8, 2, 0, 9,
- 10, 0, 0, 2, 0, 0, 0, 0,
- 0, 11, 4, 0, 0, 0, 0, 0,
- 12
-};
-
-static const char _khmer_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, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
-};
-
-static const char _khmer_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, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
-};
-
-static const short _khmer_syllable_machine_eof_trans[] = {
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 15, 20, 15, 15, 15,
- 15, 15, 15, 15, 15, 0, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 49
-};
-
-static const int khmer_syllable_machine_start = 21;
-static const int khmer_syllable_machine_first_final = 21;
-static const int khmer_syllable_machine_error = -1;
-
-static const int khmer_syllable_machine_en_main = 21;
-
-
-#line 53 "hb-ot-shaper-khmer-machine.rl"
-
-
-
-#line 102 "hb-ot-shaper-khmer-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (syllable_serial == 16) syllable_serial = 1; \
- } HB_STMT_END
-
-inline void
-find_syllables_khmer (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act HB_UNUSED;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 287 "hb-ot-shaper-khmer-machine.hh"
- {
- cs = khmer_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 122 "hb-ot-shaper-khmer-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 299 "hb-ot-shaper-khmer-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
- case 7:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 311 "hb-ot-shaper-khmer-machine.hh"
- }
-
- _keys = _khmer_syllable_machine_trans_keys + (cs<<1);
- _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
-
- _slen = _khmer_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) &&
- ( info[p].khmer_category()) <= _keys[1] ?
- ( info[p].khmer_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _khmer_syllable_machine_trans_targs[_trans];
-
- if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
- case 2:
-#line 1 "NONE"
- {te = p+1;}
- break;
- case 8:
-#line 98 "hb-ot-shaper-khmer-machine.rl"
- {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }}
- break;
- case 10:
-#line 96 "hb-ot-shaper-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_consonant_syllable); }}
- break;
- case 11:
-#line 97 "hb-ot-shaper-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 12:
-#line 98 "hb-ot-shaper-khmer-machine.rl"
- {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }}
- break;
- case 1:
-#line 96 "hb-ot-shaper-khmer-machine.rl"
- {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }}
- break;
- case 3:
-#line 97 "hb-ot-shaper-khmer-machine.rl"
- {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 5:
-#line 1 "NONE"
- { switch( act ) {
- case 2:
- {{p = ((te))-1;} found_syllable (khmer_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }
- break;
- case 3:
- {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); }
- break;
- }
- }
- break;
- case 4:
-#line 1 "NONE"
- {te = p+1;}
-#line 97 "hb-ot-shaper-khmer-machine.rl"
- {act = 2;}
- break;
- case 9:
-#line 1 "NONE"
- {te = p+1;}
-#line 98 "hb-ot-shaper-khmer-machine.rl"
- {act = 3;}
- break;
-#line 368 "hb-ot-shaper-khmer-machine.hh"
- }
-
-_again:
- switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
- case 6:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 375 "hb-ot-shaper-khmer-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _khmer_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 130 "hb-ot-shaper-khmer-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPER_KHMER_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer.cc
deleted file mode 100644
index 019a285102a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-khmer-machine.hh"
-#include "hb-ot-shaper-indic.hh"
-#include "hb-ot-layout.hh"
-
-
-/*
- * Khmer shaper.
- */
-
-
-static const hb_ot_map_feature_t
-khmer_features[] =
-{
- /*
- * Basic features.
- * These features are applied all at once, before reordering, constrained
- * to the syllable.
- */
- {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
- /*
- * Other features.
- * These features are applied all at once after clearing syllables.
- */
- {HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
- {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
- {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
- {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
-};
-
-/*
- * Must be in the same order as the khmer_features array.
- */
-enum {
- KHMER_PREF,
- KHMER_BLWF,
- KHMER_ABVF,
- KHMER_PSTF,
- KHMER_CFAR,
-
- _KHMER_PRES,
- _KHMER_ABVS,
- _KHMER_BLWS,
- _KHMER_PSTS,
-
- KHMER_NUM_FEATURES,
- KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
-};
-
-static inline void
-set_khmer_properties (hb_glyph_info_t &info)
-{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
-
- info.khmer_category() = (khmer_category_t) (type & 0xFFu);
-}
-
-static bool
-setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-reorder_khmer (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-static void
-collect_features_khmer (hb_ot_shape_planner_t *plan)
-{
- hb_ot_map_builder_t *map = &plan->map;
-
- /* Do this before any lookups have been applied. */
- map->add_gsub_pause (setup_syllables_khmer);
- map->add_gsub_pause (reorder_khmer);
-
- /* Testing suggests that Uniscribe does NOT pause between basic
- * features. Test with KhmerUI.ttf and the following three
- * sequences:
- *
- * U+1789,U+17BC
- * U+1789,U+17D2,U+1789
- * U+1789,U+17D2,U+1789,U+17BC
- *
- * https://github.com/harfbuzz/harfbuzz/issues/974
- */
- map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
- map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
-
- unsigned int i = 0;
- for (; i < KHMER_BASIC_FEATURES; i++)
- map->add_feature (khmer_features[i]);
-
- /* https://github.com/harfbuzz/harfbuzz/issues/3531 */
- map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
-
- for (; i < KHMER_NUM_FEATURES; i++)
- map->add_feature (khmer_features[i]);
-}
-
-static void
-override_features_khmer (hb_ot_shape_planner_t *plan)
-{
- hb_ot_map_builder_t *map = &plan->map;
-
- /* Khmer spec has 'clig' as part of required shaping features:
- * "Apply feature 'clig' to form ligatures that are desired for
- * typographical correctness.", hence in overrides... */
- map->enable_feature (HB_TAG('c','l','i','g'));
-
- /* Uniscribe does not apply 'kern' in Khmer. */
- if (hb_options ().uniscribe_bug_compatible)
- {
- map->disable_feature (HB_TAG('k','e','r','n'));
- }
-
- map->disable_feature (HB_TAG('l','i','g','a'));
-}
-
-
-struct khmer_shape_plan_t
-{
- hb_mask_t mask_array[KHMER_NUM_FEATURES];
-};
-
-static void *
-data_create_khmer (const hb_ot_shape_plan_t *plan)
-{
- khmer_shape_plan_t *khmer_plan = (khmer_shape_plan_t *) hb_calloc (1, sizeof (khmer_shape_plan_t));
- if (unlikely (!khmer_plan))
- return nullptr;
-
- for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++)
- khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ?
- 0 : plan->map.get_1_mask (khmer_features[i].tag);
-
- return khmer_plan;
-}
-
-static void
-data_destroy_khmer (void *data)
-{
- hb_free (data);
-}
-
-static void
-setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
-{
- HB_BUFFER_ALLOCATE_VAR (buffer, khmer_category);
-
- /* We cannot setup masks here. We save information about characters
- * and setup masks later on in a pause-callback. */
-
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- for (unsigned int i = 0; i < count; i++)
- set_khmer_properties (info[i]);
-}
-
-static bool
-setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
- find_syllables_khmer (buffer);
- foreach_syllable (buffer, start, end)
- buffer->unsafe_to_break (start, end);
- return false;
-}
-
-
-/* Rules from:
- * https://docs.microsoft.com/en-us/typography/script-development/devanagari */
-
-static void
-reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
- hb_face_t *face HB_UNUSED,
- hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
-{
- const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
- hb_glyph_info_t *info = buffer->info;
-
- /* Setup masks. */
- {
- /* Post-base */
- hb_mask_t mask = khmer_plan->mask_array[KHMER_BLWF] |
- khmer_plan->mask_array[KHMER_ABVF] |
- khmer_plan->mask_array[KHMER_PSTF];
- for (unsigned int i = start + 1; i < end; i++)
- info[i].mask |= mask;
- }
-
- unsigned int num_coengs = 0;
- for (unsigned int i = start + 1; i < end; i++)
- {
- /* """
- * When a COENG + (Cons | IndV) combination are found (and subscript count
- * is less than two) the character combination is handled according to the
- * subscript type of the character following the COENG.
- *
- * ...
- *
- * Subscript Type 2 - The COENG + RO characters are reordered to immediately
- * before the base glyph. Then the COENG + RO characters are assigned to have
- * the 'pref' OpenType feature applied to them.
- * """
- */
- if (info[i].khmer_category() == K_Cat(H) && num_coengs <= 2 && i + 1 < end)
- {
- num_coengs++;
-
- if (info[i + 1].khmer_category() == K_Cat(Ra))
- {
- for (unsigned int j = 0; j < 2; j++)
- info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
-
- /* Move the Coeng,Ro sequence to the start. */
- buffer->merge_clusters (start, i + 2);
- hb_glyph_info_t t0 = info[i];
- hb_glyph_info_t t1 = info[i + 1];
- memmove (&info[start + 2], &info[start], (i - start) * sizeof (info[0]));
- info[start] = t0;
- info[start + 1] = t1;
-
- /* Mark the subsequent stuff with 'cfar'. Used in Khmer.
- * Read the feature spec.
- * This allows distinguishing the following cases with MS Khmer fonts:
- * U+1784,U+17D2,U+179A,U+17D2,U+1782
- * U+1784,U+17D2,U+1782,U+17D2,U+179A
- */
- if (khmer_plan->mask_array[KHMER_CFAR])
- for (unsigned int j = i + 2; j < end; j++)
- info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
-
- num_coengs = 2; /* Done. */
- }
- }
-
- /* Reorder left matra piece. */
- else if (info[i].khmer_category() == K_Cat(VPre))
- {
- /* Move to the start. */
- buffer->merge_clusters (start, i + 1);
- hb_glyph_info_t t = info[i];
- memmove (&info[start + 1], &info[start], (i - start) * sizeof (info[0]));
- info[start] = t;
- }
- }
-}
-
-static void
-reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
- hb_face_t *face,
- hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
-{
- khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
- switch (syllable_type)
- {
- case khmer_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
- case khmer_consonant_syllable:
- reorder_consonant_syllable (plan, face, buffer, start, end);
- break;
-
- case khmer_non_khmer_cluster:
- break;
- }
-}
-
-static bool
-reorder_khmer (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- bool ret = false;
- if (buffer->message (font, "start reordering khmer"))
- {
- if (hb_syllabic_insert_dotted_circles (font, buffer,
- khmer_broken_cluster,
- K_Cat(DOTTEDCIRCLE),
- (unsigned) -1))
- ret = true;
-
- foreach_syllable (buffer, start, end)
- reorder_syllable_khmer (plan, font->face, buffer, start, end);
- (void) buffer->message (font, "end reordering khmer");
- }
- HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
-
- return ret;
-}
-
-
-static bool
-decompose_khmer (const hb_ot_shape_normalize_context_t *c,
- hb_codepoint_t ab,
- hb_codepoint_t *a,
- hb_codepoint_t *b)
-{
- switch (ab)
- {
- /*
- * Decompose split matras that don't have Unicode decompositions.
- */
-
- /* Khmer */
- case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true;
- case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true;
- case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true;
- case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true;
- case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true;
- }
-
- return (bool) c->unicode->decompose (ab, a, b);
-}
-
-static bool
-compose_khmer (const hb_ot_shape_normalize_context_t *c,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab)
-{
- /* Avoid recomposing split matras. */
- if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
- return false;
-
- return (bool) c->unicode->compose (a, b, ab);
-}
-
-
-const hb_ot_shaper_t _hb_ot_shaper_khmer =
-{
- collect_features_khmer,
- override_features_khmer,
- data_create_khmer,
- data_destroy_khmer,
- nullptr, /* preprocess_text */
- nullptr, /* postprocess_glyphs */
- decompose_khmer,
- compose_khmer,
- setup_masks_khmer,
- nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
- false, /* fallback_position */
-};
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh
deleted file mode 100644
index 809f6eefb02..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh
+++ /dev/null
@@ -1,553 +0,0 @@
-
-#line 1 "hb-ot-shaper-myanmar-machine.rl"
-/*
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPER_MYANMAR_MACHINE_HH
-#define HB_OT_SHAPER_MYANMAR_MACHINE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-layout.hh"
-#include "hb-ot-shaper-indic.hh"
-
-/* buffer var allocations */
-#define myanmar_category() ot_shaper_var_u8_category() /* myanmar_category_t */
-#define myanmar_position() ot_shaper_var_u8_auxiliary() /* myanmar_position_t */
-
-using myanmar_category_t = unsigned;
-using myanmar_position_t = ot_position_t;
-
-#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat
-
-enum myanmar_syllable_type_t {
- myanmar_consonant_syllable,
- myanmar_broken_cluster,
- myanmar_non_myanmar_cluster,
-};
-
-
-#line 51 "hb-ot-shaper-myanmar-machine.hh"
-#define myanmar_syllable_machine_ex_A 9u
-#define myanmar_syllable_machine_ex_As 32u
-#define myanmar_syllable_machine_ex_C 1u
-#define myanmar_syllable_machine_ex_CS 18u
-#define myanmar_syllable_machine_ex_DB 3u
-#define myanmar_syllable_machine_ex_DOTTEDCIRCLE 11u
-#define myanmar_syllable_machine_ex_GB 10u
-#define myanmar_syllable_machine_ex_H 4u
-#define myanmar_syllable_machine_ex_IV 2u
-#define myanmar_syllable_machine_ex_MH 35u
-#define myanmar_syllable_machine_ex_ML 41u
-#define myanmar_syllable_machine_ex_MR 36u
-#define myanmar_syllable_machine_ex_MW 37u
-#define myanmar_syllable_machine_ex_MY 38u
-#define myanmar_syllable_machine_ex_PT 39u
-#define myanmar_syllable_machine_ex_Ra 15u
-#define myanmar_syllable_machine_ex_SM 8u
-#define myanmar_syllable_machine_ex_VAbv 20u
-#define myanmar_syllable_machine_ex_VBlw 21u
-#define myanmar_syllable_machine_ex_VPre 22u
-#define myanmar_syllable_machine_ex_VPst 23u
-#define myanmar_syllable_machine_ex_VS 40u
-#define myanmar_syllable_machine_ex_ZWJ 6u
-#define myanmar_syllable_machine_ex_ZWNJ 5u
-
-
-#line 76 "hb-ot-shaper-myanmar-machine.hh"
-static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
- 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
- 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u,
- 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 41u,
- 3u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
- 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 41u, 3u, 39u,
- 3u, 39u, 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u,
- 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 1u, 41u, 1u, 15u, 0
-};
-
-static const char _myanmar_syllable_machine_key_spans[] = {
- 41, 39, 35, 4, 39, 37, 37, 35,
- 35, 37, 37, 39, 35, 15, 37, 37,
- 38, 37, 39, 39, 37, 39, 39, 39,
- 39, 39, 35, 4, 39, 37, 37, 35,
- 35, 37, 37, 39, 35, 15, 39, 37,
- 37, 38, 37, 39, 39, 37, 39, 39,
- 39, 39, 39, 39, 39, 41, 15
-};
-
-static const short _myanmar_syllable_machine_index_offsets[] = {
- 0, 42, 82, 118, 123, 163, 201, 239,
- 275, 311, 349, 387, 427, 463, 479, 517,
- 555, 594, 632, 672, 712, 750, 790, 830,
- 870, 910, 950, 986, 991, 1031, 1069, 1107,
- 1143, 1179, 1217, 1255, 1295, 1331, 1347, 1387,
- 1425, 1463, 1502, 1540, 1580, 1620, 1658, 1698,
- 1738, 1778, 1818, 1858, 1898, 1938, 1980
-};
-
-static const char _myanmar_syllable_machine_indicies[] = {
- 1, 1, 2, 3, 4, 4, 0, 5,
- 6, 1, 1, 0, 0, 0, 7, 0,
- 0, 8, 0, 9, 10, 11, 12, 0,
- 0, 0, 0, 0, 0, 0, 0, 13,
- 0, 0, 14, 15, 16, 17, 18, 19,
- 20, 0, 22, 23, 24, 24, 21, 25,
- 26, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 27, 28, 29, 30, 21,
- 21, 21, 21, 21, 21, 21, 21, 31,
- 21, 21, 32, 33, 34, 35, 36, 37,
- 38, 21, 24, 24, 21, 25, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 30, 21, 21, 21,
- 21, 21, 21, 21, 21, 39, 21, 21,
- 21, 21, 21, 21, 36, 21, 24, 24,
- 21, 25, 21, 22, 21, 24, 24, 21,
- 25, 26, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 40, 21, 21, 30,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 41, 21, 21, 42, 21, 21, 21, 36,
- 21, 41, 21, 22, 21, 24, 24, 21,
- 25, 26, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 30,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 36,
- 21, 43, 21, 24, 24, 21, 25, 36,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 44, 21,
- 21, 21, 21, 21, 21, 36, 21, 24,
- 24, 21, 25, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 44, 21, 21, 21, 21, 21,
- 21, 36, 21, 24, 24, 21, 25, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 36, 21, 22,
- 21, 24, 24, 21, 25, 26, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 40, 21, 21, 30, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 36, 21, 22, 21, 24,
- 24, 21, 25, 26, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 40, 21,
- 21, 30, 21, 21, 21, 21, 21, 21,
- 21, 21, 41, 21, 21, 21, 21, 21,
- 21, 36, 21, 22, 21, 24, 24, 21,
- 25, 26, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 40, 21, 21, 30,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 41, 21, 21, 21, 21, 21, 21, 36,
- 21, 41, 21, 24, 24, 21, 25, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 30, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 36, 21, 1,
- 1, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 1, 21, 22,
- 21, 24, 24, 21, 25, 26, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 27, 28, 21, 30, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 36, 21, 22, 21, 24,
- 24, 21, 25, 26, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 28,
- 21, 30, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 36, 21, 22, 21, 24, 24, 21,
- 25, 26, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 27, 28, 29, 30,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 36,
- 45, 21, 22, 21, 24, 24, 21, 25,
- 26, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 27, 28, 29, 30, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 36, 21,
- 22, 21, 24, 24, 21, 25, 26, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 27, 28, 29, 30, 21, 21, 21,
- 21, 21, 21, 21, 21, 31, 21, 21,
- 32, 33, 34, 35, 36, 21, 38, 21,
- 22, 21, 24, 24, 21, 25, 26, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 27, 28, 29, 30, 21, 21, 21,
- 21, 21, 21, 21, 21, 45, 21, 21,
- 21, 21, 21, 21, 36, 21, 38, 21,
- 22, 21, 24, 24, 21, 25, 26, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 27, 28, 29, 30, 21, 21, 21,
- 21, 21, 21, 21, 21, 45, 21, 21,
- 21, 21, 21, 21, 36, 21, 22, 21,
- 24, 24, 21, 25, 26, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 27,
- 28, 29, 30, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 32, 21,
- 34, 21, 36, 21, 38, 21, 22, 21,
- 24, 24, 21, 25, 26, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 27,
- 28, 29, 30, 21, 21, 21, 21, 21,
- 21, 21, 21, 45, 21, 21, 32, 21,
- 21, 21, 36, 21, 38, 21, 22, 21,
- 24, 24, 21, 25, 26, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 27,
- 28, 29, 30, 21, 21, 21, 21, 21,
- 21, 21, 21, 46, 21, 21, 32, 33,
- 34, 21, 36, 21, 38, 21, 22, 21,
- 24, 24, 21, 25, 26, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 27,
- 28, 29, 30, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 32, 33,
- 34, 21, 36, 21, 38, 21, 22, 23,
- 24, 24, 21, 25, 26, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 27,
- 28, 29, 30, 21, 21, 21, 21, 21,
- 21, 21, 21, 31, 21, 21, 32, 33,
- 34, 35, 36, 21, 38, 21, 48, 48,
- 47, 5, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 12, 47, 47, 47, 47, 47, 47, 47,
- 47, 49, 47, 47, 47, 47, 47, 47,
- 18, 47, 48, 48, 47, 5, 47, 2,
- 47, 48, 48, 47, 5, 6, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 50, 47, 47, 12, 47, 47, 47, 47,
- 47, 47, 47, 47, 51, 47, 47, 52,
- 47, 47, 47, 18, 47, 51, 47, 2,
- 47, 48, 48, 47, 5, 6, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 12, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 18, 47, 53, 47, 48,
- 48, 47, 5, 18, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 54, 47, 47, 47, 47, 47,
- 47, 18, 47, 48, 48, 47, 5, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 54, 47,
- 47, 47, 47, 47, 47, 18, 47, 48,
- 48, 47, 5, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 18, 47, 2, 47, 48, 48, 47,
- 5, 6, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 50, 47, 47, 12,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 18,
- 47, 2, 47, 48, 48, 47, 5, 6,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 50, 47, 47, 12, 47, 47,
- 47, 47, 47, 47, 47, 47, 51, 47,
- 47, 47, 47, 47, 47, 18, 47, 2,
- 47, 48, 48, 47, 5, 6, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 50, 47, 47, 12, 47, 47, 47, 47,
- 47, 47, 47, 47, 51, 47, 47, 47,
- 47, 47, 47, 18, 47, 51, 47, 48,
- 48, 47, 5, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 12, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 18, 47, 55, 55, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 55, 47, 2, 3, 48, 48, 47,
- 5, 6, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 9, 10, 11, 12,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 13, 47, 47, 14, 15, 16, 17, 18,
- 19, 20, 47, 2, 47, 48, 48, 47,
- 5, 6, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 9, 10, 47, 12,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 18,
- 47, 2, 47, 48, 48, 47, 5, 6,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 10, 47, 12, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 18, 47, 2,
- 47, 48, 48, 47, 5, 6, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 9, 10, 11, 12, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 18, 56, 47, 2, 47,
- 48, 48, 47, 5, 6, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 9,
- 10, 11, 12, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 18, 47, 2, 47, 48, 48,
- 47, 5, 6, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 9, 10, 11,
- 12, 47, 47, 47, 47, 47, 47, 47,
- 47, 13, 47, 47, 14, 15, 16, 17,
- 18, 47, 20, 47, 2, 47, 48, 48,
- 47, 5, 6, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 9, 10, 11,
- 12, 47, 47, 47, 47, 47, 47, 47,
- 47, 56, 47, 47, 47, 47, 47, 47,
- 18, 47, 20, 47, 2, 47, 48, 48,
- 47, 5, 6, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 9, 10, 11,
- 12, 47, 47, 47, 47, 47, 47, 47,
- 47, 56, 47, 47, 47, 47, 47, 47,
- 18, 47, 2, 47, 48, 48, 47, 5,
- 6, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 9, 10, 11, 12, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 14, 47, 16, 47, 18, 47,
- 20, 47, 2, 47, 48, 48, 47, 5,
- 6, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 9, 10, 11, 12, 47,
- 47, 47, 47, 47, 47, 47, 47, 56,
- 47, 47, 14, 47, 47, 47, 18, 47,
- 20, 47, 2, 47, 48, 48, 47, 5,
- 6, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 9, 10, 11, 12, 47,
- 47, 47, 47, 47, 47, 47, 47, 57,
- 47, 47, 14, 15, 16, 47, 18, 47,
- 20, 47, 2, 47, 48, 48, 47, 5,
- 6, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 9, 10, 11, 12, 47,
- 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 14, 15, 16, 47, 18, 47,
- 20, 47, 2, 3, 48, 48, 47, 5,
- 6, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 9, 10, 11, 12, 47,
- 47, 47, 47, 47, 47, 47, 47, 13,
- 47, 47, 14, 15, 16, 17, 18, 47,
- 20, 47, 22, 23, 24, 24, 21, 25,
- 26, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 27, 28, 29, 30, 21,
- 21, 21, 21, 21, 21, 21, 21, 58,
- 21, 21, 32, 33, 34, 35, 36, 37,
- 38, 21, 22, 59, 24, 24, 21, 25,
- 26, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 27, 28, 29, 30, 21,
- 21, 21, 21, 21, 21, 21, 21, 31,
- 21, 21, 32, 33, 34, 35, 36, 21,
- 38, 21, 1, 1, 2, 3, 48, 48,
- 47, 5, 6, 1, 1, 47, 47, 47,
- 1, 47, 47, 47, 47, 9, 10, 11,
- 12, 47, 47, 47, 47, 47, 47, 47,
- 47, 13, 47, 47, 14, 15, 16, 17,
- 18, 19, 20, 47, 1, 1, 60, 60,
- 60, 60, 60, 60, 60, 1, 1, 60,
- 60, 60, 1, 60, 0
-};
-
-static const char _myanmar_syllable_machine_trans_targs[] = {
- 0, 1, 26, 37, 0, 27, 29, 51,
- 54, 39, 40, 41, 28, 43, 44, 46,
- 47, 48, 30, 50, 45, 0, 2, 13,
- 0, 3, 5, 14, 15, 16, 4, 18,
- 19, 21, 22, 23, 6, 25, 20, 12,
- 9, 10, 11, 7, 8, 17, 24, 0,
- 0, 36, 33, 34, 35, 31, 32, 38,
- 42, 49, 52, 53, 0
-};
-
-static const char _myanmar_syllable_machine_trans_actions[] = {
- 3, 0, 0, 0, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 5, 0, 0,
- 6, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 7,
- 8, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 9
-};
-
-static const char _myanmar_syllable_machine_to_state_actions[] = {
- 1, 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, 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[] = {
- 2, 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, 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, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 22, 22, 48, 61
-};
-
-static const int myanmar_syllable_machine_start = 0;
-static const int myanmar_syllable_machine_first_final = 0;
-static const int myanmar_syllable_machine_error = -1;
-
-static const int myanmar_syllable_machine_en_main = 0;
-
-
-#line 55 "hb-ot-shaper-myanmar-machine.rl"
-
-
-
-#line 117 "hb-ot-shaper-myanmar-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
- for (unsigned int i = ts; i < te; i++) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (syllable_serial == 16) syllable_serial = 1; \
- } HB_STMT_END
-
-inline void
-find_syllables_myanmar (hb_buffer_t *buffer)
-{
- unsigned int p, pe, eof, ts, te, act HB_UNUSED;
- int cs;
- hb_glyph_info_t *info = buffer->info;
-
-#line 436 "hb-ot-shaper-myanmar-machine.hh"
- {
- cs = myanmar_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 137 "hb-ot-shaper-myanmar-machine.rl"
-
-
- p = 0;
- pe = eof = buffer->len;
-
- unsigned int syllable_serial = 1;
-
-#line 448 "hb-ot-shaper-myanmar-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
- case 2:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 460 "hb-ot-shaper-myanmar-machine.hh"
- }
-
- _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
- _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
-
- _slen = _myanmar_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
- ( info[p].myanmar_category()) <= _keys[1] ?
- ( info[p].myanmar_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _myanmar_syllable_machine_trans_targs[_trans];
-
- if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
- case 6:
-#line 110 "hb-ot-shaper-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
- break;
- case 4:
-#line 111 "hb-ot-shaper-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
- case 8:
-#line 112 "hb-ot-shaper-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 3:
-#line 113 "hb-ot-shaper-myanmar-machine.rl"
- {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
- case 5:
-#line 110 "hb-ot-shaper-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
- break;
- case 7:
-#line 112 "hb-ot-shaper-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 9:
-#line 113 "hb-ot-shaper-myanmar-machine.rl"
- {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
- break;
-#line 498 "hb-ot-shaper-myanmar-machine.hh"
- }
-
-_again:
- switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
- case 1:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 505 "hb-ot-shaper-myanmar-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 145 "hb-ot-shaper-myanmar-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPER_MYANMAR_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar.cc
deleted file mode 100644
index 1b2a085a8d7..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright © 2011,2012,2013 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.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-myanmar-machine.hh"
-#include "hb-ot-shaper-indic.hh"
-#include "hb-ot-layout.hh"
-
-
-/*
- * Myanmar shaper.
- */
-
-
-static const hb_tag_t
-myanmar_basic_features[] =
-{
- /*
- * Basic features.
- * These features are applied in order, one at a time, after reordering,
- * constrained to the syllable.
- */
- HB_TAG('r','p','h','f'),
- HB_TAG('p','r','e','f'),
- HB_TAG('b','l','w','f'),
- HB_TAG('p','s','t','f'),
-};
-static const hb_tag_t
-myanmar_other_features[] =
-{
- /*
- * Other features.
- * These features are applied all at once, after clearing syllables.
- */
- HB_TAG('p','r','e','s'),
- HB_TAG('a','b','v','s'),
- HB_TAG('b','l','w','s'),
- HB_TAG('p','s','t','s'),
-};
-
-static inline void
-set_myanmar_properties (hb_glyph_info_t &info)
-{
- hb_codepoint_t u = info.codepoint;
- unsigned int type = hb_indic_get_categories (u);
-
- info.myanmar_category() = (myanmar_category_t) (type & 0xFFu);
-}
-
-
-static inline bool
-is_one_of_myanmar (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_UNSAFE (info.myanmar_category()) & flags);
-}
-
-/* Note:
- *
- * 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!
- *
- * Keep in sync with consonant_categories in the generator. */
-#define CONSONANT_FLAGS_MYANMAR (FLAG (M_Cat(C)) | FLAG (M_Cat(CS)) | FLAG (M_Cat(Ra)) | /* FLAG (M_Cat(CM)) | */ FLAG (M_Cat(IV)) | FLAG (M_Cat(GB)) | FLAG (M_Cat(DOTTEDCIRCLE)))
-
-static inline bool
-is_consonant_myanmar (const hb_glyph_info_t &info)
-{
- return is_one_of_myanmar (info, CONSONANT_FLAGS_MYANMAR);
-}
-
-
-static bool
-setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-reorder_myanmar (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-static void
-collect_features_myanmar (hb_ot_shape_planner_t *plan)
-{
- hb_ot_map_builder_t *map = &plan->map;
-
- /* Do this before any lookups have been applied. */
- map->add_gsub_pause (setup_syllables_myanmar);
-
- map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
- /* The Indic specs do not require ccmp, but we apply it here since if
- * there is a use of it, it's typically at the beginning. */
- map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
-
-
- map->add_gsub_pause (reorder_myanmar);
-
- for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
- {
- map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
- map->add_gsub_pause (nullptr);
- }
- map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
-
- for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
- map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
-}
-
-static void
-setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
-{
- HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
- HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
-
- /* No masks, we just save information about characters. */
-
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- for (unsigned int i = 0; i < count; i++)
- set_myanmar_properties (info[i]);
-}
-
-static bool
-setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
- find_syllables_myanmar (buffer);
- foreach_syllable (buffer, start, end)
- buffer->unsafe_to_break (start, end);
- return false;
-}
-
-static int
-compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
-{
- int a = pa->myanmar_position();
- int b = pb->myanmar_position();
-
- return (int) a - (int) b;
-}
-
-
-/* Rules from:
- * https://docs.microsoft.com/en-us/typography/script-development/myanmar */
-
-static void
-initial_reordering_consonant_syllable (hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
-{
- hb_glyph_info_t *info = buffer->info;
-
- unsigned int base = end;
- bool has_reph = false;
-
- {
- unsigned int limit = start;
- if (start + 3 <= end &&
- info[start ].myanmar_category() == M_Cat(Ra) &&
- info[start+1].myanmar_category() == M_Cat(As) &&
- info[start+2].myanmar_category() == M_Cat(H))
- {
- limit += 3;
- base = start;
- has_reph = true;
- }
-
- {
- if (!has_reph)
- base = limit;
-
- for (unsigned int i = limit; i < end; i++)
- if (is_consonant_myanmar (info[i]))
- {
- base = i;
- break;
- }
- }
- }
-
- /* Reorder! */
- {
- unsigned int i = start;
- for (; i < start + (has_reph ? 3 : 0); i++)
- info[i].myanmar_position() = POS_AFTER_MAIN;
- for (; i < base; i++)
- info[i].myanmar_position() = POS_PRE_C;
- if (i < end)
- {
- info[i].myanmar_position() = POS_BASE_C;
- i++;
- }
- myanmar_position_t pos = POS_AFTER_MAIN;
- /* The following loop may be ugly, but it implements all of
- * Myanmar reordering! */
- for (; i < end; i++)
- {
- if (info[i].myanmar_category() == M_Cat(MR)) /* Pre-base reordering */
- {
- info[i].myanmar_position() = POS_PRE_C;
- continue;
- }
- if (info[i].myanmar_category() == M_Cat(VPre)) /* Left matra */
- {
- info[i].myanmar_position() = POS_PRE_M;
- continue;
- }
- if (info[i].myanmar_category() == M_Cat(VS))
- {
- info[i].myanmar_position() = info[i - 1].myanmar_position();
- continue;
- }
-
- if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == M_Cat(VBlw))
- {
- pos = POS_BELOW_C;
- info[i].myanmar_position() = pos;
- continue;
- }
-
- if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(A))
- {
- info[i].myanmar_position() = POS_BEFORE_SUB;
- continue;
- }
- if (pos == POS_BELOW_C && info[i].myanmar_category() == M_Cat(VBlw))
- {
- info[i].myanmar_position() = pos;
- continue;
- }
- if (pos == POS_BELOW_C && info[i].myanmar_category() != M_Cat(A))
- {
- pos = POS_AFTER_SUB;
- info[i].myanmar_position() = pos;
- continue;
- }
- info[i].myanmar_position() = pos;
- }
- }
-
- /* Sit tight, rock 'n roll! */
- buffer->sort (start, end, compare_myanmar_order);
-
- /* Flip left-matra sequence. */
- unsigned first_left_matra = end;
- unsigned last_left_matra = end;
- for (unsigned int i = start; i < end; i++)
- {
- if (info[i].myanmar_position() == POS_PRE_M)
- {
- if (first_left_matra == end)
- first_left_matra = i;
- last_left_matra = i;
- }
- }
- /* https://github.com/harfbuzz/harfbuzz/issues/3863 */
- if (first_left_matra < last_left_matra)
- {
- /* No need to merge clusters, done already? */
- buffer->reverse_range (first_left_matra, last_left_matra + 1);
- /* Reverse back VS, etc. */
- unsigned i = first_left_matra;
- for (unsigned j = i; j <= last_left_matra; j++)
- if (info[j].myanmar_category() == M_Cat(VPre))
- {
- buffer->reverse_range (i, j + 1);
- i = j + 1;
- }
- }
-}
-
-static void
-reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
-{
- myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
- switch (syllable_type) {
-
- case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
- case myanmar_consonant_syllable:
- initial_reordering_consonant_syllable (buffer, start, end);
- break;
-
- case myanmar_non_myanmar_cluster:
- break;
- }
-}
-
-static bool
-reorder_myanmar (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- bool ret = false;
- if (buffer->message (font, "start reordering myanmar"))
- {
- if (hb_syllabic_insert_dotted_circles (font, buffer,
- myanmar_broken_cluster,
- M_Cat(DOTTEDCIRCLE)))
- ret = true;
-
- foreach_syllable (buffer, start, end)
- reorder_syllable_myanmar (plan, font->face, buffer, start, end);
- (void) buffer->message (font, "end reordering myanmar");
- }
-
- HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
- HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
-
- return ret;
-}
-
-
-const hb_ot_shaper_t _hb_ot_shaper_myanmar =
-{
- collect_features_myanmar,
- nullptr, /* override_features */
- nullptr, /* data_create */
- nullptr, /* data_destroy */
- nullptr, /* preprocess_text */
- nullptr, /* postprocess_glyphs */
- nullptr, /* decompose */
- nullptr, /* compose */
- setup_masks_myanmar,
- nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
- false, /* fallback_position */
-};
-
-
-#ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
-/* Ugly Zawgyi encoding.
- * Disable all auto processing.
- * https://github.com/harfbuzz/harfbuzz/issues/1162 */
-const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi =
-{
- nullptr, /* collect_features */
- nullptr, /* override_features */
- nullptr, /* data_create */
- nullptr, /* data_destroy */
- nullptr, /* preprocess_text */
- nullptr, /* postprocess_glyphs */
- nullptr, /* decompose */
- nullptr, /* compose */
- nullptr, /* setup_masks */
- nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
- false, /* fallback_position */
-};
-#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.cc
deleted file mode 100644
index 89226ae4a1f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright © 2021 Behdad Esfahbod.
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-syllabic.hh"
-
-
-bool
-hb_syllabic_insert_dotted_circles (hb_font_t *font,
- hb_buffer_t *buffer,
- unsigned int broken_syllable_type,
- unsigned int dottedcircle_category,
- int repha_category,
- int dottedcircle_position)
-{
- if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
- return false;
- if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
- return false;
-
- hb_codepoint_t dottedcircle_glyph;
- if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
- return false;
-
- hb_glyph_info_t dottedcircle = {0};
- dottedcircle.codepoint = 0x25CCu;
- dottedcircle.ot_shaper_var_u8_category() = dottedcircle_category;
- if (dottedcircle_position != -1)
- dottedcircle.ot_shaper_var_u8_auxiliary() = dottedcircle_position;
- dottedcircle.codepoint = dottedcircle_glyph;
-
- buffer->clear_output ();
-
- buffer->idx = 0;
- unsigned int last_syllable = 0;
- while (buffer->idx < buffer->len && buffer->successful)
- {
- unsigned int syllable = buffer->cur().syllable();
- if (unlikely (last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type))
- {
- last_syllable = syllable;
-
- hb_glyph_info_t ginfo = dottedcircle;
- ginfo.cluster = buffer->cur().cluster;
- ginfo.mask = buffer->cur().mask;
- ginfo.syllable() = buffer->cur().syllable();
-
- /* Insert dottedcircle after possible Repha. */
- if (repha_category != -1)
- {
- while (buffer->idx < buffer->len && buffer->successful &&
- last_syllable == buffer->cur().syllable() &&
- buffer->cur().ot_shaper_var_u8_category() == (unsigned) repha_category)
- (void) buffer->next_glyph ();
- }
-
- (void) buffer->output_info (ginfo);
- }
- else
- (void) buffer->next_glyph ();
- }
- buffer->sync ();
- return true;
-}
-
-HB_INTERNAL bool
-hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
- return false;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.hh
deleted file mode 100644
index f240ad1c265..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-syllabic.hh
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright © 2021 Behdad Esfahbod.
- *
- * 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.
- */
-
-#ifndef HB_OT_SHAPER_SYLLABIC_HH
-#define HB_OT_SHAPER_SYLLABIC_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shaper.hh"
-
-
-HB_INTERNAL bool
-hb_syllabic_insert_dotted_circles (hb_font_t *font,
- hb_buffer_t *buffer,
- unsigned int broken_syllable_type,
- unsigned int dottedcircle_category,
- int repha_category = -1,
- int dottedcircle_position = -1);
-
-HB_INTERNAL bool
-hb_syllabic_clear_var (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-#endif /* HB_OT_SHAPER_SYLLABIC_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh
deleted file mode 100644
index 7249c333566..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh
+++ /dev/null
@@ -1,1080 +0,0 @@
-
-#line 1 "hb-ot-shaper-use-machine.rl"
-/*
- * Copyright © 2015 Mozilla Foundation.
- * Copyright © 2015 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.
- *
- * Mozilla Author(s): Jonathan Kew
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPER_USE_MACHINE_HH
-#define HB_OT_SHAPER_USE_MACHINE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shaper-syllabic.hh"
-
-/* buffer var allocations */
-#define use_category() ot_shaper_var_u8_category()
-
-#define USE(Cat) use_syllable_machine_ex_##Cat
-
-enum use_syllable_type_t {
- use_virama_terminated_cluster,
- use_sakot_terminated_cluster,
- use_standard_cluster,
- use_number_joiner_terminated_cluster,
- use_numeral_cluster,
- use_symbol_cluster,
- use_hieroglyph_cluster,
- use_broken_cluster,
- use_non_cluster,
-};
-
-
-#line 54 "hb-ot-shaper-use-machine.hh"
-#define use_syllable_machine_ex_B 1u
-#define use_syllable_machine_ex_CGJ 6u
-#define use_syllable_machine_ex_CMAbv 31u
-#define use_syllable_machine_ex_CMBlw 32u
-#define use_syllable_machine_ex_CS 43u
-#define use_syllable_machine_ex_FAbv 24u
-#define use_syllable_machine_ex_FBlw 25u
-#define use_syllable_machine_ex_FMAbv 45u
-#define use_syllable_machine_ex_FMBlw 46u
-#define use_syllable_machine_ex_FMPst 47u
-#define use_syllable_machine_ex_FPst 26u
-#define use_syllable_machine_ex_G 49u
-#define use_syllable_machine_ex_GB 5u
-#define use_syllable_machine_ex_H 12u
-#define use_syllable_machine_ex_HN 13u
-#define use_syllable_machine_ex_HVM 53u
-#define use_syllable_machine_ex_IS 44u
-#define use_syllable_machine_ex_J 50u
-#define use_syllable_machine_ex_MAbv 27u
-#define use_syllable_machine_ex_MBlw 28u
-#define use_syllable_machine_ex_MPre 30u
-#define use_syllable_machine_ex_MPst 29u
-#define use_syllable_machine_ex_N 4u
-#define use_syllable_machine_ex_O 0u
-#define use_syllable_machine_ex_R 18u
-#define use_syllable_machine_ex_SB 51u
-#define use_syllable_machine_ex_SE 52u
-#define use_syllable_machine_ex_SMAbv 41u
-#define use_syllable_machine_ex_SMBlw 42u
-#define use_syllable_machine_ex_SUB 11u
-#define use_syllable_machine_ex_Sk 48u
-#define use_syllable_machine_ex_VAbv 33u
-#define use_syllable_machine_ex_VBlw 34u
-#define use_syllable_machine_ex_VMAbv 37u
-#define use_syllable_machine_ex_VMBlw 38u
-#define use_syllable_machine_ex_VMPre 23u
-#define use_syllable_machine_ex_VMPst 39u
-#define use_syllable_machine_ex_VPre 22u
-#define use_syllable_machine_ex_VPst 35u
-#define use_syllable_machine_ex_WJ 16u
-#define use_syllable_machine_ex_ZWNJ 14u
-
-
-#line 96 "hb-ot-shaper-use-machine.hh"
-static const unsigned char _use_syllable_machine_trans_keys[] = {
- 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
- 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
- 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
- 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 11u, 53u, 14u, 42u, 14u, 42u, 11u, 53u,
- 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u,
- 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u,
- 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u,
- 1u, 14u, 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u,
- 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u,
- 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u,
- 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u,
- 1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
- 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
- 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
- 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 11u, 53u,
- 14u, 42u, 14u, 42u, 1u, 5u, 14u, 52u, 14u, 52u, 14u, 51u, 0
-};
-
-static const char _use_syllable_machine_key_spans[] = {
- 54, 43, 43, 53, 35, 34, 34, 34,
- 33, 33, 1, 35, 35, 35, 14, 35,
- 40, 40, 40, 40, 42, 40, 42, 42,
- 42, 43, 14, 48, 43, 29, 29, 43,
- 43, 53, 35, 34, 34, 34, 33, 33,
- 1, 35, 35, 35, 14, 35, 40, 40,
- 40, 40, 42, 40, 42, 42, 42, 43,
- 14, 14, 48, 2, 11, 43, 43, 53,
- 35, 34, 34, 34, 33, 33, 1, 35,
- 35, 35, 14, 35, 40, 40, 40, 40,
- 42, 40, 42, 42, 42, 43, 14, 14,
- 48, 43, 43, 53, 35, 34, 34, 34,
- 33, 33, 1, 35, 35, 35, 14, 35,
- 40, 40, 40, 40, 42, 40, 42, 42,
- 42, 43, 14, 48, 11, 2, 53, 43,
- 29, 29, 5, 39, 39, 38
-};
-
-static const short _use_syllable_machine_index_offsets[] = {
- 0, 55, 99, 143, 197, 233, 268, 303,
- 338, 372, 406, 408, 444, 480, 516, 531,
- 567, 608, 649, 690, 731, 774, 815, 858,
- 901, 944, 988, 1003, 1052, 1096, 1126, 1156,
- 1200, 1244, 1298, 1334, 1369, 1404, 1439, 1473,
- 1507, 1509, 1545, 1581, 1617, 1632, 1668, 1709,
- 1750, 1791, 1832, 1875, 1916, 1959, 2002, 2045,
- 2089, 2104, 2119, 2168, 2171, 2183, 2227, 2271,
- 2325, 2361, 2396, 2431, 2466, 2500, 2534, 2536,
- 2572, 2608, 2644, 2659, 2695, 2736, 2777, 2818,
- 2859, 2902, 2943, 2986, 3029, 3072, 3116, 3131,
- 3146, 3195, 3239, 3283, 3337, 3373, 3408, 3443,
- 3478, 3512, 3546, 3548, 3584, 3620, 3656, 3671,
- 3707, 3748, 3789, 3830, 3871, 3914, 3955, 3998,
- 4041, 4084, 4128, 4143, 4192, 4204, 4207, 4261,
- 4305, 4335, 4365, 4371, 4411, 4451
-};
-
-static const unsigned char _use_syllable_machine_indicies[] = {
- 0, 1, 2, 2, 3, 4, 2, 2,
- 2, 2, 2, 5, 6, 7, 8, 2,
- 2, 2, 9, 2, 2, 2, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 2, 24, 25, 26,
- 2, 27, 28, 29, 30, 31, 32, 33,
- 30, 34, 2, 35, 2, 36, 2, 38,
- 39, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54,
- 37, 55, 56, 57, 37, 58, 59, 37,
- 60, 61, 62, 63, 60, 37, 37, 37,
- 37, 64, 37, 38, 39, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 51,
- 51, 52, 53, 54, 37, 55, 56, 57,
- 37, 37, 37, 37, 60, 61, 62, 63,
- 60, 37, 37, 37, 37, 64, 37, 38,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 42, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 55, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 37, 37, 37, 42, 37, 40, 37, 37,
- 37, 37, 37, 37, 37, 37, 42, 43,
- 44, 45, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 55, 56, 57, 37,
- 37, 37, 37, 37, 61, 62, 63, 65,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 43, 44, 45, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 61, 62, 63, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 61, 62, 63, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 45, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 61, 62,
- 63, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 61, 62, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 62, 37, 40, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 66, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 40, 37, 40, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 43, 44, 45,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 61, 62, 63, 65, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 37, 37, 37, 37,
- 37, 37, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 37, 61, 62,
- 63, 65, 37, 37, 37, 37, 42, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 42, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 52, 53, 54, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 37, 37, 37, 42,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 37, 42, 43, 44, 45, 37, 37,
- 37, 37, 37, 37, 37, 53, 54, 37,
- 55, 56, 57, 37, 37, 37, 37, 37,
- 61, 62, 63, 65, 37, 37, 37, 37,
- 42, 37, 40, 37, 37, 37, 37, 37,
- 37, 37, 37, 42, 43, 44, 45, 37,
- 37, 37, 37, 37, 37, 37, 37, 54,
- 37, 55, 56, 57, 37, 37, 37, 37,
- 37, 61, 62, 63, 65, 37, 37, 37,
- 37, 42, 37, 67, 37, 40, 37, 37,
- 37, 37, 37, 37, 37, 41, 42, 43,
- 44, 45, 37, 47, 48, 37, 37, 37,
- 52, 53, 54, 37, 55, 56, 57, 37,
- 37, 37, 37, 37, 61, 62, 63, 65,
- 37, 37, 37, 37, 42, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 37, 42,
- 43, 44, 45, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 55, 56, 57,
- 37, 37, 37, 37, 37, 61, 62, 63,
- 65, 37, 37, 37, 37, 42, 37, 67,
- 37, 40, 37, 37, 37, 37, 37, 37,
- 37, 41, 42, 43, 44, 45, 37, 37,
- 48, 37, 37, 37, 52, 53, 54, 37,
- 55, 56, 57, 37, 37, 37, 37, 37,
- 61, 62, 63, 65, 37, 37, 37, 37,
- 42, 37, 67, 37, 40, 37, 37, 37,
- 37, 37, 37, 37, 41, 42, 43, 44,
- 45, 37, 37, 37, 37, 37, 37, 52,
- 53, 54, 37, 55, 56, 57, 37, 37,
- 37, 37, 37, 61, 62, 63, 65, 37,
- 37, 37, 37, 42, 37, 67, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 46, 47, 48, 37,
- 37, 37, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 37, 61, 62,
- 63, 65, 37, 37, 37, 37, 42, 37,
- 38, 39, 37, 40, 37, 37, 37, 37,
- 37, 37, 37, 41, 42, 43, 44, 45,
- 46, 47, 48, 49, 37, 51, 52, 53,
- 54, 37, 55, 56, 57, 37, 37, 37,
- 37, 60, 61, 62, 63, 60, 37, 37,
- 37, 37, 64, 37, 38, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 40, 37, 38, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 42, 43, 44, 45, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 55,
- 56, 57, 37, 37, 37, 37, 37, 61,
- 62, 63, 65, 37, 38, 39, 37, 40,
- 37, 37, 37, 37, 37, 37, 37, 41,
- 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 37, 55, 56,
- 57, 37, 37, 37, 37, 60, 61, 62,
- 63, 60, 37, 37, 37, 37, 64, 37,
- 40, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 58, 59, 37, 40, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 59, 37, 69, 70, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 1, 81, 82, 83, 84, 68, 85, 86,
- 87, 68, 68, 68, 68, 88, 89, 90,
- 91, 92, 68, 68, 68, 68, 93, 68,
- 69, 70, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 81, 82, 83,
- 84, 68, 85, 86, 87, 68, 68, 68,
- 68, 88, 89, 90, 91, 92, 68, 68,
- 68, 68, 93, 68, 69, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 73, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 85, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 68, 68, 68,
- 73, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 73, 74, 75, 76, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 85, 86, 87, 68, 68, 68, 68,
- 68, 89, 90, 91, 94, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 74, 75, 76, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 89, 90, 91, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 76, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 89, 90, 91, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 89, 90,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 90, 68, 71, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 85, 86, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 96, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 97, 95,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 74, 75, 76, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 89,
- 90, 91, 94, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 72, 73, 74, 75,
- 76, 68, 68, 68, 68, 68, 68, 82,
- 83, 84, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 68, 68, 68, 73, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 73, 74,
- 75, 76, 68, 68, 68, 68, 68, 68,
- 82, 83, 84, 68, 85, 86, 87, 68,
- 68, 68, 68, 68, 89, 90, 91, 94,
- 68, 68, 68, 68, 73, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 73,
- 74, 75, 76, 68, 68, 68, 68, 68,
- 68, 68, 83, 84, 68, 85, 86, 87,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 94, 68, 68, 68, 68, 73, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 73, 74, 75, 76, 68, 68, 68, 68,
- 68, 68, 68, 68, 84, 68, 85, 86,
- 87, 68, 68, 68, 68, 68, 89, 90,
- 91, 94, 68, 68, 68, 68, 73, 68,
- 98, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 72, 73, 74, 75, 76, 68,
- 78, 79, 68, 68, 68, 82, 83, 84,
- 68, 85, 86, 87, 68, 68, 68, 68,
- 68, 89, 90, 91, 94, 68, 68, 68,
- 68, 73, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 68, 73, 74, 75, 76,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 85, 86, 87, 68, 68, 68,
- 68, 68, 89, 90, 91, 94, 68, 68,
- 68, 68, 73, 68, 98, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 72, 73,
- 74, 75, 76, 68, 68, 79, 68, 68,
- 68, 82, 83, 84, 68, 85, 86, 87,
- 68, 68, 68, 68, 68, 89, 90, 91,
- 94, 68, 68, 68, 68, 73, 68, 98,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 72, 73, 74, 75, 76, 68, 68,
- 68, 68, 68, 68, 82, 83, 84, 68,
- 85, 86, 87, 68, 68, 68, 68, 68,
- 89, 90, 91, 94, 68, 68, 68, 68,
- 73, 68, 98, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 72, 73, 74, 75,
- 76, 77, 78, 79, 68, 68, 68, 82,
- 83, 84, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 68, 68, 68, 73, 68, 69, 70, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 68, 81, 82, 83, 84, 68, 85,
- 86, 87, 68, 68, 68, 68, 88, 89,
- 90, 91, 92, 68, 68, 68, 68, 93,
- 68, 69, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 100, 99,
- 69, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 97, 95, 69,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 73, 74, 75,
- 76, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 85, 86, 87, 68, 68,
- 68, 68, 68, 89, 90, 91, 94, 68,
- 102, 103, 101, 3, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 105, 104, 106,
- 107, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 108, 109, 110, 111, 112, 113,
- 114, 115, 116, 117, 118, 119, 120, 121,
- 68, 122, 123, 124, 68, 58, 59, 68,
- 125, 126, 127, 128, 129, 68, 68, 68,
- 68, 130, 68, 106, 107, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 118,
- 118, 119, 120, 121, 68, 122, 123, 124,
- 68, 68, 68, 68, 125, 126, 127, 128,
- 129, 68, 68, 68, 68, 130, 68, 106,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 109, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 122, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 68, 68, 68, 109, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 68, 109, 110,
- 111, 112, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 122, 123, 124, 68,
- 68, 68, 68, 68, 126, 127, 128, 131,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 110, 111, 112, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 126, 127, 128, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 126, 127, 128, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 112, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 126, 127,
- 128, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 126, 127, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 127, 68, 71, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 122,
- 123, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 132, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 97, 95, 71, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 110, 111, 112,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 126, 127, 128, 131, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 108,
- 109, 110, 111, 112, 68, 68, 68, 68,
- 68, 68, 119, 120, 121, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 68, 68, 68, 109, 68,
- 71, 68, 68, 68, 68, 68, 68, 68,
- 68, 109, 110, 111, 112, 68, 68, 68,
- 68, 68, 68, 119, 120, 121, 68, 122,
- 123, 124, 68, 68, 68, 68, 68, 126,
- 127, 128, 131, 68, 68, 68, 68, 109,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 68, 109, 110, 111, 112, 68, 68,
- 68, 68, 68, 68, 68, 120, 121, 68,
- 122, 123, 124, 68, 68, 68, 68, 68,
- 126, 127, 128, 131, 68, 68, 68, 68,
- 109, 68, 71, 68, 68, 68, 68, 68,
- 68, 68, 68, 109, 110, 111, 112, 68,
- 68, 68, 68, 68, 68, 68, 68, 121,
- 68, 122, 123, 124, 68, 68, 68, 68,
- 68, 126, 127, 128, 131, 68, 68, 68,
- 68, 109, 68, 133, 68, 71, 68, 68,
- 68, 68, 68, 68, 68, 108, 109, 110,
- 111, 112, 68, 114, 115, 68, 68, 68,
- 119, 120, 121, 68, 122, 123, 124, 68,
- 68, 68, 68, 68, 126, 127, 128, 131,
- 68, 68, 68, 68, 109, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 68, 109,
- 110, 111, 112, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 122, 123, 124,
- 68, 68, 68, 68, 68, 126, 127, 128,
- 131, 68, 68, 68, 68, 109, 68, 133,
- 68, 71, 68, 68, 68, 68, 68, 68,
- 68, 108, 109, 110, 111, 112, 68, 68,
- 115, 68, 68, 68, 119, 120, 121, 68,
- 122, 123, 124, 68, 68, 68, 68, 68,
- 126, 127, 128, 131, 68, 68, 68, 68,
- 109, 68, 133, 68, 71, 68, 68, 68,
- 68, 68, 68, 68, 108, 109, 110, 111,
- 112, 68, 68, 68, 68, 68, 68, 119,
- 120, 121, 68, 122, 123, 124, 68, 68,
- 68, 68, 68, 126, 127, 128, 131, 68,
- 68, 68, 68, 109, 68, 133, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 108,
- 109, 110, 111, 112, 113, 114, 115, 68,
- 68, 68, 119, 120, 121, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 68, 68, 68, 109, 68,
- 106, 107, 68, 71, 68, 68, 68, 68,
- 68, 68, 68, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 68, 118, 119, 120,
- 121, 68, 122, 123, 124, 68, 68, 68,
- 68, 125, 126, 127, 128, 129, 68, 68,
- 68, 68, 130, 68, 106, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 100, 99, 106, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 97, 95, 106, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 68, 71,
- 68, 68, 68, 68, 68, 68, 68, 68,
- 109, 110, 111, 112, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 68, 122, 123,
- 124, 68, 68, 68, 68, 68, 126, 127,
- 128, 131, 68, 106, 107, 68, 71, 68,
- 68, 68, 68, 68, 68, 68, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117,
- 118, 119, 120, 121, 68, 122, 123, 124,
- 68, 68, 68, 68, 125, 126, 127, 128,
- 129, 68, 68, 68, 68, 130, 68, 5,
- 6, 134, 8, 134, 134, 134, 134, 134,
- 134, 134, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 20, 20, 21, 22, 23,
- 134, 24, 25, 26, 134, 134, 134, 134,
- 30, 31, 32, 33, 30, 134, 134, 134,
- 134, 36, 134, 5, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 11, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 24,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 134, 134, 134, 11,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 134, 11, 12, 13, 14, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 24, 25, 26, 134, 134, 134, 134, 134,
- 31, 32, 33, 135, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 12,
- 13, 14, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 31, 32, 33, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 31,
- 32, 33, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 14,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 31, 32, 33, 134, 8, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 31, 32, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 32, 134, 8, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 136, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 8, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 12, 13, 14, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 31, 32,
- 33, 135, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 10, 11, 12, 13, 14,
- 134, 134, 134, 134, 134, 134, 21, 22,
- 23, 134, 24, 25, 26, 134, 134, 134,
- 134, 134, 31, 32, 33, 135, 134, 134,
- 134, 134, 11, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 11, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 21,
- 22, 23, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 134, 134, 134, 11, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 134, 11, 12,
- 13, 14, 134, 134, 134, 134, 134, 134,
- 134, 22, 23, 134, 24, 25, 26, 134,
- 134, 134, 134, 134, 31, 32, 33, 135,
- 134, 134, 134, 134, 11, 134, 8, 134,
- 134, 134, 134, 134, 134, 134, 134, 11,
- 12, 13, 14, 134, 134, 134, 134, 134,
- 134, 134, 134, 23, 134, 24, 25, 26,
- 134, 134, 134, 134, 134, 31, 32, 33,
- 135, 134, 134, 134, 134, 11, 134, 137,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 10, 11, 12, 13, 14, 134, 16,
- 17, 134, 134, 134, 21, 22, 23, 134,
- 24, 25, 26, 134, 134, 134, 134, 134,
- 31, 32, 33, 135, 134, 134, 134, 134,
- 11, 134, 8, 134, 134, 134, 134, 134,
- 134, 134, 134, 11, 12, 13, 14, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 24, 25, 26, 134, 134, 134, 134,
- 134, 31, 32, 33, 135, 134, 134, 134,
- 134, 11, 134, 137, 134, 8, 134, 134,
- 134, 134, 134, 134, 134, 10, 11, 12,
- 13, 14, 134, 134, 17, 134, 134, 134,
- 21, 22, 23, 134, 24, 25, 26, 134,
- 134, 134, 134, 134, 31, 32, 33, 135,
- 134, 134, 134, 134, 11, 134, 137, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 10, 11, 12, 13, 14, 134, 134, 134,
- 134, 134, 134, 21, 22, 23, 134, 24,
- 25, 26, 134, 134, 134, 134, 134, 31,
- 32, 33, 135, 134, 134, 134, 134, 11,
- 134, 137, 134, 8, 134, 134, 134, 134,
- 134, 134, 134, 10, 11, 12, 13, 14,
- 15, 16, 17, 134, 134, 134, 21, 22,
- 23, 134, 24, 25, 26, 134, 134, 134,
- 134, 134, 31, 32, 33, 135, 134, 134,
- 134, 134, 11, 134, 5, 6, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 10,
- 11, 12, 13, 14, 15, 16, 17, 18,
- 134, 20, 21, 22, 23, 134, 24, 25,
- 26, 134, 134, 134, 134, 30, 31, 32,
- 33, 30, 134, 134, 134, 134, 36, 134,
- 5, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 8, 134, 5,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 8, 134, 134, 134,
- 134, 134, 134, 134, 134, 11, 12, 13,
- 14, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 24, 25, 26, 134, 134,
- 134, 134, 134, 31, 32, 33, 135, 134,
- 138, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 8, 134, 7, 8, 134, 1,
- 134, 134, 134, 1, 134, 134, 134, 134,
- 134, 5, 6, 7, 8, 134, 134, 134,
- 134, 134, 134, 134, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 134, 24, 25, 26, 134, 27,
- 28, 134, 30, 31, 32, 33, 30, 134,
- 134, 134, 134, 36, 134, 5, 6, 134,
- 8, 134, 134, 134, 134, 134, 134, 134,
- 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 134, 24,
- 25, 26, 134, 134, 134, 134, 30, 31,
- 32, 33, 30, 134, 134, 134, 134, 36,
- 134, 8, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 27, 28, 134, 8,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 28, 134, 1, 139, 139,
- 139, 1, 139, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 142,
- 140, 34, 140, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 34, 142,
- 140, 142, 140, 141, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 140, 140, 34, 140,
- 35, 140, 0
-};
-
-static const char _use_syllable_machine_trans_targs[] = {
- 1, 31, 0, 59, 61, 90, 91, 116,
- 0, 118, 104, 92, 93, 94, 95, 108,
- 110, 111, 112, 119, 113, 105, 106, 107,
- 99, 100, 101, 120, 121, 122, 114, 96,
- 97, 98, 123, 125, 115, 0, 2, 3,
- 0, 16, 4, 5, 6, 7, 20, 22,
- 23, 24, 28, 25, 17, 18, 19, 11,
- 12, 13, 29, 30, 26, 8, 9, 10,
- 27, 14, 15, 21, 0, 32, 33, 0,
- 46, 34, 35, 36, 37, 50, 52, 53,
- 54, 55, 47, 48, 49, 41, 42, 43,
- 56, 38, 39, 40, 57, 58, 44, 0,
- 45, 0, 51, 0, 0, 0, 60, 0,
- 0, 0, 62, 63, 76, 64, 65, 66,
- 67, 80, 82, 83, 84, 89, 85, 77,
- 78, 79, 71, 72, 73, 86, 68, 69,
- 70, 87, 88, 74, 75, 81, 0, 102,
- 103, 109, 117, 0, 0, 0, 124
-};
-
-static const char _use_syllable_machine_trans_actions[] = {
- 0, 0, 3, 0, 0, 0, 0, 0,
- 4, 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, 5, 0, 0,
- 6, 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, 7, 0, 0, 8,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 9,
- 0, 10, 0, 11, 12, 13, 0, 14,
- 15, 16, 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, 17, 0,
- 0, 0, 0, 18, 19, 20, 0
-};
-
-static const char _use_syllable_machine_to_state_actions[] = {
- 1, 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, 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, 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, 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[] = {
- 2, 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, 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, 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, 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[] = {
- 0, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 38, 38, 38, 38, 38, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 96, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 100, 96, 69, 102, 105, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 96, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 69, 69, 100, 96,
- 69, 69, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 140, 141, 141, 141
-};
-
-static const int use_syllable_machine_start = 0;
-static const int use_syllable_machine_first_final = 0;
-static const int use_syllable_machine_error = -1;
-
-static const int use_syllable_machine_en_main = 0;
-
-
-#line 58 "hb-ot-shaper-use-machine.rl"
-
-
-
-#line 182 "hb-ot-shaper-use-machine.rl"
-
-
-#define found_syllable(syllable_type) \
- HB_STMT_START { \
- if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
- for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
- info[i].syllable() = (syllable_serial << 4) | syllable_type; \
- syllable_serial++; \
- if (syllable_serial == 16) syllable_serial = 1; \
- } HB_STMT_END
-
-
-template <typename Iter>
-struct machine_index_t :
- hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t>
-{
- machine_index_t (const Iter& it) : it (it) {}
- machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>,
- typename Iter::item_t> (),
- it (o.it), is_null (o.is_null) {}
-
- static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
- static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
-
- typename Iter::item_t __item__ () const { return *it; }
- typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
- unsigned __len__ () const { return it.len (); }
- void __next__ () { ++it; }
- void __forward__ (unsigned n) { it += n; }
- void __prev__ () { --it; }
- void __rewind__ (unsigned n) { it -= n; }
-
- void operator = (unsigned n)
- {
- assert (n == 0);
- is_null = true;
- }
- explicit operator bool () { return !is_null; }
-
- void operator = (const machine_index_t& o)
- {
- is_null = o.is_null;
- unsigned index = (*it).first;
- unsigned n = (*o.it).first;
- if (index < n) it += n - index; else if (index > n) it -= index - n;
- }
- bool operator == (const machine_index_t& o) const
- { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; }
- bool operator != (const machine_index_t& o) const { return !(*this == o); }
-
- private:
- Iter it;
- bool is_null = false;
-};
-struct
-{
- template <typename Iter,
- hb_requires (hb_is_iterable (Iter))>
- machine_index_t<hb_iter_type<Iter>>
- operator () (Iter&& it) const
- { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
-}
-HB_FUNCOBJ (machine_index);
-
-
-
-static bool
-not_ccs_default_ignorable (const hb_glyph_info_t &i)
-{ return i.use_category() != USE(CGJ); }
-
-static inline void
-find_syllables_use (hb_buffer_t *buffer)
-{
- hb_glyph_info_t *info = buffer->info;
- auto p =
- + hb_iter (info, buffer->len)
- | hb_enumerate
- | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
- hb_second)
- | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
- {
- if (p.second.use_category() == USE(ZWNJ))
- for (unsigned i = p.first + 1; i < buffer->len; ++i)
- if (not_ccs_default_ignorable (info[i]))
- return !_hb_glyph_info_is_unicode_mark (&info[i]);
- return true;
- })
- | hb_enumerate
- | machine_index
- ;
- auto pe = p + p.len ();
- auto eof = +pe;
- auto ts = +p;
- auto te = +p;
- unsigned int act HB_UNUSED;
- int cs;
-
-#line 922 "hb-ot-shaper-use-machine.hh"
- {
- cs = use_syllable_machine_start;
- ts = 0;
- te = 0;
- act = 0;
- }
-
-#line 282 "hb-ot-shaper-use-machine.rl"
-
-
- unsigned int syllable_serial = 1;
-
-#line 931 "hb-ot-shaper-use-machine.hh"
- {
- int _slen;
- int _trans;
- const unsigned char *_keys;
- const unsigned char *_inds;
- if ( p == pe )
- goto _test_eof;
-_resume:
- switch ( _use_syllable_machine_from_state_actions[cs] ) {
- case 2:
-#line 1 "NONE"
- {ts = p;}
- break;
-#line 943 "hb-ot-shaper-use-machine.hh"
- }
-
- _keys = _use_syllable_machine_trans_keys + (cs<<1);
- _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
-
- _slen = _use_syllable_machine_key_spans[cs];
- _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) &&
- ( (*p).second.second.use_category()) <= _keys[1] ?
- ( (*p).second.second.use_category()) - _keys[0] : _slen ];
-
-_eof_trans:
- cs = _use_syllable_machine_trans_targs[_trans];
-
- if ( _use_syllable_machine_trans_actions[_trans] == 0 )
- goto _again;
-
- switch ( _use_syllable_machine_trans_actions[_trans] ) {
- case 12:
-#line 170 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
- break;
- case 10:
-#line 171 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
- break;
- case 8:
-#line 172 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_standard_cluster); }}
- break;
- case 16:
-#line 173 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
- break;
- case 14:
-#line 174 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_numeral_cluster); }}
- break;
- case 6:
-#line 175 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_symbol_cluster); }}
- break;
- case 20:
-#line 176 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
- break;
- case 4:
-#line 177 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 3:
-#line 178 "hb-ot-shaper-use-machine.rl"
- {te = p+1;{ found_syllable (use_non_cluster); }}
- break;
- case 11:
-#line 170 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
- break;
- case 9:
-#line 171 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
- break;
- case 7:
-#line 172 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_standard_cluster); }}
- break;
- case 15:
-#line 173 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
- break;
- case 13:
-#line 174 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_numeral_cluster); }}
- break;
- case 5:
-#line 175 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_symbol_cluster); }}
- break;
- case 19:
-#line 176 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
- break;
- case 17:
-#line 177 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
- break;
- case 18:
-#line 178 "hb-ot-shaper-use-machine.rl"
- {te = p;p--;{ found_syllable (use_non_cluster); }}
- break;
-#line 1014 "hb-ot-shaper-use-machine.hh"
- }
-
-_again:
- switch ( _use_syllable_machine_to_state_actions[cs] ) {
- case 1:
-#line 1 "NONE"
- {ts = 0;}
- break;
-#line 1021 "hb-ot-shaper-use-machine.hh"
- }
-
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- if ( p == eof )
- {
- if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
- _trans = _use_syllable_machine_eof_trans[cs] - 1;
- goto _eof_trans;
- }
- }
-
- }
-
-#line 287 "hb-ot-shaper-use-machine.rl"
-
-}
-
-#undef found_syllable
-
-#endif /* HB_OT_SHAPER_USE_MACHINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh
deleted file mode 100644
index 6b6b552ee58..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-table.hh
+++ /dev/null
@@ -1,674 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
- *
- * on files with these headers:
- *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # DerivedCoreProperties-15.0.0.txt
- * # Date: 2022-08-05, 22:17:05 GMT
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
- * # Override values For Indic_Syllabic_Category
- * # Not derivable
- * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
- * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
- * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
- * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
- * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
- * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
- * # Override values For Indic_Positional_Category
- * # Not derivable
- * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
- * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
- * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
- * # Updated for L2/19-083 by Andrew Glass 2019-05-06
- * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
- * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
- * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
- * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
- * UnicodeData.txt does not have a header.
- */
-
-#ifndef HB_OT_SHAPER_USE_TABLE_HH
-#define HB_OT_SHAPER_USE_TABLE_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shaper-use-machine.hh"
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-macros"
-#define B USE(B) /* BASE */
-#define CGJ USE(CGJ) /* CGJ */
-#define CS USE(CS) /* CONS_WITH_STACKER */
-#define G USE(G) /* HIEROGLYPH */
-#define GB USE(GB) /* BASE_OTHER */
-#define H USE(H) /* HALANT */
-#define HN USE(HN) /* HALANT_NUM */
-#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */
-#define IS USE(IS) /* INVISIBLE_STACKER */
-#define J USE(J) /* HIEROGLYPH_JOINER */
-#define N USE(N) /* BASE_NUM */
-#define O USE(O) /* OTHER */
-#define R USE(R) /* REPHA */
-#define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */
-#define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */
-#define SUB USE(SUB) /* CONS_SUB */
-#define Sk USE(Sk) /* SAKOT */
-#define WJ USE(WJ) /* Word_Joiner */
-#define ZWNJ USE(ZWNJ) /* ZWNJ */
-#define CMAbv USE(CMAbv)
-#define CMBlw USE(CMBlw)
-#define FAbv USE(FAbv)
-#define FBlw USE(FBlw)
-#define FPst USE(FPst)
-#define FMAbv USE(FMAbv)
-#define FMBlw USE(FMBlw)
-#define FMPst USE(FMPst)
-#define MAbv USE(MAbv)
-#define MBlw USE(MBlw)
-#define MPst USE(MPst)
-#define MPre USE(MPre)
-#define SMAbv USE(SMAbv)
-#define SMBlw USE(SMBlw)
-#define VAbv USE(VAbv)
-#define VBlw USE(VBlw)
-#define VPst USE(VPst)
-#define VPre USE(VPre)
-#define VMAbv USE(VMAbv)
-#define VMBlw USE(VMBlw)
-#define VMPst USE(VMPst)
-#define VMPre USE(VMPre)
-#pragma GCC diagnostic pop
-
-
-#ifndef HB_OPTIMIZE_SIZE
-
-static const uint8_t
-hb_use_u8[3141] =
-{
- 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 14, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2,
- 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17,
- 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2,
- 2, 34, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 38, 39, 40, 41, 42, 43, 2, 44, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 46, 2,
- 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 49, 2, 2, 2,
- 2, 2, 2, 2, 2, 50, 51, 2, 52, 2, 2, 53, 2, 2, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 2, 64, 65, 2, 66, 67, 68, 69,
- 2, 70, 2, 71, 72, 73, 74, 2, 2, 75, 76, 77, 78, 2, 79, 80,
- 2, 81, 81, 81, 81, 81, 81, 81, 81, 82, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 83, 84, 2, 2, 2, 2, 2, 2, 2, 85,
- 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 81, 81, 81, 87, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 89, 2, 2, 2, 2, 2,
- 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 91, 2, 2, 92, 2, 2, 2, 93, 2, 2, 2, 2, 2,
- 2, 2, 2, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 95, 95, 96, 97, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4,
- 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10,
- 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22,
- 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2,
- 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7,
- 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2,
- 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32,
- 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7,
- 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35,
- 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7,
- 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0,
- 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2,
- 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22,
- 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7,
- 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2,
- 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0,
- 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0,
- 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7,
- 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15,
- 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0,
- 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15,
- 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0,
- 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51,
- 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0,
- 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2,
- 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0,
- 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0,
- 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
- 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18,
- 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61,
- 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43,
- 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0,
- 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27,
- 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76,
- 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0,
- 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0,
- 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82,
- 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79,
- 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2,
- 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0,
- 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2,
- 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0,
- 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0,
- 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59,
- 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44,
- 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20,
- 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108,
- 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2,
- 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43,
- 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111,
- 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28,
- 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38,
- 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0,
- 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118,
- 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0,
- 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
- 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
- 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29,
- 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0,
- 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0,
- 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18,
- 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2,
- 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0,
- 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57,
- 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136,
- 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2,
- 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19,
- 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141,
- 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0,
- 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2,
- 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7,
- 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2,
- 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2,
- 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2,
- 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36,
- 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0,
- 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2,
- 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0,
- 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2,
- 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2,
- 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0,
- 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151,
- 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0,
- 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20,
- 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0,
- 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2,
- 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2,
- 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7,
- 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44,
- 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18,
- 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
- 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23,
- 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
- 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80,
- 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164,
- 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41,
- 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0,
- 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2,
- 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0,
- 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21,
- 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2,
- 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0,
- 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173,
- 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9,
- 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0,
- 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20,
- 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2,
- 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0,
- 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2,
- 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0,
- 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114,
- 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0,
- 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
- 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56,
- 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2,
- 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
- 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20,
- 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB,
- O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,
- CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
- VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,
- VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw,
- O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst,
- VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv,
- B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB,
- SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv,
- MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,
- VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
- VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB,
- B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw,
- SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,
- SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
- CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H,
- VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H,
- O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,
- VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst,
- CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R,
- R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst,
- H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R,
- MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B,
- H, B,VMBlw, O, VBlw,
-};
-static const uint16_t
-hb_use_u16[784] =
-{
- 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
- 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11,
- 0, 0, 0, 0, 9, 12, 0, 0, 13, 9, 9, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 17, 25, 26, 20, 21, 27, 28, 29, 30, 31,
- 32, 33, 21, 34, 35, 0, 17, 36, 37, 20, 21, 38, 23, 39, 17, 40,
- 41, 42, 43, 44, 45, 46, 30, 0, 47, 48, 21, 49, 50, 51, 17, 0,
- 52, 48, 21, 53, 50, 54, 17, 55, 56, 48, 9, 57, 58, 59, 17, 0,
- 60, 61, 9, 62, 63, 64, 30, 65, 66, 67, 9, 68, 69, 9, 70, 71,
- 72, 73, 74, 75, 76, 0, 0, 0, 9, 9, 77, 78, 79, 80, 81, 82,
- 83, 84, 0, 0, 0, 0, 0, 0, 9, 85, 9, 86, 9, 87, 88, 89,
- 9, 9, 9, 90, 91, 92, 2, 0, 93, 0, 9, 9, 9, 9, 9, 94,
- 95, 9, 96, 0, 0, 0, 0, 0, 97, 98, 99,100, 30, 9,101,102,
- 9, 9,103, 9,104,105, 0, 0, 9,106, 9, 9, 9,107,108,109,
- 2, 2, 0, 0, 0, 0, 0, 0,110, 9, 9,111,112, 2,113,114,
- 115, 9,116, 9, 9, 9,117,118, 9, 9,119,120,121, 0, 0, 0,
- 0, 0, 0, 0, 0,122,123,124, 0, 0, 0, 0, 0, 0, 0,125,
- 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132,
- 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 9, 9, 9,134,135,
- 136, 9,137, 0, 9, 9, 9,138,139, 9, 9,140,141, 2,142,143,
- 9, 9,144, 9,145,146, 0, 0,147, 9, 9,148,149, 2,150, 98,
- 9, 9,151,152,153, 2, 9,154, 9, 9, 9,155,156, 0,157,158,
- 0, 0, 0, 0, 9, 9,159, 2,160, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0,162,
- 0, 0, 0, 0, 0, 0, 0,163,163,164, 33,165, 0, 0, 0, 0,
- 166,167, 9,168, 94, 0, 0, 0, 0, 0, 0, 0, 69, 9,169, 0,
- 9,170,171, 0, 0, 0, 0, 0, 9, 9,172, 2, 0, 0, 0, 0,
- 9, 9,173,170, 0, 0, 0, 0, 0, 0, 0, 9,174,175, 0, 9,
- 176, 0, 0,177,178, 0, 0, 0,179, 9, 9,180,181,182,183,184,
- 185, 9, 9,186,187, 0, 0, 0,188, 9,189,190,191, 9, 9,192,
- 185, 9, 9,193,194,105,195,102, 9, 33,196,197,198, 0, 0, 0,
- 199,200, 94, 9, 9,201,202, 2,203, 20, 21,204,205,206,207,208,
- 9, 9, 9,209,210,211,212, 0,195, 9, 9,213,214, 2, 0, 0,
- 9, 9,215,216,217,218, 0, 0, 9, 9, 9,219,220, 2, 0, 0,
- 9, 9,221,222, 2, 0, 0, 0, 9,223,224,103,225, 0, 0, 0,
- 9, 9,226,227, 0, 0, 0, 0,228,229, 9,230,231, 2, 0, 0,
- 0, 0,232, 9, 9,233,234, 0,235, 9, 9,236,237,238, 9, 9,
- 239,240, 0, 0, 0, 0, 0, 0, 21, 9,215,241, 7, 9, 70, 18,
- 9,242, 73,243, 0, 0, 0, 0,244, 9, 9,245,246, 2,247, 9,
- 248,249, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,250,
- 251, 48, 9,252,253, 2, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9,254,255,256, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
- 9, 9, 9,257, 0, 0, 0, 0, 9, 9, 9, 9,258,259,260,260,
- 261,262, 0, 0, 0, 0,263, 0, 9, 9, 9, 9, 9,264, 0, 0,
- 9, 9, 9, 9, 9, 9,105, 70, 94,265, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,266, 9, 9, 70,267,268, 0, 0, 0,
- 0, 9,269, 0, 9, 9,270, 2, 0, 0, 0, 0, 0, 9,271, 2,
- 9, 9, 9, 9,272, 2, 0, 0,129,129,129,129,129,129,129,129,
- 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129,
-};
-
-static inline unsigned
-hb_use_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline uint_fast8_t
-hb_use_get_category (unsigned u)
-{
- return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
-}
-
-
-#else
-
-static const uint8_t
-hb_use_u8[3413] =
-{
- 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 14, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1,
- 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1,
- 1, 20, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 22, 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, 1, 23, 24, 25, 26, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27,
- 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, 48,
- 49, 50, 50, 50, 50, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 52, 53, 1, 1, 1,
- 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 55, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 1, 1,
- 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 58, 59, 1, 60, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1,
- 1, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 8, 0, 0, 0, 0,
- 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 0, 55, 56, 57, 58, 59, 0, 0, 0, 60, 61, 62, 63, 55, 64, 65,
- 66, 67, 55, 55, 68, 69, 70, 0, 0, 71, 72, 73, 74, 55, 75, 76,
- 0, 77, 55, 78, 79, 80, 0, 0, 0, 81, 82, 83, 84, 85, 86, 55,
- 87, 55, 88, 89, 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, 0, 0,
- 92, 93, 94, 0, 95, 96, 0, 0, 97, 0, 0, 0, 0, 0, 0, 98,
- 0, 0, 99, 55, 100, 0, 0, 0, 0, 101, 102, 55, 103, 104, 105, 106,
- 107, 55, 108, 109, 0, 110, 111, 112, 113, 55, 114, 115, 116, 55, 117, 118,
- 119, 0, 0, 0, 0, 0, 0, 55, 120, 121, 0, 0, 0, 0, 0, 0,
- 122, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 124, 125, 126, 0,
- 0, 127, 128, 129, 0, 0, 0, 50, 130, 0, 0, 0, 0, 131, 132, 0,
- 0, 55, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 134, 0,
- 0, 0, 99, 135, 99, 136, 137, 138, 0, 139, 140, 141, 142, 143, 144, 145,
- 0, 146, 147, 148, 149, 143, 150, 151, 152, 153, 154, 155, 0, 156, 157, 158,
- 159, 160, 161, 162, 163, 0, 0, 0, 0, 55, 164, 165, 166, 167, 168, 169,
- 0, 0, 0, 0, 0, 55, 170, 171, 0, 55, 172, 173, 0, 55, 174, 66,
- 0, 175, 176, 177, 0, 0, 0, 0, 0, 55, 178, 0, 0, 0, 0, 0,
- 0, 179, 180, 181, 0, 0, 182, 183, 184, 185, 186, 187, 55, 188, 0, 0,
- 0, 189, 190, 191, 192, 193, 194, 0, 0, 195, 196, 197, 198, 199, 66, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 202, 203, 0, 0, 0, 0,
- 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 204, 205, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 66, 0, 55, 206, 0, 0, 0, 0, 0,
- 0, 55, 55, 207, 208, 209, 0, 0, 210, 55, 55, 55, 55, 55, 55, 211,
- 0, 55, 55, 55, 212, 213, 0, 0, 0, 0, 0, 0, 214, 0, 0, 0,
- 0, 55, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 217, 55,
- 218, 0, 0, 0, 0, 0, 0, 99, 219, 55, 55, 220, 0, 0, 0, 0,
- 0, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222,
- 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4,
- 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10,
- 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22,
- 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2,
- 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7,
- 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2,
- 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32,
- 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7,
- 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35,
- 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7,
- 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0,
- 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2,
- 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22,
- 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7,
- 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2,
- 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0,
- 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0,
- 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7,
- 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15,
- 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0,
- 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15,
- 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0,
- 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51,
- 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0,
- 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2,
- 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0,
- 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0,
- 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0,
- 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18,
- 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61,
- 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43,
- 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0,
- 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27,
- 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76,
- 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0,
- 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0,
- 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82,
- 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79,
- 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2,
- 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0,
- 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2,
- 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0,
- 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0,
- 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59,
- 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44,
- 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20,
- 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108,
- 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2,
- 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43,
- 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111,
- 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28,
- 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38,
- 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0,
- 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118,
- 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0,
- 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
- 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0,
- 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29,
- 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0,
- 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0,
- 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18,
- 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2,
- 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0,
- 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57,
- 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136,
- 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2,
- 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19,
- 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141,
- 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0,
- 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2,
- 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7,
- 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2,
- 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2,
- 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2,
- 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36,
- 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0,
- 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2,
- 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0,
- 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2,
- 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2,
- 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0,
- 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151,
- 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0,
- 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20,
- 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0,
- 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2,
- 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2,
- 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7,
- 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32,
- 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44,
- 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18,
- 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
- 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23,
- 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
- 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80,
- 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164,
- 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41,
- 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0,
- 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2,
- 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0,
- 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21,
- 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2,
- 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0,
- 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173,
- 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9,
- 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0,
- 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20,
- 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2,
- 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0,
- 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2,
- 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0,
- 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114,
- 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0,
- 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0,
- 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
- 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56,
- 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2,
- 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
- 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20,
- 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB,
- O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,
- CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
- VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,
- VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw,
- O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst,
- VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv,
- B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB,
- SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv,
- MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,
- VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
- VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB,
- B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw,
- SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,
- SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
- CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H,
- VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H,
- O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,
- VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst,
- CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R,
- R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst,
- H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R,
- MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B,
- H, B,VMBlw, O, VBlw,
-};
-static const uint16_t
-hb_use_u16[448] =
-{
- 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11,
- 9, 12, 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0,
- 17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46,
- 30, 0, 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54,
- 17, 55, 56, 48, 9, 57, 58, 59, 60, 61, 9, 62, 63, 64, 30, 65,
- 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 9, 9,
- 77, 78, 79, 80, 81, 82, 83, 84, 9, 85, 9, 86, 9, 87, 88, 89,
- 9, 90, 91, 92, 2, 0, 93, 0, 9, 94, 95, 9, 96, 0, 97, 98,
- 99,100, 30, 9,101,102,103, 9,104,105, 9,106, 9,107,108,109,
- 2, 2,110, 9, 9,111,112, 2,113,114,115, 9,116, 9,117,118,
- 119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0,129,130,
- 131, 0, 0,132,133, 0, 0, 9,134,135,136, 9,137, 0, 9,138,
- 139, 9, 9,140,141, 2,142,143,144, 9,145,146,147, 9, 9,148,
- 149, 2,150, 98,151,152,153, 2, 9,154, 9,155,156, 0,157,158,
- 159, 2,160, 0, 0,161, 0,162, 0,163,163,164, 33,165,166,167,
- 9,168, 94, 0,169, 0, 9,170,171, 0,172, 2,173,170,174,175,
- 176, 0, 0,177,178, 0,179, 9, 9,180,181,182,183,184,185, 9,
- 9,186,187, 0,188, 9,189,190,191, 9, 9,192, 9,193,194,105,
- 195,102, 9, 33,196,197,198, 0,199,200, 94, 9, 9,201,202, 2,
- 203, 20, 21,204,205,206,207,208, 9,209,210,211,212, 0,195, 9,
- 9,213,214, 2,215,216,217,218, 9,219,220, 2,221,222, 9,223,
- 224,103,225, 0,226,227,228,229, 9,230,231, 2,232, 9, 9,233,
- 234, 0,235, 9, 9,236,237,238,239,240, 21, 9,215,241, 7, 9,
- 70, 18, 9,242, 73,243,244, 9, 9,245,246, 2,247, 9,248,249,
- 9,250,251, 48, 9,252,253, 2, 9,254,255,256, 9,257,258,259,
- 260,260,261,262,263, 0, 9,264,105, 70, 94,265, 0,266, 70,267,
- 268, 0,269, 0,270, 2,271, 2,272, 2,129,129,160,160,160,129,
-};
-
-static inline unsigned
-hb_use_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline uint_fast8_t
-hb_use_get_category (unsigned u)
-{
- return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
-}
-
-#endif
-
-#undef B
-#undef CGJ
-#undef CS
-#undef G
-#undef GB
-#undef H
-#undef HN
-#undef HVM
-#undef IS
-#undef J
-#undef N
-#undef O
-#undef R
-#undef SB
-#undef SE
-#undef SUB
-#undef Sk
-#undef WJ
-#undef ZWNJ
-#undef CMAbv
-#undef CMBlw
-#undef FAbv
-#undef FBlw
-#undef FPst
-#undef FMAbv
-#undef FMBlw
-#undef FMPst
-#undef MAbv
-#undef MBlw
-#undef MPst
-#undef MPre
-#undef SMAbv
-#undef SMBlw
-#undef VAbv
-#undef VBlw
-#undef VPst
-#undef VPre
-#undef VMAbv
-#undef VMBlw
-#undef VMPst
-#undef VMPre
-
-
-#endif /* HB_OT_SHAPER_USE_TABLE_HH */
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use.cc
deleted file mode 100644
index 342aba12358..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use.cc
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright © 2015 Mozilla Foundation.
- * Copyright © 2015 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.
- *
- * Mozilla Author(s): Jonathan Kew
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-use-machine.hh"
-#include "hb-ot-shaper-use-table.hh"
-#include "hb-ot-shaper-arabic.hh"
-#include "hb-ot-shaper-arabic-joining-list.hh"
-#include "hb-ot-shaper-vowel-constraints.hh"
-
-
-/*
- * Universal Shaping Engine.
- * https://docs.microsoft.com/en-us/typography/script-development/use
- */
-
-static const hb_tag_t
-use_basic_features[] =
-{
- /*
- * Basic features.
- * These features are applied all at once, before reordering, constrained
- * to the syllable.
- */
- HB_TAG('r','k','r','f'),
- HB_TAG('a','b','v','f'),
- HB_TAG('b','l','w','f'),
- HB_TAG('h','a','l','f'),
- HB_TAG('p','s','t','f'),
- HB_TAG('v','a','t','u'),
- HB_TAG('c','j','c','t'),
-};
-static const hb_tag_t
-use_topographical_features[] =
-{
- HB_TAG('i','s','o','l'),
- HB_TAG('i','n','i','t'),
- HB_TAG('m','e','d','i'),
- HB_TAG('f','i','n','a'),
-};
-/* Same order as use_topographical_features. */
-enum joining_form_t {
- JOINING_FORM_ISOL,
- JOINING_FORM_INIT,
- JOINING_FORM_MEDI,
- JOINING_FORM_FINA,
- _JOINING_FORM_NONE
-};
-static const hb_tag_t
-use_other_features[] =
-{
- /*
- * Other features.
- * These features are applied all at once, after reordering and
- * clearing syllables.
- */
- HB_TAG('a','b','v','s'),
- HB_TAG('b','l','w','s'),
- HB_TAG('h','a','l','n'),
- HB_TAG('p','r','e','s'),
- HB_TAG('p','s','t','s'),
-};
-
-static bool
-setup_syllables_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-record_rphf_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-record_pref_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-static bool
-reorder_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer);
-
-static void
-collect_features_use (hb_ot_shape_planner_t *plan)
-{
- hb_ot_map_builder_t *map = &plan->map;
-
- /* Do this before any lookups have been applied. */
- map->add_gsub_pause (setup_syllables_use);
-
- /* "Default glyph pre-processing group" */
- map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
- map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
- map->enable_feature (HB_TAG('n','u','k','t'), F_PER_SYLLABLE);
- map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
-
- /* "Reordering group" */
- map->add_gsub_pause (_hb_clear_substitution_flags);
- map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
- map->add_gsub_pause (record_rphf_use);
- map->add_gsub_pause (_hb_clear_substitution_flags);
- map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ | F_PER_SYLLABLE);
- map->add_gsub_pause (record_pref_use);
-
- /* "Orthographic unit shaping group" */
- for (unsigned int i = 0; i < ARRAY_LENGTH (use_basic_features); i++)
- map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ | F_PER_SYLLABLE);
-
- map->add_gsub_pause (reorder_use);
- map->add_gsub_pause (hb_syllabic_clear_var); // Don't need syllables anymore, use stop to free buffer var
-
- /* "Topographical features" */
- for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
- map->add_feature (use_topographical_features[i]);
- map->add_gsub_pause (nullptr);
-
- /* "Standard typographic presentation" */
- for (unsigned int i = 0; i < ARRAY_LENGTH (use_other_features); i++)
- map->enable_feature (use_other_features[i], F_MANUAL_ZWJ);
-}
-
-struct use_shape_plan_t
-{
- hb_mask_t rphf_mask;
-
- arabic_shape_plan_t *arabic_plan;
-};
-
-static void *
-data_create_use (const hb_ot_shape_plan_t *plan)
-{
- use_shape_plan_t *use_plan = (use_shape_plan_t *) hb_calloc (1, sizeof (use_shape_plan_t));
- if (unlikely (!use_plan))
- return nullptr;
-
- use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f'));
-
- if (has_arabic_joining (plan->props.script))
- {
- use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan);
- if (unlikely (!use_plan->arabic_plan))
- {
- hb_free (use_plan);
- return nullptr;
- }
- }
-
- return use_plan;
-}
-
-static void
-data_destroy_use (void *data)
-{
- use_shape_plan_t *use_plan = (use_shape_plan_t *) data;
-
- if (use_plan->arabic_plan)
- data_destroy_arabic (use_plan->arabic_plan);
-
- hb_free (data);
-}
-
-static void
-setup_masks_use (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
-{
- const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
-
- /* Do this before allocating use_category(). */
- if (use_plan->arabic_plan)
- {
- setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script);
- }
-
- HB_BUFFER_ALLOCATE_VAR (buffer, use_category);
-
- /* We cannot setup masks here. We save information about characters
- * and setup masks later on in a pause-callback. */
-
- unsigned int count = buffer->len;
- hb_glyph_info_t *info = buffer->info;
- for (unsigned int i = 0; i < count; i++)
- info[i].use_category() = hb_use_get_category (info[i].codepoint);
-}
-
-static void
-setup_rphf_mask (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer)
-{
- const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
-
- hb_mask_t mask = use_plan->rphf_mask;
- if (!mask) return;
-
- hb_glyph_info_t *info = buffer->info;
-
- foreach_syllable (buffer, start, end)
- {
- unsigned int limit = info[start].use_category() == USE(R) ? 1 : hb_min (3u, end - start);
- for (unsigned int i = start; i < start + limit; i++)
- info[i].mask |= mask;
- }
-}
-
-static void
-setup_topographical_masks (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer)
-{
- const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
- if (use_plan->arabic_plan)
- return;
-
- static_assert ((JOINING_FORM_INIT < 4 && JOINING_FORM_ISOL < 4 && JOINING_FORM_MEDI < 4 && JOINING_FORM_FINA < 4), "");
- hb_mask_t masks[4], all_masks = 0;
- for (unsigned int i = 0; i < 4; i++)
- {
- masks[i] = plan->map.get_1_mask (use_topographical_features[i]);
- if (masks[i] == plan->map.get_global_mask ())
- masks[i] = 0;
- all_masks |= masks[i];
- }
- if (!all_masks)
- return;
- hb_mask_t other_masks = ~all_masks;
-
- unsigned int last_start = 0;
- joining_form_t last_form = _JOINING_FORM_NONE;
- hb_glyph_info_t *info = buffer->info;
- foreach_syllable (buffer, start, end)
- {
- use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
- switch (syllable_type)
- {
- case use_hieroglyph_cluster:
- case use_non_cluster:
- /* These don't join. Nothing to do. */
- last_form = _JOINING_FORM_NONE;
- break;
-
- case use_virama_terminated_cluster:
- case use_sakot_terminated_cluster:
- case use_standard_cluster:
- case use_number_joiner_terminated_cluster:
- case use_numeral_cluster:
- case use_symbol_cluster:
- case use_broken_cluster:
-
- bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL;
-
- if (join)
- {
- /* Fixup previous syllable's form. */
- last_form = last_form == JOINING_FORM_FINA ? JOINING_FORM_MEDI : JOINING_FORM_INIT;
- for (unsigned int i = last_start; i < start; i++)
- info[i].mask = (info[i].mask & other_masks) | masks[last_form];
- }
-
- /* Form for this syllable. */
- last_form = join ? JOINING_FORM_FINA : JOINING_FORM_ISOL;
- for (unsigned int i = start; i < end; i++)
- info[i].mask = (info[i].mask & other_masks) | masks[last_form];
-
- break;
- }
-
- last_start = start;
- }
-}
-
-static bool
-setup_syllables_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
- find_syllables_use (buffer);
- foreach_syllable (buffer, start, end)
- buffer->unsafe_to_break (start, end);
- setup_rphf_mask (plan, buffer);
- setup_topographical_masks (plan, buffer);
- return false;
-}
-
-static bool
-record_rphf_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
-
- hb_mask_t mask = use_plan->rphf_mask;
- if (!mask) return false;
- hb_glyph_info_t *info = buffer->info;
-
- foreach_syllable (buffer, start, end)
- {
- /* Mark a substituted repha as USE(R). */
- for (unsigned int i = start; i < end && (info[i].mask & mask); i++)
- if (_hb_glyph_info_substituted (&info[i]))
- {
- info[i].use_category() = USE(R);
- break;
- }
- }
- return false;
-}
-
-static bool
-record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_font_t *font HB_UNUSED,
- hb_buffer_t *buffer)
-{
- hb_glyph_info_t *info = buffer->info;
-
- foreach_syllable (buffer, start, end)
- {
- /* Mark a substituted pref as VPre, as they behave the same way. */
- for (unsigned int i = start; i < end; i++)
- if (_hb_glyph_info_substituted (&info[i]))
- {
- info[i].use_category() = USE(VPre);
- break;
- }
- }
- return false;
-}
-
-static inline bool
-is_halant_use (const hb_glyph_info_t &info)
-{
- return (info.use_category() == USE(H) || info.use_category() == USE(HVM) || info.use_category() == USE(IS)) &&
- !_hb_glyph_info_ligated (&info);
-}
-
-static void
-reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
-{
- use_syllable_type_t syllable_type = (use_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
- /* Only a few syllable types need reordering. */
- if (unlikely (!(FLAG_UNSAFE (syllable_type) &
- (FLAG (use_virama_terminated_cluster) |
- FLAG (use_sakot_terminated_cluster) |
- FLAG (use_standard_cluster) |
- FLAG (use_symbol_cluster) |
- FLAG (use_broken_cluster) |
- 0))))
- return;
-
- hb_glyph_info_t *info = buffer->info;
-
-#define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \
- FLAG64 (USE(FBlw)) | \
- FLAG64 (USE(FPst)) | \
- FLAG64 (USE(MAbv)) | \
- FLAG64 (USE(MBlw)) | \
- FLAG64 (USE(MPst)) | \
- FLAG64 (USE(MPre)) | \
- FLAG64 (USE(VAbv)) | \
- FLAG64 (USE(VBlw)) | \
- FLAG64 (USE(VPst)) | \
- FLAG64 (USE(VPre)) | \
- FLAG64 (USE(VMAbv)) | \
- FLAG64 (USE(VMBlw)) | \
- FLAG64 (USE(VMPst)) | \
- FLAG64 (USE(VMPre)))
-
- /* Move things forward. */
- if (info[start].use_category() == USE(R) && end - start > 1)
- {
- /* Got a repha. Reorder it towards the end, but before the first post-base
- * glyph. */
- for (unsigned int i = start + 1; i < end; i++)
- {
- bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) ||
- is_halant_use (info[i]);
- if (is_post_base_glyph || i == end - 1)
- {
- /* If we hit a post-base glyph, move before it; otherwise move to the
- * end. Shift things in between backward. */
-
- if (is_post_base_glyph)
- i--;
-
- buffer->merge_clusters (start, i + 1);
- hb_glyph_info_t t = info[start];
- memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]));
- info[i] = t;
-
- break;
- }
- }
- }
-
- /* Move things back. */
- unsigned int j = start;
- for (unsigned int i = start; i < end; i++)
- {
- uint32_t flag = FLAG_UNSAFE (info[i].use_category());
- if (is_halant_use (info[i]))
- {
- /* If we hit a halant, move after it; otherwise move to the beginning, and
- * shift things in between forward. */
- j = i + 1;
- }
- else if (((flag) & (FLAG (USE(VPre)) | FLAG (USE(VMPre)))) &&
- /* Only move the first component of a MultipleSubst. */
- 0 == _hb_glyph_info_get_lig_comp (&info[i]) &&
- j < i)
- {
- buffer->merge_clusters (j, i + 1);
- hb_glyph_info_t t = info[i];
- memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0]));
- info[j] = t;
- }
- }
-}
-
-static bool
-reorder_use (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer)
-{
- bool ret = false;
- if (buffer->message (font, "start reordering USE"))
- {
- if (hb_syllabic_insert_dotted_circles (font, buffer,
- use_broken_cluster,
- USE(B),
- USE(R)))
- ret = true;
-
- foreach_syllable (buffer, start, end)
- reorder_syllable_use (buffer, start, end);
-
- (void) buffer->message (font, "end reordering USE");
- }
-
- HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
-
- return ret;
-}
-
-
-static void
-preprocess_text_use (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- hb_font_t *font)
-{
- _hb_preprocess_text_vowel_constraints (plan, buffer, font);
-}
-
-static bool
-compose_use (const hb_ot_shape_normalize_context_t *c,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab)
-{
- /* Avoid recomposing split matras. */
- if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
- return false;
-
- return (bool)c->unicode->compose (a, b, ab);
-}
-
-
-const hb_ot_shaper_t _hb_ot_shaper_use =
-{
- collect_features_use,
- nullptr, /* override_features */
- data_create_use,
- data_destroy_use,
- preprocess_text_use,
- nullptr, /* postprocess_glyphs */
- nullptr, /* decompose */
- compose_use,
- setup_masks_use,
- nullptr, /* reorder_marks */
- HB_TAG_NONE, /* gpos_tag */
- HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
- false, /* fallback_position */
-};
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.cc
deleted file mode 100644
index e76b554b00c..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.cc
+++ /dev/null
@@ -1,477 +0,0 @@
-/* == Start of generated functions == */
-/*
- * The following functions are generated by running:
- *
- * ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt
- *
- * on files with these headers:
- *
- * # IndicShapingInvalidCluster.txt
- * # Date: 2015-03-12, 21:17:00 GMT [AG]
- * # Date: 2019-11-08, 23:22:00 GMT [AG]
- *
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OT_SHAPE
-
-#include "hb-ot-shaper-vowel-constraints.hh"
-
-static void
-_output_dotted_circle (hb_buffer_t *buffer)
-{
- (void) buffer->output_glyph (0x25CCu);
- _hb_glyph_info_reset_continuation (&buffer->prev());
-}
-
-static void
-_output_with_dotted_circle (hb_buffer_t *buffer)
-{
- _output_dotted_circle (buffer);
- (void) buffer->next_glyph ();
-}
-
-void
-_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
-{
-#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS
- return;
-#endif
- if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
- return;
-
- /* UGLY UGLY UGLY business of adding dotted-circle in the middle of
- * vowel-sequences that look like another vowel. Data for each script
- * collected from the USE script development spec.
- *
- * https://github.com/harfbuzz/harfbuzz/issues/1019
- */
- buffer->clear_output ();
- unsigned int count = buffer->len;
- switch ((unsigned) buffer->props.script)
- {
- case HB_SCRIPT_DEVANAGARI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0905u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x093Au: case 0x093Bu: case 0x093Eu: case 0x0945u:
- case 0x0946u: case 0x0949u: case 0x094Au: case 0x094Bu:
- case 0x094Cu: case 0x094Fu: case 0x0956u: case 0x0957u:
- matched = true;
- break;
- }
- break;
- case 0x0906u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x093Au: case 0x0945u: case 0x0946u: case 0x0947u:
- case 0x0948u:
- matched = true;
- break;
- }
- break;
- case 0x0909u:
- matched = 0x0941u == buffer->cur (1).codepoint;
- break;
- case 0x090Fu:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0945u: case 0x0946u: case 0x0947u:
- matched = true;
- break;
- }
- break;
- case 0x0930u:
- if (0x094Du == buffer->cur (1).codepoint &&
- buffer->idx + 2 < count &&
- 0x0907u == buffer->cur (2).codepoint)
- {
- (void) buffer->next_glyph ();
- matched = true;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_BENGALI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0985u:
- matched = 0x09BEu == buffer->cur (1).codepoint;
- break;
- case 0x098Bu:
- matched = 0x09C3u == buffer->cur (1).codepoint;
- break;
- case 0x098Cu:
- matched = 0x09E2u == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_GURMUKHI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0A05u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0A3Eu: case 0x0A48u: case 0x0A4Cu:
- matched = true;
- break;
- }
- break;
- case 0x0A72u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0A3Fu: case 0x0A40u: case 0x0A47u:
- matched = true;
- break;
- }
- break;
- case 0x0A73u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0A41u: case 0x0A42u: case 0x0A4Bu:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_GUJARATI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0A85u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0ABEu: case 0x0AC5u: case 0x0AC7u: case 0x0AC8u:
- case 0x0AC9u: case 0x0ACBu: case 0x0ACCu:
- matched = true;
- break;
- }
- break;
- case 0x0AC5u:
- matched = 0x0ABEu == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_ORIYA:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0B05u:
- matched = 0x0B3Eu == buffer->cur (1).codepoint;
- break;
- case 0x0B0Fu: case 0x0B13u:
- matched = 0x0B57u == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_TAMIL:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- if (0x0B85u == buffer->cur ().codepoint &&
- 0x0BC2u == buffer->cur (1).codepoint)
- {
- matched = true;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_TELUGU:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0C12u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0C4Cu: case 0x0C55u:
- matched = true;
- break;
- }
- break;
- case 0x0C3Fu: case 0x0C46u: case 0x0C4Au:
- matched = 0x0C55u == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_KANNADA:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0C89u: case 0x0C8Bu:
- matched = 0x0CBEu == buffer->cur (1).codepoint;
- break;
- case 0x0C92u:
- matched = 0x0CCCu == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_MALAYALAM:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0D07u: case 0x0D09u:
- matched = 0x0D57u == buffer->cur (1).codepoint;
- break;
- case 0x0D0Eu:
- matched = 0x0D46u == buffer->cur (1).codepoint;
- break;
- case 0x0D12u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0D3Eu: case 0x0D57u:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_SINHALA:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x0D85u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0DCFu: case 0x0DD0u: case 0x0DD1u:
- matched = true;
- break;
- }
- break;
- case 0x0D8Bu: case 0x0D8Fu: case 0x0D94u:
- matched = 0x0DDFu == buffer->cur (1).codepoint;
- break;
- case 0x0D8Du:
- matched = 0x0DD8u == buffer->cur (1).codepoint;
- break;
- case 0x0D91u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
- case 0x0DDDu: case 0x0DDEu:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_BRAHMI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x11005u:
- matched = 0x11038u == buffer->cur (1).codepoint;
- break;
- case 0x1100Bu:
- matched = 0x1103Eu == buffer->cur (1).codepoint;
- break;
- case 0x1100Fu:
- matched = 0x11042u == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_KHOJKI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x11200u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x1122Cu: case 0x11231u: case 0x11233u:
- matched = true;
- break;
- }
- break;
- case 0x11206u:
- matched = 0x1122Cu == buffer->cur (1).codepoint;
- break;
- case 0x1122Cu:
- switch (buffer->cur (1).codepoint)
- {
- case 0x11230u: case 0x11231u:
- matched = true;
- break;
- }
- break;
- case 0x11240u:
- matched = 0x1122Eu == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_KHUDAWADI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x112B0u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x112E0u: case 0x112E5u: case 0x112E6u: case 0x112E7u:
- case 0x112E8u:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_TIRHUTA:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x11481u:
- matched = 0x114B0u == buffer->cur (1).codepoint;
- break;
- case 0x1148Bu: case 0x1148Du:
- matched = 0x114BAu == buffer->cur (1).codepoint;
- break;
- case 0x114AAu:
- switch (buffer->cur (1).codepoint)
- {
- case 0x114B5u: case 0x114B6u:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_MODI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x11600u: case 0x11601u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x11639u: case 0x1163Au:
- matched = true;
- break;
- }
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- case HB_SCRIPT_TAKRI:
- for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
- {
- bool matched = false;
- switch (buffer->cur ().codepoint)
- {
- case 0x11680u:
- switch (buffer->cur (1).codepoint)
- {
- case 0x116ADu: case 0x116B4u: case 0x116B5u:
- matched = true;
- break;
- }
- break;
- case 0x11686u:
- matched = 0x116B2u == buffer->cur (1).codepoint;
- break;
- }
- (void) buffer->next_glyph ();
- if (matched) _output_with_dotted_circle (buffer);
- }
- break;
-
- default:
- break;
- }
- buffer->sync ();
-}
-
-
-#endif
-/* == End of generated functions == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.hh
deleted file mode 100644
index 5a7ee1b0f27..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-vowel-constraints.hh
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright © 2018 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_SHAPER_VOWEL_CONSTRAINTS_HH
-#define HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH
-
-#include "hb.hh"
-
-#include "hb-ot-shaper.hh"
-
-HB_INTERNAL void
-_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan,
- hb_buffer_t *buffer,
- hb_font_t *font);
-
-#endif /* HB_OT_SHAPER_VOWEL_CONSTRAINTS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh
deleted file mode 100644
index de553dd72ff..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-stat-table.hh
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright © 2018 Ebrahim Byagowi
- *
- * 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.
- */
-
-#ifndef HB_OT_STAT_TABLE_HH
-#define HB_OT_STAT_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-
-/*
- * STAT -- Style Attributes
- * https://docs.microsoft.com/en-us/typography/opentype/spec/stat
- */
-#define HB_OT_TAG_STAT HB_TAG('S','T','A','T')
-
-
-namespace OT {
-
-enum
-{
- OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001, /* If set, this axis value table
- * provides axis value information
- * that is applicable to other fonts
- * within the same font family. This
- * is used if the other fonts were
- * released earlier and did not include
- * information about values for some axis.
- * If newer versions of the other
- * fonts include the information
- * themselves and are present,
- * then this record is ignored. */
- ELIDABLE_AXIS_VALUE_NAME = 0x0002 /* If set, it indicates that the axis
- * value represents the “normal” value
- * for the axis and may be omitted when
- * composing name strings. */
- // Reserved = 0xFFFC /* Reserved for future use — set to zero. */
-};
-
-struct StatAxisRecord
-{
- int cmp (hb_tag_t key) const { return tag.cmp (key); }
-
- hb_ot_name_id_t get_name_id () const { return nameID; }
-
- hb_tag_t get_axis_tag () const { return tag; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this)));
- }
-
- protected:
- Tag tag; /* A tag identifying the axis of design variation. */
- NameID nameID; /* The name ID for entries in the 'name' table that
- * provide a display string for this axis. */
- HBUINT16 ordering; /* A value that applications can use to determine
- * primary sorting of face names, or for ordering
- * of descriptors when composing family or face names. */
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-struct AxisValueFormat1
-{
- unsigned int get_axis_index () const { return axisIndex; }
- float get_value () const { return value.to_float (); }
-
- hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
-
- hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
- {
- unsigned axis_idx = get_axis_index ();
- return axis_records[axis_idx].get_axis_tag ();
- }
-
- bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
- const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
- {
- hb_tag_t axis_tag = get_axis_tag (axis_records);
- float axis_value = get_value ();
-
- if (!user_axes_location->has (axis_tag) ||
- fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
- return true;
-
- return false;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_array_t<const StatAxisRecord> axis_records) const
- {
- TRACE_SUBSET (this);
- const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
-
- if (keep_axis_value (axis_records, user_axes_location))
- return_trace (c->serializer->embed (this));
-
- return_trace (false);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier — set to 1. */
- HBUINT16 axisIndex; /* Zero-base index into the axis record array
- * identifying the axis of design variation
- * to which the axis value record applies.
- * Must be less than designAxisCount. */
- HBUINT16 flags; /* Flags — see below for details. */
- NameID valueNameID; /* The name ID for entries in the 'name' table
- * that provide a display string for this
- * attribute value. */
- F16DOT16 value; /* A numeric value for this attribute value. */
- public:
- DEFINE_SIZE_STATIC (12);
-};
-
-struct AxisValueFormat2
-{
- unsigned int get_axis_index () const { return axisIndex; }
- float get_value () const { return nominalValue.to_float (); }
-
- hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
-
- hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
- {
- unsigned axis_idx = get_axis_index ();
- return axis_records[axis_idx].get_axis_tag ();
- }
-
- bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
- const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
- {
- hb_tag_t axis_tag = get_axis_tag (axis_records);
- float axis_value = get_value ();
-
- if (!user_axes_location->has (axis_tag) ||
- fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
- return true;
-
- return false;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_array_t<const StatAxisRecord> axis_records) const
- {
- TRACE_SUBSET (this);
- const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
-
- if (keep_axis_value (axis_records, user_axes_location))
- return_trace (c->serializer->embed (this));
-
- return_trace (false);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier — set to 2. */
- HBUINT16 axisIndex; /* Zero-base index into the axis record array
- * identifying the axis of design variation
- * to which the axis value record applies.
- * Must be less than designAxisCount. */
- HBUINT16 flags; /* Flags — see below for details. */
- NameID valueNameID; /* The name ID for entries in the 'name' table
- * that provide a display string for this
- * attribute value. */
- F16DOT16 nominalValue; /* A numeric value for this attribute value. */
- F16DOT16 rangeMinValue; /* The minimum value for a range associated
- * with the specified name ID. */
- F16DOT16 rangeMaxValue; /* The maximum value for a range associated
- * with the specified name ID. */
- public:
- DEFINE_SIZE_STATIC (20);
-};
-
-struct AxisValueFormat3
-{
- unsigned int get_axis_index () const { return axisIndex; }
- float get_value () const { return value.to_float (); }
-
- hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
-
- hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
- {
- unsigned axis_idx = get_axis_index ();
- return axis_records[axis_idx].get_axis_tag ();
- }
-
- bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
- const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
- {
- hb_tag_t axis_tag = get_axis_tag (axis_records);
- float axis_value = get_value ();
-
- if (!user_axes_location->has (axis_tag) ||
- fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
- return true;
-
- return false;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_array_t<const StatAxisRecord> axis_records) const
- {
- TRACE_SUBSET (this);
- const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
-
- if (keep_axis_value (axis_records, user_axes_location))
- return_trace (c->serializer->embed (this));
-
- return_trace (false);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 format; /* Format identifier — set to 3. */
- HBUINT16 axisIndex; /* Zero-base index into the axis record array
- * identifying the axis of design variation
- * to which the axis value record applies.
- * Must be less than designAxisCount. */
- HBUINT16 flags; /* Flags — see below for details. */
- NameID valueNameID; /* The name ID for entries in the 'name' table
- * that provide a display string for this
- * attribute value. */
- F16DOT16 value; /* A numeric value for this attribute value. */
- F16DOT16 linkedValue; /* The numeric value for a style-linked mapping
- * from this value. */
- public:
- DEFINE_SIZE_STATIC (16);
-};
-
-struct AxisValueRecord
-{
- unsigned int get_axis_index () const { return axisIndex; }
- float get_value () const { return value.to_float (); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- protected:
- HBUINT16 axisIndex; /* Zero-base index into the axis record array
- * identifying the axis to which this value
- * applies. Must be less than designAxisCount. */
- F16DOT16 value; /* A numeric value for this attribute value. */
- public:
- DEFINE_SIZE_STATIC (6);
-};
-
-struct AxisValueFormat4
-{
- const AxisValueRecord &get_axis_record (unsigned int axis_index) const
- { return axisValues.as_array (axisCount)[axis_index]; }
-
- bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
- const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
- {
- hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount);
-
- for (const auto& rec : axis_value_records)
- {
- unsigned axis_idx = rec.get_axis_index ();
- float axis_value = rec.get_value ();
- hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag ();
-
- if (user_axes_location->has (axis_tag) &&
- fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f)
- return false;
- }
-
- return true;
- }
-
- bool subset (hb_subset_context_t *c,
- const hb_array_t<const StatAxisRecord> axis_records) const
- {
- TRACE_SUBSET (this);
- const hb_hashmap_t<hb_tag_t, float> *user_axes_location = &c->plan->user_axes_location;
- if (!keep_axis_value (axis_records, user_axes_location))
- return_trace (false);
-
- unsigned total_size = min_size + axisCount * AxisValueRecord::static_size;
- auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size);
- if (unlikely (!out)) return_trace (false);
- hb_memcpy (out, this, total_size);
- return_trace (true);
- }
-
- hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- axisValues.sanitize (c, axisCount)));
- }
-
- protected:
- HBUINT16 format; /* Format identifier — set to 4. */
- HBUINT16 axisCount; /* The total number of axes contributing to
- * this axis-values combination. */
- HBUINT16 flags; /* Flags — see below for details. */
- NameID valueNameID; /* The name ID for entries in the 'name' table
- * that provide a display string for this
- * attribute value. */
- UnsizedArrayOf<AxisValueRecord>
- axisValues; /* Array of AxisValue records that provide the
- * combination of axis values, one for each
- * contributing axis. */
- public:
- DEFINE_SIZE_ARRAY (8, axisValues);
-};
-
-struct AxisValue
-{
- bool get_value (unsigned int axis_index) const
- {
- switch (u.format)
- {
- case 1: return u.format1.get_value ();
- case 2: return u.format2.get_value ();
- case 3: return u.format3.get_value ();
- case 4: return u.format4.get_axis_record (axis_index).get_value ();
- default:return 0;
- }
- }
-
- unsigned int get_axis_index () const
- {
- switch (u.format)
- {
- case 1: return u.format1.get_axis_index ();
- case 2: return u.format2.get_axis_index ();
- case 3: return u.format3.get_axis_index ();
- /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */
- default:return -1;
- }
- }
-
- hb_ot_name_id_t get_value_name_id () const
- {
- switch (u.format)
- {
- case 1: return u.format1.get_value_name_id ();
- case 2: return u.format2.get_value_name_id ();
- case 3: return u.format3.get_value_name_id ();
- case 4: return u.format4.get_value_name_id ();
- default:return HB_OT_NAME_ID_INVALID;
- }
- }
-
- template <typename context_t, typename ...Ts>
- typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
- {
- if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
- TRACE_DISPATCH (this, u.format);
- switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
- case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
- case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
- case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
- default:return_trace (c->default_return_value ());
- }
- }
-
- bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
- hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
- {
- switch (u.format)
- {
- case 1: return u.format1.keep_axis_value (axis_records, user_axes_location);
- case 2: return u.format2.keep_axis_value (axis_records, user_axes_location);
- case 3: return u.format3.keep_axis_value (axis_records, user_axes_location);
- case 4: return u.format4.keep_axis_value (axis_records, user_axes_location);
- default:return false;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (this)))
- return_trace (false);
-
- switch (u.format)
- {
- case 1: return_trace (u.format1.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- case 3: return_trace (u.format3.sanitize (c));
- case 4: return_trace (u.format4.sanitize (c));
- default:return_trace (true);
- }
- }
-
- protected:
- union
- {
- HBUINT16 format;
- AxisValueFormat1 format1;
- AxisValueFormat2 format2;
- AxisValueFormat3 format3;
- AxisValueFormat4 format4;
- } u;
- public:
- DEFINE_SIZE_UNION (2, format);
-};
-
-struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>>
-{
- bool subset (hb_subset_context_t *c,
- unsigned axisValueCount,
- unsigned& count,
- const hb_array_t<const StatAxisRecord> axis_records) const
- {
- TRACE_SUBSET (this);
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!out)) return_trace (false);
-
- auto axisValueOffsets = as_array (axisValueCount);
- count = 0;
- for (const auto& offset : axisValueOffsets)
- {
- if (!offset) continue;
- auto o_snap = c->serializer->snapshot ();
- auto *o = c->serializer->embed (offset);
- if (!o) return_trace (false);
- if (!o->serialize_subset (c, offset, this, axis_records))
- {
- c->serializer->revert (o_snap);
- continue;
- }
- count++;
- }
-
- return_trace (count);
- }
-};
-
-struct STAT
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;
-
- bool has_data () const { return version.to_int (); }
-
- bool get_value (hb_tag_t tag, float *value) const
- {
- unsigned int axis_index;
- if (!get_design_axes ().lfind (tag, &axis_index)) return false;
-
- hb_array_t<const Offset16To<AxisValue>> axis_values = get_axis_value_offsets ();
- for (unsigned int i = 0; i < axis_values.length; i++)
- {
- const AxisValue& axis_value = this+axis_values[i];
- if (axis_value.get_axis_index () == axis_index)
- {
- if (value)
- *value = axis_value.get_value (axis_index);
- return true;
- }
- }
- return false;
- }
-
- unsigned get_design_axis_count () const { return designAxisCount; }
-
- hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
- {
- if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
- const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
- return axis_record.get_name_id ();
- }
-
- unsigned get_axis_value_count () const { return axisValueCount; }
-
- hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
- {
- if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
- const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
- return axis_value.get_value_name_id ();
- }
-
- void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
- hb_set_t *nameids_to_retain /* OUT */) const
- {
- if (!has_data ()) return;
-
- + get_design_axes ()
- | hb_map (&StatAxisRecord::get_name_id)
- | hb_sink (nameids_to_retain)
- ;
-
- auto designAxes = get_design_axes ();
-
- + get_axis_value_offsets ()
- | hb_map (hb_add (&(this + offsetToAxisValueOffsets)))
- | hb_filter ([&] (const AxisValue& _)
- { return _.keep_axis_value (designAxes, user_axes_location); })
- | hb_map (&AxisValue::get_value_name_id)
- | hb_sink (nameids_to_retain)
- ;
-
- nameids_to_retain->add (elidedFallbackNameID);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- STAT *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- auto designAxes = get_design_axes ();
- for (unsigned i = 0; i < (unsigned)designAxisCount; i++)
- if (unlikely (!c->serializer->embed (designAxes[i])))
- return_trace (false);
-
- if (designAxisCount)
- c->serializer->check_assign (out->designAxesOffset, this->get_size (),
- HB_SERIALIZE_ERROR_INT_OVERFLOW);
-
- unsigned count = 0;
- out->offsetToAxisValueOffsets.serialize_subset (c, offsetToAxisValueOffsets, this,
- axisValueCount, count, designAxes);
- return_trace (c->serializer->check_assign (out->axisValueCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this) &&
- version.major == 1 &&
- version.minor > 0 &&
- designAxesOffset.sanitize (c, this, designAxisCount) &&
- offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
- }
-
- protected:
- hb_array_t<const StatAxisRecord> const get_design_axes () const
- { return (this+designAxesOffset).as_array (designAxisCount); }
-
- hb_array_t<const Offset16To<AxisValue>> const get_axis_value_offsets () const
- { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }
-
-
- protected:
- FixedVersion<>version; /* Version of the stat table
- * initially set to 0x00010002u */
- HBUINT16 designAxisSize; /* The size in bytes of each axis record. */
- HBUINT16 designAxisCount;/* The number of design axis records. In a
- * font with an 'fvar' table, this value must be
- * greater than or equal to the axisCount value
- * in the 'fvar' table. In all fonts, must
- * be greater than zero if axisValueCount
- * is greater than zero. */
- NNOffset32To<UnsizedArrayOf<StatAxisRecord>>
- designAxesOffset;
- /* Offset in bytes from the beginning of
- * the STAT table to the start of the design
- * axes array. If designAxisCount is zero,
- * set to zero; if designAxisCount is greater
- * than zero, must be greater than zero. */
- HBUINT16 axisValueCount; /* The number of axis value tables. */
- NNOffset32To<AxisValueOffsetArray>
- offsetToAxisValueOffsets;
- /* Offset in bytes from the beginning of
- * the STAT table to the start of the design
- * axes value offsets array. If axisValueCount
- * is zero, set to zero; if axisValueCount is
- * greater than zero, must be greater than zero. */
- NameID elidedFallbackNameID;
- /* Name ID used as fallback when projection of
- * names into a particular font model produces
- * a subfamily name containing only elidable
- * elements. */
- public:
- DEFINE_SIZE_STATIC (20);
-};
-
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_STAT_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh
deleted file mode 100644
index 9394b90ee61..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag-table.hh
+++ /dev/null
@@ -1,2993 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-tag-table.py languagetags language-subtag-registry
- *
- * on files with these headers:
- *
- * <meta name="updated_at" content="2022-01-28 10:00 PM" />
- * File-Date: 2022-03-02
- */
-
-#ifndef HB_OT_TAG_TABLE_HH
-#define HB_OT_TAG_TABLE_HH
-
-static const LangTag ot_languages2[] = {
- {HB_TAG('a','a',' ',' '), HB_TAG('A','F','R',' ')}, /* Afar */
- {HB_TAG('a','b',' ',' '), HB_TAG('A','B','K',' ')}, /* Abkhazian */
- {HB_TAG('a','f',' ',' '), HB_TAG('A','F','K',' ')}, /* Afrikaans */
- {HB_TAG('a','k',' ',' '), HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */
- {HB_TAG('a','m',' ',' '), HB_TAG('A','M','H',' ')}, /* Amharic */
- {HB_TAG('a','n',' ',' '), HB_TAG('A','R','G',' ')}, /* Aragonese */
- {HB_TAG('a','r',' ',' '), HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
- {HB_TAG('a','s',' ',' '), HB_TAG('A','S','M',' ')}, /* Assamese */
- {HB_TAG('a','v',' ',' '), HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */
- {HB_TAG('a','y',' ',' '), HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */
- {HB_TAG('a','z',' ',' '), HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
- {HB_TAG('b','a',' ',' '), HB_TAG('B','S','H',' ')}, /* Bashkir */
- {HB_TAG('b','e',' ',' '), HB_TAG('B','E','L',' ')}, /* Belarusian -> Belarussian */
- {HB_TAG('b','g',' ',' '), HB_TAG('B','G','R',' ')}, /* Bulgarian */
- {HB_TAG('b','i',' ',' '), HB_TAG('B','I','S',' ')}, /* Bislama */
- {HB_TAG('b','i',' ',' '), HB_TAG('C','P','P',' ')}, /* Bislama -> Creoles */
- {HB_TAG('b','m',' ',' '), HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */
- {HB_TAG('b','n',' ',' '), HB_TAG('B','E','N',' ')}, /* Bengali */
- {HB_TAG('b','o',' ',' '), HB_TAG('T','I','B',' ')}, /* Tibetan */
- {HB_TAG('b','r',' ',' '), HB_TAG('B','R','E',' ')}, /* Breton */
- {HB_TAG('b','s',' ',' '), HB_TAG('B','O','S',' ')}, /* Bosnian */
- {HB_TAG('c','a',' ',' '), HB_TAG('C','A','T',' ')}, /* Catalan */
- {HB_TAG('c','e',' ',' '), HB_TAG('C','H','E',' ')}, /* Chechen */
- {HB_TAG('c','h',' ',' '), HB_TAG('C','H','A',' ')}, /* Chamorro */
- {HB_TAG('c','o',' ',' '), HB_TAG('C','O','S',' ')}, /* Corsican */
- {HB_TAG('c','r',' ',' '), HB_TAG('C','R','E',' ')}, /* Cree [macrolanguage] */
- {HB_TAG('c','s',' ',' '), HB_TAG('C','S','Y',' ')}, /* Czech */
- {HB_TAG('c','u',' ',' '), HB_TAG('C','S','L',' ')}, /* Church Slavonic */
- {HB_TAG('c','v',' ',' '), HB_TAG('C','H','U',' ')}, /* Chuvash */
- {HB_TAG('c','y',' ',' '), HB_TAG('W','E','L',' ')}, /* Welsh */
- {HB_TAG('d','a',' ',' '), HB_TAG('D','A','N',' ')}, /* Danish */
- {HB_TAG('d','e',' ',' '), HB_TAG('D','E','U',' ')}, /* German */
- {HB_TAG('d','v',' ',' '), HB_TAG('D','I','V',' ')}, /* Divehi (Dhivehi, Maldivian) */
- {HB_TAG('d','v',' ',' '), HB_TAG('D','H','V',' ')}, /* Divehi (Dhivehi, Maldivian) (deprecated) */
- {HB_TAG('d','z',' ',' '), HB_TAG('D','Z','N',' ')}, /* Dzongkha */
- {HB_TAG('e','e',' ',' '), HB_TAG('E','W','E',' ')}, /* Ewe */
- {HB_TAG('e','l',' ',' '), HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) -> Greek */
- {HB_TAG('e','n',' ',' '), HB_TAG('E','N','G',' ')}, /* English */
- {HB_TAG('e','o',' ',' '), HB_TAG('N','T','O',' ')}, /* Esperanto */
- {HB_TAG('e','s',' ',' '), HB_TAG('E','S','P',' ')}, /* Spanish */
- {HB_TAG('e','t',' ',' '), HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
- {HB_TAG('e','u',' ',' '), HB_TAG('E','U','Q',' ')}, /* Basque */
- {HB_TAG('f','a',' ',' '), HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
- {HB_TAG('f','f',' ',' '), HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
- {HB_TAG('f','i',' ',' '), HB_TAG('F','I','N',' ')}, /* Finnish */
- {HB_TAG('f','j',' ',' '), HB_TAG('F','J','I',' ')}, /* Fijian */
- {HB_TAG('f','o',' ',' '), HB_TAG('F','O','S',' ')}, /* Faroese */
- {HB_TAG('f','r',' ',' '), HB_TAG('F','R','A',' ')}, /* French */
- {HB_TAG('f','y',' ',' '), HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */
- {HB_TAG('g','a',' ',' '), HB_TAG('I','R','I',' ')}, /* Irish */
- {HB_TAG('g','d',' ',' '), HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */
- {HB_TAG('g','l',' ',' '), HB_TAG('G','A','L',' ')}, /* Galician */
- {HB_TAG('g','n',' ',' '), HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
- {HB_TAG('g','u',' ',' '), HB_TAG('G','U','J',' ')}, /* Gujarati */
- {HB_TAG('g','v',' ',' '), HB_TAG('M','N','X',' ')}, /* Manx */
- {HB_TAG('h','a',' ',' '), HB_TAG('H','A','U',' ')}, /* Hausa */
- {HB_TAG('h','e',' ',' '), HB_TAG('I','W','R',' ')}, /* Hebrew */
- {HB_TAG('h','i',' ',' '), HB_TAG('H','I','N',' ')}, /* Hindi */
- {HB_TAG('h','o',' ',' '), HB_TAG('H','M','O',' ')}, /* Hiri Motu */
- {HB_TAG('h','o',' ',' '), HB_TAG('C','P','P',' ')}, /* Hiri Motu -> Creoles */
- {HB_TAG('h','r',' ',' '), HB_TAG('H','R','V',' ')}, /* Croatian */
- {HB_TAG('h','t',' ',' '), HB_TAG('H','A','I',' ')}, /* Haitian (Haitian Creole) */
- {HB_TAG('h','t',' ',' '), HB_TAG('C','P','P',' ')}, /* Haitian -> Creoles */
- {HB_TAG('h','u',' ',' '), HB_TAG('H','U','N',' ')}, /* Hungarian */
- {HB_TAG('h','y',' ',' '), HB_TAG('H','Y','E','0')}, /* Armenian -> Armenian East */
- {HB_TAG('h','y',' ',' '), HB_TAG('H','Y','E',' ')}, /* Armenian */
- {HB_TAG('h','z',' ',' '), HB_TAG('H','E','R',' ')}, /* Herero */
- {HB_TAG('i','a',' ',' '), HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
- {HB_TAG('i','d',' ',' '), HB_TAG('I','N','D',' ')}, /* Indonesian */
- {HB_TAG('i','d',' ',' '), HB_TAG('M','L','Y',' ')}, /* Indonesian -> Malay */
- {HB_TAG('i','e',' ',' '), HB_TAG('I','L','E',' ')}, /* Interlingue */
- {HB_TAG('i','g',' ',' '), HB_TAG('I','B','O',' ')}, /* Igbo */
- {HB_TAG('i','i',' ',' '), HB_TAG('Y','I','M',' ')}, /* Sichuan Yi -> Yi Modern */
- {HB_TAG('i','k',' ',' '), HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */
- {HB_TAG('i','n',' ',' '), HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */
- {HB_TAG('i','n',' ',' '), HB_TAG('M','L','Y',' ')}, /* Indonesian (retired code) -> Malay */
- {HB_TAG('i','o',' ',' '), HB_TAG('I','D','O',' ')}, /* Ido */
- {HB_TAG('i','s',' ',' '), HB_TAG('I','S','L',' ')}, /* Icelandic */
- {HB_TAG('i','t',' ',' '), HB_TAG('I','T','A',' ')}, /* Italian */
- {HB_TAG('i','u',' ',' '), HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
- {HB_TAG('i','u',' ',' '), HB_TAG('I','N','U','K')}, /* Inuktitut [macrolanguage] -> Nunavik Inuktitut */
- {HB_TAG('i','w',' ',' '), HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */
- {HB_TAG('j','a',' ',' '), HB_TAG('J','A','N',' ')}, /* Japanese */
- {HB_TAG('j','i',' ',' '), HB_TAG('J','I','I',' ')}, /* Yiddish (retired code) */
- {HB_TAG('j','v',' ',' '), HB_TAG('J','A','V',' ')}, /* Javanese */
- {HB_TAG('j','w',' ',' '), HB_TAG('J','A','V',' ')}, /* Javanese (retired code) */
- {HB_TAG('k','a',' ',' '), HB_TAG('K','A','T',' ')}, /* Georgian */
- {HB_TAG('k','g',' ',' '), HB_TAG('K','O','N','0')}, /* Kongo [macrolanguage] */
- {HB_TAG('k','i',' ',' '), HB_TAG('K','I','K',' ')}, /* Kikuyu (Gikuyu) */
- {HB_TAG('k','j',' ',' '), HB_TAG('K','U','A',' ')}, /* Kuanyama */
- {HB_TAG('k','k',' ',' '), HB_TAG('K','A','Z',' ')}, /* Kazakh */
- {HB_TAG('k','l',' ',' '), HB_TAG('G','R','N',' ')}, /* Greenlandic */
- {HB_TAG('k','m',' ',' '), HB_TAG('K','H','M',' ')}, /* Khmer */
- {HB_TAG('k','n',' ',' '), HB_TAG('K','A','N',' ')}, /* Kannada */
- {HB_TAG('k','o',' ',' '), HB_TAG('K','O','R',' ')}, /* Korean */
- {HB_TAG('k','o',' ',' '), HB_TAG('K','O','H',' ')}, /* Korean -> Korean Old Hangul */
- {HB_TAG('k','r',' ',' '), HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
- {HB_TAG('k','s',' ',' '), HB_TAG('K','S','H',' ')}, /* Kashmiri */
- {HB_TAG('k','u',' ',' '), HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
- {HB_TAG('k','v',' ',' '), HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
- {HB_TAG('k','w',' ',' '), HB_TAG('C','O','R',' ')}, /* Cornish */
- {HB_TAG('k','y',' ',' '), HB_TAG('K','I','R',' ')}, /* Kirghiz (Kyrgyz) */
- {HB_TAG('l','a',' ',' '), HB_TAG('L','A','T',' ')}, /* Latin */
- {HB_TAG('l','b',' ',' '), HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
- {HB_TAG('l','g',' ',' '), HB_TAG('L','U','G',' ')}, /* Ganda */
- {HB_TAG('l','i',' ',' '), HB_TAG('L','I','M',' ')}, /* Limburgish */
- {HB_TAG('l','n',' ',' '), HB_TAG('L','I','N',' ')}, /* Lingala */
- {HB_TAG('l','o',' ',' '), HB_TAG('L','A','O',' ')}, /* Lao */
- {HB_TAG('l','t',' ',' '), HB_TAG('L','T','H',' ')}, /* Lithuanian */
- {HB_TAG('l','u',' ',' '), HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
- {HB_TAG('l','v',' ',' '), HB_TAG('L','V','I',' ')}, /* Latvian [macrolanguage] */
- {HB_TAG('m','g',' ',' '), HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
- {HB_TAG('m','h',' ',' '), HB_TAG('M','A','H',' ')}, /* Marshallese */
- {HB_TAG('m','i',' ',' '), HB_TAG('M','R','I',' ')}, /* Maori */
- {HB_TAG('m','k',' ',' '), HB_TAG('M','K','D',' ')}, /* Macedonian */
- {HB_TAG('m','l',' ',' '), HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */
- {HB_TAG('m','l',' ',' '), HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */
- {HB_TAG('m','n',' ',' '), HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
- {HB_TAG('m','o',' ',' '), HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */
- {HB_TAG('m','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Moldavian (retired code) -> Romanian */
- {HB_TAG('m','r',' ',' '), HB_TAG('M','A','R',' ')}, /* Marathi */
- {HB_TAG('m','s',' ',' '), HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
- {HB_TAG('m','t',' ',' '), HB_TAG('M','T','S',' ')}, /* Maltese */
- {HB_TAG('m','y',' ',' '), HB_TAG('B','R','M',' ')}, /* Burmese */
- {HB_TAG('n','a',' ',' '), HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */
- {HB_TAG('n','b',' ',' '), HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål -> Norwegian */
- {HB_TAG('n','d',' ',' '), HB_TAG('N','D','B',' ')}, /* North Ndebele -> Ndebele */
- {HB_TAG('n','e',' ',' '), HB_TAG('N','E','P',' ')}, /* Nepali [macrolanguage] */
- {HB_TAG('n','g',' ',' '), HB_TAG('N','D','G',' ')}, /* Ndonga */
- {HB_TAG('n','l',' ',' '), HB_TAG('N','L','D',' ')}, /* Dutch */
- {HB_TAG('n','n',' ',' '), HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */
- {HB_TAG('n','o',' ',' '), HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
- {HB_TAG('n','r',' ',' '), HB_TAG('N','D','B',' ')}, /* South Ndebele -> Ndebele */
- {HB_TAG('n','v',' ',' '), HB_TAG('N','A','V',' ')}, /* Navajo */
- {HB_TAG('n','v',' ',' '), HB_TAG('A','T','H',' ')}, /* Navajo -> Athapaskan */
- {HB_TAG('n','y',' ',' '), HB_TAG('C','H','I',' ')}, /* Chichewa (Chewa, Nyanja) */
- {HB_TAG('o','c',' ',' '), HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
- {HB_TAG('o','j',' ',' '), HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */
- {HB_TAG('o','m',' ',' '), HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
- {HB_TAG('o','r',' ',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */
- {HB_TAG('o','s',' ',' '), HB_TAG('O','S','S',' ')}, /* Ossetian */
- {HB_TAG('p','a',' ',' '), HB_TAG('P','A','N',' ')}, /* Punjabi */
- {HB_TAG('p','i',' ',' '), HB_TAG('P','A','L',' ')}, /* Pali */
- {HB_TAG('p','l',' ',' '), HB_TAG('P','L','K',' ')}, /* Polish */
- {HB_TAG('p','s',' ',' '), HB_TAG('P','A','S',' ')}, /* Pashto [macrolanguage] */
- {HB_TAG('p','t',' ',' '), HB_TAG('P','T','G',' ')}, /* Portuguese */
- {HB_TAG('q','u',' ',' '), HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
- {HB_TAG('r','m',' ',' '), HB_TAG('R','M','S',' ')}, /* Romansh */
- {HB_TAG('r','n',' ',' '), HB_TAG('R','U','N',' ')}, /* Rundi */
- {HB_TAG('r','o',' ',' '), HB_TAG('R','O','M',' ')}, /* Romanian */
- {HB_TAG('r','u',' ',' '), HB_TAG('R','U','S',' ')}, /* Russian */
- {HB_TAG('r','w',' ',' '), HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
- {HB_TAG('s','a',' ',' '), HB_TAG('S','A','N',' ')}, /* Sanskrit */
- {HB_TAG('s','c',' ',' '), HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
- {HB_TAG('s','d',' ',' '), HB_TAG('S','N','D',' ')}, /* Sindhi */
- {HB_TAG('s','e',' ',' '), HB_TAG('N','S','M',' ')}, /* Northern Sami */
- {HB_TAG('s','g',' ',' '), HB_TAG('S','G','O',' ')}, /* Sango */
- {HB_TAG('s','h',' ',' '), HB_TAG('B','O','S',' ')}, /* Serbo-Croatian [macrolanguage] -> Bosnian */
- {HB_TAG('s','h',' ',' '), HB_TAG('H','R','V',' ')}, /* Serbo-Croatian [macrolanguage] -> Croatian */
- {HB_TAG('s','h',' ',' '), HB_TAG('S','R','B',' ')}, /* Serbo-Croatian [macrolanguage] -> Serbian */
- {HB_TAG('s','i',' ',' '), HB_TAG('S','N','H',' ')}, /* Sinhala (Sinhalese) */
- {HB_TAG('s','k',' ',' '), HB_TAG('S','K','Y',' ')}, /* Slovak */
- {HB_TAG('s','l',' ',' '), HB_TAG('S','L','V',' ')}, /* Slovenian */
- {HB_TAG('s','m',' ',' '), HB_TAG('S','M','O',' ')}, /* Samoan */
- {HB_TAG('s','n',' ',' '), HB_TAG('S','N','A','0')}, /* Shona */
- {HB_TAG('s','o',' ',' '), HB_TAG('S','M','L',' ')}, /* Somali */
- {HB_TAG('s','q',' ',' '), HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
- {HB_TAG('s','r',' ',' '), HB_TAG('S','R','B',' ')}, /* Serbian */
- {HB_TAG('s','s',' ',' '), HB_TAG('S','W','Z',' ')}, /* Swati */
- {HB_TAG('s','t',' ',' '), HB_TAG('S','O','T',' ')}, /* Southern Sotho */
- {HB_TAG('s','u',' ',' '), HB_TAG('S','U','N',' ')}, /* Sundanese */
- {HB_TAG('s','v',' ',' '), HB_TAG('S','V','E',' ')}, /* Swedish */
- {HB_TAG('s','w',' ',' '), HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
- {HB_TAG('t','a',' ',' '), HB_TAG('T','A','M',' ')}, /* Tamil */
- {HB_TAG('t','e',' ',' '), HB_TAG('T','E','L',' ')}, /* Telugu */
- {HB_TAG('t','g',' ',' '), HB_TAG('T','A','J',' ')}, /* Tajik -> Tajiki */
- {HB_TAG('t','h',' ',' '), HB_TAG('T','H','A',' ')}, /* Thai */
- {HB_TAG('t','i',' ',' '), HB_TAG('T','G','Y',' ')}, /* Tigrinya */
- {HB_TAG('t','k',' ',' '), HB_TAG('T','K','M',' ')}, /* Turkmen */
- {HB_TAG('t','l',' ',' '), HB_TAG('T','G','L',' ')}, /* Tagalog */
- {HB_TAG('t','n',' ',' '), HB_TAG('T','N','A',' ')}, /* Tswana */
- {HB_TAG('t','o',' ',' '), HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) -> Tongan */
- {HB_TAG('t','r',' ',' '), HB_TAG('T','R','K',' ')}, /* Turkish */
- {HB_TAG('t','s',' ',' '), HB_TAG('T','S','G',' ')}, /* Tsonga */
- {HB_TAG('t','t',' ',' '), HB_TAG('T','A','T',' ')}, /* Tatar */
- {HB_TAG('t','w',' ',' '), HB_TAG('T','W','I',' ')}, /* Twi */
- {HB_TAG('t','w',' ',' '), HB_TAG('A','K','A',' ')}, /* Twi -> Akan */
- {HB_TAG('t','y',' ',' '), HB_TAG('T','H','T',' ')}, /* Tahitian */
- {HB_TAG('u','g',' ',' '), HB_TAG('U','Y','G',' ')}, /* Uyghur */
- {HB_TAG('u','k',' ',' '), HB_TAG('U','K','R',' ')}, /* Ukrainian */
- {HB_TAG('u','r',' ',' '), HB_TAG('U','R','D',' ')}, /* Urdu */
- {HB_TAG('u','z',' ',' '), HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
- {HB_TAG('v','e',' ',' '), HB_TAG('V','E','N',' ')}, /* Venda */
- {HB_TAG('v','i',' ',' '), HB_TAG('V','I','T',' ')}, /* Vietnamese */
- {HB_TAG('v','o',' ',' '), HB_TAG('V','O','L',' ')}, /* Volapük */
- {HB_TAG('w','a',' ',' '), HB_TAG('W','L','N',' ')}, /* Walloon */
- {HB_TAG('w','o',' ',' '), HB_TAG('W','L','F',' ')}, /* Wolof */
- {HB_TAG('x','h',' ',' '), HB_TAG('X','H','S',' ')}, /* Xhosa */
- {HB_TAG('y','i',' ',' '), HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
- {HB_TAG('y','o',' ',' '), HB_TAG('Y','B','A',' ')}, /* Yoruba */
- {HB_TAG('z','a',' ',' '), HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */
- {HB_TAG('z','h',' ',' '), HB_TAG('Z','H','S',' ')}, /* Chinese, Simplified [macrolanguage] */
- {HB_TAG('z','u',' ',' '), HB_TAG('Z','U','L',' ')}, /* Zulu */
-};
-
-#ifndef HB_NO_LANGUAGE_LONG
-static const LangTag ot_languages3[] = {
- {HB_TAG('a','a','e',' '), HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */
- {HB_TAG('a','a','o',' '), HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */
- {HB_TAG('a','a','t',' '), HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */
- {HB_TAG('a','b','a',' '), HB_TAG_NONE }, /* Abé != Abaza */
- {HB_TAG('a','b','h',' '), HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */
- {HB_TAG('a','b','q',' '), HB_TAG('A','B','A',' ')}, /* Abaza */
- {HB_TAG('a','b','s',' '), HB_TAG('C','P','P',' ')}, /* Ambonese Malay -> Creoles */
- {HB_TAG('a','b','v',' '), HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */
- {HB_TAG('a','c','f',' '), HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */
- {HB_TAG('a','c','f',' '), HB_TAG('C','P','P',' ')}, /* Saint Lucian Creole French -> Creoles */
-/*{HB_TAG('a','c','h',' '), HB_TAG('A','C','H',' ')},*/ /* Acoli -> Acholi */
- {HB_TAG('a','c','m',' '), HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */
- {HB_TAG('a','c','q',' '), HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */
- {HB_TAG('a','c','r',' '), HB_TAG('A','C','R',' ')}, /* Achi */
- {HB_TAG('a','c','r',' '), HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */
- {HB_TAG('a','c','w',' '), HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */
- {HB_TAG('a','c','x',' '), HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */
- {HB_TAG('a','c','y',' '), HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */
- {HB_TAG('a','d','a',' '), HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */
- {HB_TAG('a','d','f',' '), HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */
- {HB_TAG('a','d','p',' '), HB_TAG('D','Z','N',' ')}, /* Adap (retired code) -> Dzongkha */
-/*{HB_TAG('a','d','y',' '), HB_TAG('A','D','Y',' ')},*/ /* Adyghe */
- {HB_TAG('a','e','b',' '), HB_TAG('A','R','A',' ')}, /* Tunisian Arabic -> Arabic */
- {HB_TAG('a','e','c',' '), HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */
- {HB_TAG('a','f','b',' '), HB_TAG('A','R','A',' ')}, /* Gulf Arabic -> Arabic */
- {HB_TAG('a','f','k',' '), HB_TAG_NONE }, /* Nanubae != Afrikaans */
- {HB_TAG('a','f','s',' '), HB_TAG('C','P','P',' ')}, /* Afro-Seminole Creole -> Creoles */
- {HB_TAG('a','g','u',' '), HB_TAG('M','Y','N',' ')}, /* Aguacateco -> Mayan */
- {HB_TAG('a','g','w',' '), HB_TAG_NONE }, /* Kahua != Agaw */
- {HB_TAG('a','h','g',' '), HB_TAG('A','G','W',' ')}, /* Qimant -> Agaw */
- {HB_TAG('a','h','t',' '), HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */
- {HB_TAG('a','i','g',' '), HB_TAG('C','P','P',' ')}, /* Antigua and Barbuda Creole English -> Creoles */
- {HB_TAG('a','i','i',' '), HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */
- {HB_TAG('a','i','i',' '), HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */
-/*{HB_TAG('a','i','o',' '), HB_TAG('A','I','O',' ')},*/ /* Aiton */
- {HB_TAG('a','i','w',' '), HB_TAG('A','R','I',' ')}, /* Aari */
- {HB_TAG('a','j','p',' '), HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */
- {HB_TAG('a','j','t',' '), HB_TAG('A','R','A',' ')}, /* Judeo-Tunisian Arabic (retired code) -> Arabic */
- {HB_TAG('a','k','b',' '), HB_TAG('A','K','B',' ')}, /* Batak Angkola */
- {HB_TAG('a','k','b',' '), HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */
- {HB_TAG('a','l','n',' '), HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */
- {HB_TAG('a','l','s',' '), HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */
-/*{HB_TAG('a','l','t',' '), HB_TAG('A','L','T',' ')},*/ /* Southern Altai -> Altai */
- {HB_TAG('a','m','f',' '), HB_TAG('H','B','N',' ')}, /* Hamer-Banna -> Hammer-Banna */
- {HB_TAG('a','m','w',' '), HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */
-/*{HB_TAG('a','n','g',' '), HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
- {HB_TAG('a','o','a',' '), HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */
- {HB_TAG('a','p','a',' '), HB_TAG('A','T','H',' ')}, /* Apache [collection] -> Athapaskan */
- {HB_TAG('a','p','c',' '), HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */
- {HB_TAG('a','p','d',' '), HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */
- {HB_TAG('a','p','j',' '), HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */
- {HB_TAG('a','p','k',' '), HB_TAG('A','T','H',' ')}, /* Kiowa Apache -> Athapaskan */
- {HB_TAG('a','p','l',' '), HB_TAG('A','T','H',' ')}, /* Lipan Apache -> Athapaskan */
- {HB_TAG('a','p','m',' '), HB_TAG('A','T','H',' ')}, /* Mescalero-Chiricahua Apache -> Athapaskan */
- {HB_TAG('a','p','w',' '), HB_TAG('A','T','H',' ')}, /* Western Apache -> Athapaskan */
- {HB_TAG('a','r','b',' '), HB_TAG('A','R','A',' ')}, /* Standard Arabic -> Arabic */
- {HB_TAG('a','r','i',' '), HB_TAG_NONE }, /* Arikara != Aari */
- {HB_TAG('a','r','k',' '), HB_TAG_NONE }, /* Arikapú != Rakhine */
- {HB_TAG('a','r','n',' '), HB_TAG('M','A','P',' ')}, /* Mapudungun */
- {HB_TAG('a','r','q',' '), HB_TAG('A','R','A',' ')}, /* Algerian Arabic -> Arabic */
- {HB_TAG('a','r','s',' '), HB_TAG('A','R','A',' ')}, /* Najdi Arabic -> Arabic */
- {HB_TAG('a','r','y',' '), HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */
- {HB_TAG('a','r','y',' '), HB_TAG('A','R','A',' ')}, /* Moroccan Arabic -> Arabic */
- {HB_TAG('a','r','z',' '), HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */
-/*{HB_TAG('a','s','t',' '), HB_TAG('A','S','T',' ')},*/ /* Asturian */
-/*{HB_TAG('a','t','h',' '), HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */
- {HB_TAG('a','t','j',' '), HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */
- {HB_TAG('a','t','v',' '), HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */
- {HB_TAG('a','u','j',' '), HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */
- {HB_TAG('a','u','z',' '), HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */
- {HB_TAG('a','v','l',' '), HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */
-/*{HB_TAG('a','v','n',' '), HB_TAG('A','V','N',' ')},*/ /* Avatime */
-/*{HB_TAG('a','w','a',' '), HB_TAG('A','W','A',' ')},*/ /* Awadhi */
- {HB_TAG('a','y','c',' '), HB_TAG('A','Y','M',' ')}, /* Southern Aymara -> Aymara */
- {HB_TAG('a','y','h',' '), HB_TAG('A','R','A',' ')}, /* Hadrami Arabic -> Arabic */
- {HB_TAG('a','y','l',' '), HB_TAG('A','R','A',' ')}, /* Libyan Arabic -> Arabic */
- {HB_TAG('a','y','n',' '), HB_TAG('A','R','A',' ')}, /* Sanaani Arabic -> Arabic */
- {HB_TAG('a','y','p',' '), HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */
- {HB_TAG('a','y','r',' '), HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */
- {HB_TAG('a','z','b',' '), HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */
- {HB_TAG('a','z','b',' '), HB_TAG('A','Z','E',' ')}, /* South Azerbaijani -> Azerbaijani */
- {HB_TAG('a','z','d',' '), HB_TAG('N','A','H',' ')}, /* Eastern Durango Nahuatl -> Nahuatl */
- {HB_TAG('a','z','j',' '), HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */
- {HB_TAG('a','z','n',' '), HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */
- {HB_TAG('a','z','z',' '), HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */
- {HB_TAG('b','a','d',' '), HB_TAG('B','A','D','0')}, /* Banda [collection] */
- {HB_TAG('b','a','g',' '), HB_TAG_NONE }, /* Tuki != Baghelkhandi */
- {HB_TAG('b','a','h',' '), HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */
- {HB_TAG('b','a','i',' '), HB_TAG('B','M','L',' ')}, /* Bamileke [collection] */
- {HB_TAG('b','a','l',' '), HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */
-/*{HB_TAG('b','a','n',' '), HB_TAG('B','A','N',' ')},*/ /* Balinese */
-/*{HB_TAG('b','a','r',' '), HB_TAG('B','A','R',' ')},*/ /* Bavarian */
- {HB_TAG('b','a','u',' '), HB_TAG_NONE }, /* Bada (Nigeria) != Baulé */
- {HB_TAG('b','b','c',' '), HB_TAG('B','B','C',' ')}, /* Batak Toba */
- {HB_TAG('b','b','c',' '), HB_TAG('B','T','K',' ')}, /* Batak Toba -> Batak */
- {HB_TAG('b','b','j',' '), HB_TAG('B','M','L',' ')}, /* Ghomálá' -> Bamileke */
- {HB_TAG('b','b','p',' '), HB_TAG('B','A','D','0')}, /* West Central Banda -> Banda */
- {HB_TAG('b','b','r',' '), HB_TAG_NONE }, /* Girawa != Berber */
- {HB_TAG('b','b','z',' '), HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic (retired code) -> Arabic */
- {HB_TAG('b','c','c',' '), HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */
- {HB_TAG('b','c','h',' '), HB_TAG_NONE }, /* Bariai != Bench */
- {HB_TAG('b','c','i',' '), HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */
- {HB_TAG('b','c','l',' '), HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */
- {HB_TAG('b','c','q',' '), HB_TAG('B','C','H',' ')}, /* Bench */
- {HB_TAG('b','c','r',' '), HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */
-/*{HB_TAG('b','d','y',' '), HB_TAG('B','D','Y',' ')},*/ /* Bandjalang */
- {HB_TAG('b','e','a',' '), HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */
- {HB_TAG('b','e','b',' '), HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */
-/*{HB_TAG('b','e','m',' '), HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */
- {HB_TAG('b','e','r',' '), HB_TAG('B','B','R',' ')}, /* Berber [collection] */
- {HB_TAG('b','e','w',' '), HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */
- {HB_TAG('b','f','l',' '), HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */
- {HB_TAG('b','f','q',' '), HB_TAG('B','A','D',' ')}, /* Badaga */
- {HB_TAG('b','f','t',' '), HB_TAG('B','L','T',' ')}, /* Balti */
- {HB_TAG('b','f','u',' '), HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */
- {HB_TAG('b','f','y',' '), HB_TAG('B','A','G',' ')}, /* Bagheli -> Baghelkhandi */
-/*{HB_TAG('b','g','c',' '), HB_TAG('B','G','C',' ')},*/ /* Haryanvi */
- {HB_TAG('b','g','n',' '), HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */
- {HB_TAG('b','g','p',' '), HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */
- {HB_TAG('b','g','q',' '), HB_TAG('B','G','Q',' ')}, /* Bagri */
- {HB_TAG('b','g','q',' '), HB_TAG('R','A','J',' ')}, /* Bagri -> Rajasthani */
- {HB_TAG('b','g','r',' '), HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */
- {HB_TAG('b','h','b',' '), HB_TAG('B','H','I',' ')}, /* Bhili */
-/*{HB_TAG('b','h','i',' '), HB_TAG('B','H','I',' ')},*/ /* Bhilali -> Bhili */
- {HB_TAG('b','h','k',' '), HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) -> Bikol */
-/*{HB_TAG('b','h','o',' '), HB_TAG('B','H','O',' ')},*/ /* Bhojpuri */
- {HB_TAG('b','h','r',' '), HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */
-/*{HB_TAG('b','i','k',' '), HB_TAG('B','I','K',' ')},*/ /* Bikol [macrolanguage] */
- {HB_TAG('b','i','l',' '), HB_TAG_NONE }, /* Bile != Bilen */
- {HB_TAG('b','i','n',' '), HB_TAG('E','D','O',' ')}, /* Edo */
- {HB_TAG('b','i','u',' '), HB_TAG('Q','I','N',' ')}, /* Biete -> Chin */
-/*{HB_TAG('b','j','j',' '), HB_TAG('B','J','J',' ')},*/ /* Kanauji */
- {HB_TAG('b','j','n',' '), HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */
- {HB_TAG('b','j','o',' '), HB_TAG('B','A','D','0')}, /* Mid-Southern Banda -> Banda */
- {HB_TAG('b','j','q',' '), HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
- {HB_TAG('b','j','s',' '), HB_TAG('C','P','P',' ')}, /* Bajan -> Creoles */
- {HB_TAG('b','j','t',' '), HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */
- {HB_TAG('b','k','f',' '), HB_TAG_NONE }, /* Beeke != Blackfoot */
- {HB_TAG('b','k','o',' '), HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */
- {HB_TAG('b','l','a',' '), HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */
- {HB_TAG('b','l','e',' '), HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */
- {HB_TAG('b','l','g',' '), HB_TAG('I','B','A',' ')}, /* Balau (retired code) -> Iban */
- {HB_TAG('b','l','i',' '), HB_TAG_NONE }, /* Bolia != Baluchi */
- {HB_TAG('b','l','k',' '), HB_TAG('B','L','K',' ')}, /* Pa’o Karen */
- {HB_TAG('b','l','k',' '), HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */
- {HB_TAG('b','l','n',' '), HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */
- {HB_TAG('b','l','t',' '), HB_TAG_NONE }, /* Tai Dam != Balti */
- {HB_TAG('b','m','b',' '), HB_TAG_NONE }, /* Bembe != Bambara (Bamanankan) */
- {HB_TAG('b','m','l',' '), HB_TAG_NONE }, /* Bomboli != Bamileke */
- {HB_TAG('b','m','m',' '), HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */
- {HB_TAG('b','p','d',' '), HB_TAG('B','A','D','0')}, /* Banda-Banda -> Banda */
- {HB_TAG('b','p','l',' '), HB_TAG('C','P','P',' ')}, /* Broome Pearling Lugger Pidgin -> Creoles */
- {HB_TAG('b','p','q',' '), HB_TAG('C','P','P',' ')}, /* Banda Malay -> Creoles */
-/*{HB_TAG('b','p','y',' '), HB_TAG('B','P','Y',' ')},*/ /* Bishnupriya -> Bishnupriya Manipuri */
- {HB_TAG('b','q','i',' '), HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */
- {HB_TAG('b','q','k',' '), HB_TAG('B','A','D','0')}, /* Banda-Mbrès -> Banda */
- {HB_TAG('b','r','a',' '), HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */
- {HB_TAG('b','r','c',' '), HB_TAG('C','P','P',' ')}, /* Berbice Creole Dutch -> Creoles */
-/*{HB_TAG('b','r','h',' '), HB_TAG('B','R','H',' ')},*/ /* Brahui */
- {HB_TAG('b','r','i',' '), HB_TAG_NONE }, /* Mokpwe != Braj Bhasha */
- {HB_TAG('b','r','m',' '), HB_TAG_NONE }, /* Barambu != Burmese */
-/*{HB_TAG('b','r','x',' '), HB_TAG('B','R','X',' ')},*/ /* Bodo (India) */
- {HB_TAG('b','s','h',' '), HB_TAG_NONE }, /* Kati != Bashkir */
-/*{HB_TAG('b','s','k',' '), HB_TAG('B','S','K',' ')},*/ /* Burushaski */
- {HB_TAG('b','t','b',' '), HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */
- {HB_TAG('b','t','d',' '), HB_TAG('B','T','D',' ')}, /* Batak Dairi (Pakpak) */
- {HB_TAG('b','t','d',' '), HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */
- {HB_TAG('b','t','i',' '), HB_TAG_NONE }, /* Burate != Beti */
- {HB_TAG('b','t','j',' '), HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */
-/*{HB_TAG('b','t','k',' '), HB_TAG('B','T','K',' ')},*/ /* Batak [collection] */
- {HB_TAG('b','t','m',' '), HB_TAG('B','T','M',' ')}, /* Batak Mandailing */
- {HB_TAG('b','t','m',' '), HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */
- {HB_TAG('b','t','o',' '), HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */
- {HB_TAG('b','t','s',' '), HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
- {HB_TAG('b','t','s',' '), HB_TAG('B','T','K',' ')}, /* Batak Simalungun -> Batak */
- {HB_TAG('b','t','x',' '), HB_TAG('B','T','X',' ')}, /* Batak Karo */
- {HB_TAG('b','t','x',' '), HB_TAG('B','T','K',' ')}, /* Batak Karo -> Batak */
- {HB_TAG('b','t','z',' '), HB_TAG('B','T','Z',' ')}, /* Batak Alas-Kluet */
- {HB_TAG('b','t','z',' '), HB_TAG('B','T','K',' ')}, /* Batak Alas-Kluet -> Batak */
-/*{HB_TAG('b','u','g',' '), HB_TAG('B','U','G',' ')},*/ /* Buginese -> Bugis */
- {HB_TAG('b','u','m',' '), HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */
- {HB_TAG('b','v','e',' '), HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */
- {HB_TAG('b','v','u',' '), HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */
- {HB_TAG('b','w','e',' '), HB_TAG('K','R','N',' ')}, /* Bwe Karen -> Karen */
- {HB_TAG('b','x','k',' '), HB_TAG('L','U','H',' ')}, /* Bukusu -> Luyia */
- {HB_TAG('b','x','o',' '), HB_TAG('C','P','P',' ')}, /* Barikanchi -> Creoles */
- {HB_TAG('b','x','p',' '), HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */
- {HB_TAG('b','x','r',' '), HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */
- {HB_TAG('b','y','n',' '), HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */
- {HB_TAG('b','y','v',' '), HB_TAG('B','Y','V',' ')}, /* Medumba */
- {HB_TAG('b','y','v',' '), HB_TAG('B','M','L',' ')}, /* Medumba -> Bamileke */
- {HB_TAG('b','z','c',' '), HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */
- {HB_TAG('b','z','j',' '), HB_TAG('C','P','P',' ')}, /* Belize Kriol English -> Creoles */
- {HB_TAG('b','z','k',' '), HB_TAG('C','P','P',' ')}, /* Nicaragua Creole English -> Creoles */
- {HB_TAG('c','a','a',' '), HB_TAG('M','Y','N',' ')}, /* Chortí -> Mayan */
- {HB_TAG('c','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Chuj -> Mayan */
- {HB_TAG('c','a','f',' '), HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */
- {HB_TAG('c','a','f',' '), HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */
- {HB_TAG('c','a','k',' '), HB_TAG('C','A','K',' ')}, /* Kaqchikel */
- {HB_TAG('c','a','k',' '), HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */
- {HB_TAG('c','b','k',' '), HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */
- {HB_TAG('c','b','k',' '), HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */
- {HB_TAG('c','b','l',' '), HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */
- {HB_TAG('c','c','l',' '), HB_TAG('C','P','P',' ')}, /* Cutchi-Swahili -> Creoles */
- {HB_TAG('c','c','m',' '), HB_TAG('C','P','P',' ')}, /* Malaccan Creole Malay -> Creoles */
- {HB_TAG('c','c','o',' '), HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */
- {HB_TAG('c','c','q',' '), HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */
- {HB_TAG('c','d','o',' '), HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese, Simplified */
-/*{HB_TAG('c','e','b',' '), HB_TAG('C','E','B',' ')},*/ /* Cebuano */
- {HB_TAG('c','e','k',' '), HB_TAG('Q','I','N',' ')}, /* Eastern Khumi Chin -> Chin */
- {HB_TAG('c','e','y',' '), HB_TAG('Q','I','N',' ')}, /* Ekai Chin -> Chin */
- {HB_TAG('c','f','m',' '), HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */
- {HB_TAG('c','f','m',' '), HB_TAG('Q','I','N',' ')}, /* Falam Chin -> Chin */
-/*{HB_TAG('c','g','g',' '), HB_TAG('C','G','G',' ')},*/ /* Chiga */
- {HB_TAG('c','h','f',' '), HB_TAG('M','Y','N',' ')}, /* Tabasco Chontal -> Mayan */
- {HB_TAG('c','h','g',' '), HB_TAG_NONE }, /* Chagatai != Chaha Gurage */
- {HB_TAG('c','h','h',' '), HB_TAG_NONE }, /* Chinook != Chattisgarhi */
- {HB_TAG('c','h','j',' '), HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */
- {HB_TAG('c','h','k',' '), HB_TAG('C','H','K','0')}, /* Chuukese */
- {HB_TAG('c','h','m',' '), HB_TAG('H','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> High Mari */
- {HB_TAG('c','h','m',' '), HB_TAG('L','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> Low Mari */
- {HB_TAG('c','h','n',' '), HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */
-/*{HB_TAG('c','h','o',' '), HB_TAG('C','H','O',' ')},*/ /* Choctaw */
- {HB_TAG('c','h','p',' '), HB_TAG('C','H','P',' ')}, /* Chipewyan */
- {HB_TAG('c','h','p',' '), HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */
- {HB_TAG('c','h','p',' '), HB_TAG('A','T','H',' ')}, /* Chipewyan -> Athapaskan */
- {HB_TAG('c','h','q',' '), HB_TAG('C','C','H','N')}, /* Quiotepec Chinantec -> Chinantec */
-/*{HB_TAG('c','h','r',' '), HB_TAG('C','H','R',' ')},*/ /* Cherokee */
-/*{HB_TAG('c','h','y',' '), HB_TAG('C','H','Y',' ')},*/ /* Cheyenne */
- {HB_TAG('c','h','z',' '), HB_TAG('C','C','H','N')}, /* Ozumacín Chinantec -> Chinantec */
- {HB_TAG('c','i','w',' '), HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */
-/*{HB_TAG('c','j','a',' '), HB_TAG('C','J','A',' ')},*/ /* Western Cham */
-/*{HB_TAG('c','j','m',' '), HB_TAG('C','J','M',' ')},*/ /* Eastern Cham */
- {HB_TAG('c','j','y',' '), HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese, Simplified */
- {HB_TAG('c','k','a',' '), HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */
- {HB_TAG('c','k','b',' '), HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */
- {HB_TAG('c','k','n',' '), HB_TAG('Q','I','N',' ')}, /* Kaang Chin -> Chin */
- {HB_TAG('c','k','s',' '), HB_TAG('C','P','P',' ')}, /* Tayo -> Creoles */
- {HB_TAG('c','k','t',' '), HB_TAG('C','H','K',' ')}, /* Chukot -> Chukchi */
- {HB_TAG('c','k','z',' '), HB_TAG('M','Y','N',' ')}, /* Cakchiquel-Quiché Mixed Language -> Mayan */
- {HB_TAG('c','l','c',' '), HB_TAG('A','T','H',' ')}, /* Chilcotin -> Athapaskan */
- {HB_TAG('c','l','d',' '), HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */
- {HB_TAG('c','l','e',' '), HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */
- {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */
- {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */
- {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */
- {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */
- {HB_TAG('c','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */
- {HB_TAG('c','n','h',' '), HB_TAG('Q','I','N',' ')}, /* Hakha Chin -> Chin */
- {HB_TAG('c','n','k',' '), HB_TAG('Q','I','N',' ')}, /* Khumi Chin -> Chin */
- {HB_TAG('c','n','l',' '), HB_TAG('C','C','H','N')}, /* Lalana Chinantec -> Chinantec */
- {HB_TAG('c','n','p',' '), HB_TAG('Z','H','S',' ')}, /* Northern Ping Chinese -> Chinese, Simplified */
- {HB_TAG('c','n','r',' '), HB_TAG('S','R','B',' ')}, /* Montenegrin -> Serbian */
- {HB_TAG('c','n','t',' '), HB_TAG('C','C','H','N')}, /* Tepetotutla Chinantec -> Chinantec */
- {HB_TAG('c','n','u',' '), HB_TAG('B','B','R',' ')}, /* Chenoua -> Berber */
- {HB_TAG('c','n','w',' '), HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */
- {HB_TAG('c','o','a',' '), HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */
- {HB_TAG('c','o','b',' '), HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */
-/*{HB_TAG('c','o','p',' '), HB_TAG('C','O','P',' ')},*/ /* Coptic */
- {HB_TAG('c','o','q',' '), HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */
- {HB_TAG('c','p','a',' '), HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */
- {HB_TAG('c','p','e',' '), HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [collection] -> Creoles */
- {HB_TAG('c','p','f',' '), HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [collection] -> Creoles */
- {HB_TAG('c','p','i',' '), HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */
-/*{HB_TAG('c','p','p',' '), HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [collection] -> Creoles */
- {HB_TAG('c','p','x',' '), HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */
- {HB_TAG('c','q','d',' '), HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */
- {HB_TAG('c','q','u',' '), HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
- {HB_TAG('c','q','u',' '), HB_TAG('Q','U','Z',' ')}, /* Chilean Quechua (retired code) -> Quechua */
- {HB_TAG('c','r','h',' '), HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
- {HB_TAG('c','r','i',' '), HB_TAG('C','P','P',' ')}, /* Sãotomense -> Creoles */
- {HB_TAG('c','r','j',' '), HB_TAG('E','C','R',' ')}, /* Southern East Cree -> Eastern Cree */
- {HB_TAG('c','r','j',' '), HB_TAG('Y','C','R',' ')}, /* Southern East Cree -> Y-Cree */
- {HB_TAG('c','r','j',' '), HB_TAG('C','R','E',' ')}, /* Southern East Cree -> Cree */
- {HB_TAG('c','r','k',' '), HB_TAG('W','C','R',' ')}, /* Plains Cree -> West-Cree */
- {HB_TAG('c','r','k',' '), HB_TAG('Y','C','R',' ')}, /* Plains Cree -> Y-Cree */
- {HB_TAG('c','r','k',' '), HB_TAG('C','R','E',' ')}, /* Plains Cree -> Cree */
- {HB_TAG('c','r','l',' '), HB_TAG('E','C','R',' ')}, /* Northern East Cree -> Eastern Cree */
- {HB_TAG('c','r','l',' '), HB_TAG('Y','C','R',' ')}, /* Northern East Cree -> Y-Cree */
- {HB_TAG('c','r','l',' '), HB_TAG('C','R','E',' ')}, /* Northern East Cree -> Cree */
- {HB_TAG('c','r','m',' '), HB_TAG('M','C','R',' ')}, /* Moose Cree */
- {HB_TAG('c','r','m',' '), HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */
- {HB_TAG('c','r','m',' '), HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */
- {HB_TAG('c','r','p',' '), HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [collection] -> Creoles */
- {HB_TAG('c','r','r',' '), HB_TAG_NONE }, /* Carolina Algonquian != Carrier */
- {HB_TAG('c','r','s',' '), HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */
- {HB_TAG('c','r','t',' '), HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */
- {HB_TAG('c','r','x',' '), HB_TAG('C','R','R',' ')}, /* Carrier */
- {HB_TAG('c','r','x',' '), HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */
- {HB_TAG('c','s','a',' '), HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */
-/*{HB_TAG('c','s','b',' '), HB_TAG('C','S','B',' ')},*/ /* Kashubian */
- {HB_TAG('c','s','h',' '), HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */
- {HB_TAG('c','s','j',' '), HB_TAG('Q','I','N',' ')}, /* Songlai Chin -> Chin */
- {HB_TAG('c','s','l',' '), HB_TAG_NONE }, /* Chinese Sign Language != Church Slavonic */
- {HB_TAG('c','s','o',' '), HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */
- {HB_TAG('c','s','p',' '), HB_TAG('Z','H','S',' ')}, /* Southern Ping Chinese -> Chinese, Simplified */
- {HB_TAG('c','s','v',' '), HB_TAG('Q','I','N',' ')}, /* Sumtu Chin -> Chin */
- {HB_TAG('c','s','w',' '), HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */
- {HB_TAG('c','s','w',' '), HB_TAG('N','H','C',' ')}, /* Swampy Cree -> Norway House Cree */
- {HB_TAG('c','s','w',' '), HB_TAG('C','R','E',' ')}, /* Swampy Cree -> Cree */
- {HB_TAG('c','s','y',' '), HB_TAG('Q','I','N',' ')}, /* Siyin Chin -> Chin */
- {HB_TAG('c','t','c',' '), HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */
- {HB_TAG('c','t','d',' '), HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */
- {HB_TAG('c','t','e',' '), HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */
-/*{HB_TAG('c','t','g',' '), HB_TAG('C','T','G',' ')},*/ /* Chittagonian */
- {HB_TAG('c','t','h',' '), HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */
- {HB_TAG('c','t','l',' '), HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */
- {HB_TAG('c','t','s',' '), HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */
-/*{HB_TAG('c','t','t',' '), HB_TAG('C','T','T',' ')},*/ /* Wayanad Chetti */
- {HB_TAG('c','t','u',' '), HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */
- {HB_TAG('c','u','c',' '), HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */
-/*{HB_TAG('c','u','k',' '), HB_TAG('C','U','K',' ')},*/ /* San Blas Kuna */
- {HB_TAG('c','v','n',' '), HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */
- {HB_TAG('c','w','d',' '), HB_TAG('D','C','R',' ')}, /* Woods Cree */
- {HB_TAG('c','w','d',' '), HB_TAG('T','C','R',' ')}, /* Woods Cree -> TH-Cree */
- {HB_TAG('c','w','d',' '), HB_TAG('C','R','E',' ')}, /* Woods Cree -> Cree */
- {HB_TAG('c','z','h',' '), HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese, Simplified */
- {HB_TAG('c','z','o',' '), HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */
- {HB_TAG('c','z','t',' '), HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */
-/*{HB_TAG('d','a','g',' '), HB_TAG('D','A','G',' ')},*/ /* Dagbani */
- {HB_TAG('d','a','o',' '), HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */
- {HB_TAG('d','a','p',' '), HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */
-/*{HB_TAG('d','a','r',' '), HB_TAG('D','A','R',' ')},*/ /* Dargwa */
-/*{HB_TAG('d','a','x',' '), HB_TAG('D','A','X',' ')},*/ /* Dayi */
- {HB_TAG('d','c','r',' '), HB_TAG('C','P','P',' ')}, /* Negerhollands -> Creoles */
- {HB_TAG('d','e','n',' '), HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */
- {HB_TAG('d','e','n',' '), HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */
- {HB_TAG('d','e','p',' '), HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */
- {HB_TAG('d','g','o',' '), HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */
- {HB_TAG('d','g','o',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */
- {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */
- {HB_TAG('d','h','d',' '), HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */
-/*{HB_TAG('d','h','g',' '), HB_TAG('D','H','G',' ')},*/ /* Dhangu */
- {HB_TAG('d','h','v',' '), HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */
- {HB_TAG('d','i','b',' '), HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */
- {HB_TAG('d','i','k',' '), HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */
- {HB_TAG('d','i','n',' '), HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
- {HB_TAG('d','i','p',' '), HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */
- {HB_TAG('d','i','q',' '), HB_TAG('D','I','Q',' ')}, /* Dimli */
- {HB_TAG('d','i','q',' '), HB_TAG('Z','Z','A',' ')}, /* Dimli -> Zazaki */
- {HB_TAG('d','i','w',' '), HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */
- {HB_TAG('d','j','e',' '), HB_TAG('D','J','R',' ')}, /* Zarma */
- {HB_TAG('d','j','k',' '), HB_TAG('C','P','P',' ')}, /* Eastern Maroon Creole -> Creoles */
- {HB_TAG('d','j','r',' '), HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */
- {HB_TAG('d','k','s',' '), HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */
- {HB_TAG('d','n','g',' '), HB_TAG('D','U','N',' ')}, /* Dungan */
-/*{HB_TAG('d','n','j',' '), HB_TAG('D','N','J',' ')},*/ /* Dan */
- {HB_TAG('d','n','k',' '), HB_TAG_NONE }, /* Dengka != Dinka */
- {HB_TAG('d','o','i',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) [macrolanguage] */
- {HB_TAG('d','r','h',' '), HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */
- {HB_TAG('d','r','i',' '), HB_TAG_NONE }, /* C'Lela != Dari */
- {HB_TAG('d','r','w',' '), HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */
- {HB_TAG('d','r','w',' '), HB_TAG('F','A','R',' ')}, /* Darwazi (retired code) -> Persian */
- {HB_TAG('d','s','b',' '), HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
- {HB_TAG('d','t','y',' '), HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */
-/*{HB_TAG('d','u','j',' '), HB_TAG('D','U','J',' ')},*/ /* Dhuwal (retired code) */
- {HB_TAG('d','u','n',' '), HB_TAG_NONE }, /* Dusun Deyah != Dungan */
- {HB_TAG('d','u','p',' '), HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */
- {HB_TAG('d','w','k',' '), HB_TAG('K','U','I',' ')}, /* Dawik Kui -> Kui */
- {HB_TAG('d','w','u',' '), HB_TAG('D','U','J',' ')}, /* Dhuwal */
- {HB_TAG('d','w','y',' '), HB_TAG('D','U','J',' ')}, /* Dhuwaya -> Dhuwal */
- {HB_TAG('d','y','u',' '), HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */
- {HB_TAG('d','z','n',' '), HB_TAG_NONE }, /* Dzando != Dzongkha */
- {HB_TAG('e','c','r',' '), HB_TAG_NONE }, /* Eteocretan != Eastern Cree */
-/*{HB_TAG('e','f','i',' '), HB_TAG('E','F','I',' ')},*/ /* Efik */
- {HB_TAG('e','k','k',' '), HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */
- {HB_TAG('e','k','y',' '), HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */
- {HB_TAG('e','m','k',' '), HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */
- {HB_TAG('e','m','k',' '), HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */
- {HB_TAG('e','m','y',' '), HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */
- {HB_TAG('e','n','b',' '), HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */
- {HB_TAG('e','n','f',' '), HB_TAG('F','N','E',' ')}, /* Forest Enets */
- {HB_TAG('e','n','h',' '), HB_TAG('T','N','E',' ')}, /* Tundra Enets */
- {HB_TAG('e','s','g',' '), HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */
- {HB_TAG('e','s','i',' '), HB_TAG('I','P','K',' ')}, /* North Alaskan Inupiatun -> Inupiat */
- {HB_TAG('e','s','k',' '), HB_TAG('I','P','K',' ')}, /* Northwest Alaska Inupiatun -> Inupiat */
-/*{HB_TAG('e','s','u',' '), HB_TAG('E','S','U',' ')},*/ /* Central Yupik */
- {HB_TAG('e','t','o',' '), HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */
- {HB_TAG('e','u','q',' '), HB_TAG_NONE }, /* Basque [collection] != Basque */
- {HB_TAG('e','v','e',' '), HB_TAG('E','V','N',' ')}, /* Even */
- {HB_TAG('e','v','n',' '), HB_TAG('E','V','K',' ')}, /* Evenki */
- {HB_TAG('e','w','o',' '), HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */
- {HB_TAG('e','y','o',' '), HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */
- {HB_TAG('f','a','b',' '), HB_TAG('C','P','P',' ')}, /* Fa d'Ambu -> Creoles */
- {HB_TAG('f','a','n',' '), HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */
- {HB_TAG('f','a','n',' '), HB_TAG('B','T','I',' ')}, /* Fang (Equatorial Guinea) -> Beti */
- {HB_TAG('f','a','r',' '), HB_TAG_NONE }, /* Fataleka != Persian */
- {HB_TAG('f','a','t',' '), HB_TAG('F','A','T',' ')}, /* Fanti */
- {HB_TAG('f','a','t',' '), HB_TAG('A','K','A',' ')}, /* Fanti -> Akan */
- {HB_TAG('f','b','l',' '), HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */
- {HB_TAG('f','f','m',' '), HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */
- {HB_TAG('f','i','l',' '), HB_TAG('P','I','L',' ')}, /* Filipino */
- {HB_TAG('f','l','m',' '), HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */
- {HB_TAG('f','l','m',' '), HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */
- {HB_TAG('f','m','p',' '), HB_TAG('F','M','P',' ')}, /* Fe’fe’ */
- {HB_TAG('f','m','p',' '), HB_TAG('B','M','L',' ')}, /* Fe'fe' -> Bamileke */
- {HB_TAG('f','n','g',' '), HB_TAG('C','P','P',' ')}, /* Fanagalo -> Creoles */
-/*{HB_TAG('f','o','n',' '), HB_TAG('F','O','N',' ')},*/ /* Fon */
- {HB_TAG('f','o','s',' '), HB_TAG_NONE }, /* Siraya != Faroese */
- {HB_TAG('f','p','e',' '), HB_TAG('C','P','P',' ')}, /* Fernando Po Creole English -> Creoles */
-/*{HB_TAG('f','r','c',' '), HB_TAG('F','R','C',' ')},*/ /* Cajun French */
-/*{HB_TAG('f','r','p',' '), HB_TAG('F','R','P',' ')},*/ /* Arpitan */
- {HB_TAG('f','u','b',' '), HB_TAG('F','U','L',' ')}, /* Adamawa Fulfulde -> Fulah */
- {HB_TAG('f','u','c',' '), HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */
- {HB_TAG('f','u','e',' '), HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */
- {HB_TAG('f','u','f',' '), HB_TAG('F','T','A',' ')}, /* Pular -> Futa */
- {HB_TAG('f','u','f',' '), HB_TAG('F','U','L',' ')}, /* Pular -> Fulah */
- {HB_TAG('f','u','h',' '), HB_TAG('F','U','L',' ')}, /* Western Niger Fulfulde -> Fulah */
- {HB_TAG('f','u','i',' '), HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */
- {HB_TAG('f','u','q',' '), HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */
- {HB_TAG('f','u','r',' '), HB_TAG('F','R','L',' ')}, /* Friulian */
- {HB_TAG('f','u','v',' '), HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
- {HB_TAG('f','u','v',' '), HB_TAG('F','U','L',' ')}, /* Nigerian Fulfulde -> Fulah */
- {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */
- {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */
- {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */
- {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic (Gaelic) */
-/*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */
- {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */
- {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */
- {HB_TAG('g','a','r',' '), HB_TAG_NONE }, /* Galeya != Garshuni */
- {HB_TAG('g','a','w',' '), HB_TAG_NONE }, /* Nobonob != Garhwali */
- {HB_TAG('g','a','x',' '), HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */
- {HB_TAG('g','a','z',' '), HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */
- {HB_TAG('g','b','m',' '), HB_TAG('G','A','W',' ')}, /* Garhwali */
- {HB_TAG('g','c','e',' '), HB_TAG('A','T','H',' ')}, /* Galice -> Athapaskan */
- {HB_TAG('g','c','f',' '), HB_TAG('C','P','P',' ')}, /* Guadeloupean Creole French -> Creoles */
- {HB_TAG('g','c','l',' '), HB_TAG('C','P','P',' ')}, /* Grenadian Creole English -> Creoles */
- {HB_TAG('g','c','r',' '), HB_TAG('C','P','P',' ')}, /* Guianese Creole French -> Creoles */
- {HB_TAG('g','d','a',' '), HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */
-/*{HB_TAG('g','e','z',' '), HB_TAG('G','E','Z',' ')},*/ /* Geez */
- {HB_TAG('g','g','o',' '), HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */
- {HB_TAG('g','h','a',' '), HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */
- {HB_TAG('g','h','k',' '), HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */
- {HB_TAG('g','h','o',' '), HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */
- {HB_TAG('g','i','b',' '), HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */
-/*{HB_TAG('g','i','h',' '), HB_TAG('G','I','H',' ')},*/ /* Githabul */
- {HB_TAG('g','i','l',' '), HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */
- {HB_TAG('g','j','u',' '), HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */
- {HB_TAG('g','k','p',' '), HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */
- {HB_TAG('g','k','p',' '), HB_TAG('K','P','L',' ')}, /* Guinea Kpelle -> Kpelle */
- {HB_TAG('g','l','d',' '), HB_TAG('N','A','N',' ')}, /* Nanai */
-/*{HB_TAG('g','l','k',' '), HB_TAG('G','L','K',' ')},*/ /* Gilaki */
- {HB_TAG('g','m','z',' '), HB_TAG_NONE }, /* Mgbolizhia != Gumuz */
- {HB_TAG('g','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Gangte -> Chin */
-/*{HB_TAG('g','n','n',' '), HB_TAG('G','N','N',' ')},*/ /* Gumatj */
- {HB_TAG('g','n','o',' '), HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */
- {HB_TAG('g','n','w',' '), HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */
-/*{HB_TAG('g','o','g',' '), HB_TAG('G','O','G',' ')},*/ /* Gogo */
- {HB_TAG('g','o','m',' '), HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */
-/*{HB_TAG('g','o','n',' '), HB_TAG('G','O','N',' ')},*/ /* Gondi [macrolanguage] */
- {HB_TAG('g','o','q',' '), HB_TAG('C','P','P',' ')}, /* Gorap -> Creoles */
- {HB_TAG('g','o','x',' '), HB_TAG('B','A','D','0')}, /* Gobu -> Banda */
- {HB_TAG('g','p','e',' '), HB_TAG('C','P','P',' ')}, /* Ghanaian Pidgin English -> Creoles */
- {HB_TAG('g','r','o',' '), HB_TAG_NONE }, /* Groma != Garo */
- {HB_TAG('g','r','r',' '), HB_TAG('B','B','R',' ')}, /* Taznatit -> Berber */
- {HB_TAG('g','r','t',' '), HB_TAG('G','R','O',' ')}, /* Garo */
- {HB_TAG('g','r','u',' '), HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */
- {HB_TAG('g','s','w',' '), HB_TAG('A','L','S',' ')}, /* Alsatian */
- {HB_TAG('g','u','a',' '), HB_TAG_NONE }, /* Shiki != Guarani */
-/*{HB_TAG('g','u','c',' '), HB_TAG('G','U','C',' ')},*/ /* Wayuu */
-/*{HB_TAG('g','u','f',' '), HB_TAG('G','U','F',' ')},*/ /* Gupapuyngu */
- {HB_TAG('g','u','g',' '), HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */
- {HB_TAG('g','u','i',' '), HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */
- {HB_TAG('g','u','k',' '), HB_TAG('G','M','Z',' ')}, /* Gumuz */
- {HB_TAG('g','u','l',' '), HB_TAG('C','P','P',' ')}, /* Sea Island Creole English -> Creoles */
- {HB_TAG('g','u','n',' '), HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */
-/*{HB_TAG('g','u','z',' '), HB_TAG('G','U','Z',' ')},*/ /* Gusii */
- {HB_TAG('g','w','i',' '), HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */
- {HB_TAG('g','y','n',' '), HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */
- {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */
- {HB_TAG('h','a','e',' '), HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */
- {HB_TAG('h','a','i',' '), HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */
- {HB_TAG('h','a','k',' '), HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */
- {HB_TAG('h','a','l',' '), HB_TAG_NONE }, /* Halang != Halam (Falam Chin) */
- {HB_TAG('h','a','r',' '), HB_TAG('H','R','I',' ')}, /* Harari */
-/*{HB_TAG('h','a','w',' '), HB_TAG('H','A','W',' ')},*/ /* Hawaiian */
- {HB_TAG('h','a','x',' '), HB_TAG('H','A','I','0')}, /* Southern Haida -> Haida */
-/*{HB_TAG('h','a','y',' '), HB_TAG('H','A','Y',' ')},*/ /* Haya */
-/*{HB_TAG('h','a','z',' '), HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */
- {HB_TAG('h','b','n',' '), HB_TAG_NONE }, /* Heiban != Hammer-Banna */
- {HB_TAG('h','c','a',' '), HB_TAG('C','P','P',' ')}, /* Andaman Creole Hindi -> Creoles */
- {HB_TAG('h','d','n',' '), HB_TAG('H','A','I','0')}, /* Northern Haida -> Haida */
- {HB_TAG('h','e','a',' '), HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */
-/*{HB_TAG('h','e','i',' '), HB_TAG('H','E','I',' ')},*/ /* Heiltsuk */
-/*{HB_TAG('h','i','l',' '), HB_TAG('H','I','L',' ')},*/ /* Hiligaynon */
- {HB_TAG('h','j','i',' '), HB_TAG('M','L','Y',' ')}, /* Haji -> Malay */
- {HB_TAG('h','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Matu Chin -> Chin */
- {HB_TAG('h','m','a',' '), HB_TAG('H','M','N',' ')}, /* Southern Mashan Hmong -> Hmong */
- {HB_TAG('h','m','c',' '), HB_TAG('H','M','N',' ')}, /* Central Huishui Hmong -> Hmong */
- {HB_TAG('h','m','d',' '), HB_TAG('H','M','D',' ')}, /* Large Flowery Miao -> A-Hmao */
- {HB_TAG('h','m','d',' '), HB_TAG('H','M','N',' ')}, /* Large Flowery Miao -> Hmong */
- {HB_TAG('h','m','e',' '), HB_TAG('H','M','N',' ')}, /* Eastern Huishui Hmong -> Hmong */
- {HB_TAG('h','m','g',' '), HB_TAG('H','M','N',' ')}, /* Southwestern Guiyang Hmong -> Hmong */
- {HB_TAG('h','m','h',' '), HB_TAG('H','M','N',' ')}, /* Southwestern Huishui Hmong -> Hmong */
- {HB_TAG('h','m','i',' '), HB_TAG('H','M','N',' ')}, /* Northern Huishui Hmong -> Hmong */
- {HB_TAG('h','m','j',' '), HB_TAG('H','M','N',' ')}, /* Ge -> Hmong */
- {HB_TAG('h','m','l',' '), HB_TAG('H','M','N',' ')}, /* Luopohe Hmong -> Hmong */
- {HB_TAG('h','m','m',' '), HB_TAG('H','M','N',' ')}, /* Central Mashan Hmong -> Hmong */
-/*{HB_TAG('h','m','n',' '), HB_TAG('H','M','N',' ')},*/ /* Hmong [macrolanguage] */
- {HB_TAG('h','m','p',' '), HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */
- {HB_TAG('h','m','q',' '), HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */
- {HB_TAG('h','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Hmar -> Chin */
- {HB_TAG('h','m','s',' '), HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */
- {HB_TAG('h','m','w',' '), HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */
- {HB_TAG('h','m','y',' '), HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */
- {HB_TAG('h','m','z',' '), HB_TAG('H','M','Z',' ')}, /* Hmong Shua -> Hmong Shuat */
- {HB_TAG('h','m','z',' '), HB_TAG('H','M','N',' ')}, /* Hmong Shua -> Hmong */
-/*{HB_TAG('h','n','d',' '), HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */
- {HB_TAG('h','n','e',' '), HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */
- {HB_TAG('h','n','j',' '), HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */
- {HB_TAG('h','n','o',' '), HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */
- {HB_TAG('h','o','c',' '), HB_TAG('H','O',' ',' ')}, /* Ho */
- {HB_TAG('h','o','i',' '), HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */
- {HB_TAG('h','o','j',' '), HB_TAG('H','A','R',' ')}, /* Hadothi -> Harauti */
- {HB_TAG('h','o','j',' '), HB_TAG('R','A','J',' ')}, /* Hadothi -> Rajasthani */
- {HB_TAG('h','r','a',' '), HB_TAG('Q','I','N',' ')}, /* Hrangkhol -> Chin */
- {HB_TAG('h','r','m',' '), HB_TAG('H','M','N',' ')}, /* Horned Miao -> Hmong */
- {HB_TAG('h','s','b',' '), HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
- {HB_TAG('h','s','n',' '), HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */
- {HB_TAG('h','u','j',' '), HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */
- {HB_TAG('h','u','p',' '), HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */
- {HB_TAG('h','u','s',' '), HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */
- {HB_TAG('h','w','c',' '), HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */
- {HB_TAG('h','y','w',' '), HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */
-/*{HB_TAG('i','b','a',' '), HB_TAG('I','B','A',' ')},*/ /* Iban */
-/*{HB_TAG('i','b','b',' '), HB_TAG('I','B','B',' ')},*/ /* Ibibio */
- {HB_TAG('i','b','y',' '), HB_TAG('I','J','O',' ')}, /* Ibani -> Ijo */
- {HB_TAG('i','c','r',' '), HB_TAG('C','P','P',' ')}, /* Islander Creole English -> Creoles */
- {HB_TAG('i','d','a',' '), HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */
- {HB_TAG('i','d','b',' '), HB_TAG('C','P','P',' ')}, /* Indo-Portuguese -> Creoles */
- {HB_TAG('i','g','b',' '), HB_TAG('E','B','I',' ')}, /* Ebira */
- {HB_TAG('i','h','b',' '), HB_TAG('C','P','P',' ')}, /* Iha Based Pidgin -> Creoles */
- {HB_TAG('i','j','c',' '), HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */
- {HB_TAG('i','j','e',' '), HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */
- {HB_TAG('i','j','n',' '), HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */
-/*{HB_TAG('i','j','o',' '), HB_TAG('I','J','O',' ')},*/ /* Ijo [collection] */
- {HB_TAG('i','j','s',' '), HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */
- {HB_TAG('i','k','e',' '), HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */
- {HB_TAG('i','k','e',' '), HB_TAG('I','N','U','K')}, /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */
- {HB_TAG('i','k','t',' '), HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */
-/*{HB_TAG('i','l','o',' '), HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */
- {HB_TAG('i','n','g',' '), HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */
- {HB_TAG('i','n','h',' '), HB_TAG('I','N','G',' ')}, /* Ingush */
- {HB_TAG('i','r','i',' '), HB_TAG_NONE }, /* Rigwe != Irish */
-/*{HB_TAG('i','r','u',' '), HB_TAG('I','R','U',' ')},*/ /* Irula */
- {HB_TAG('i','s','m',' '), HB_TAG_NONE }, /* Masimasi != Inari Sami */
- {HB_TAG('i','t','z',' '), HB_TAG('M','Y','N',' ')}, /* Itzá -> Mayan */
- {HB_TAG('i','x','l',' '), HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */
- {HB_TAG('j','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Popti' -> Mayan */
- {HB_TAG('j','a','k',' '), HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */
- {HB_TAG('j','a','m',' '), HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */
- {HB_TAG('j','a','m',' '), HB_TAG('C','P','P',' ')}, /* Jamaican Creole English -> Creoles */
- {HB_TAG('j','a','n',' '), HB_TAG_NONE }, /* Jandai != Japanese */
- {HB_TAG('j','a','x',' '), HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */
- {HB_TAG('j','b','e',' '), HB_TAG('B','B','R',' ')}, /* Judeo-Berber -> Berber */
- {HB_TAG('j','b','n',' '), HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */
-/*{HB_TAG('j','b','o',' '), HB_TAG('J','B','O',' ')},*/ /* Lojban */
-/*{HB_TAG('j','c','t',' '), HB_TAG('J','C','T',' ')},*/ /* Krymchak */
- {HB_TAG('j','g','o',' '), HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */
- {HB_TAG('j','i','i',' '), HB_TAG_NONE }, /* Jiiddu != Yiddish */
- {HB_TAG('j','k','m',' '), HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */
- {HB_TAG('j','k','p',' '), HB_TAG('K','R','N',' ')}, /* Paku Karen -> Karen */
- {HB_TAG('j','u','d',' '), HB_TAG_NONE }, /* Worodougou != Ladino */
- {HB_TAG('j','u','l',' '), HB_TAG_NONE }, /* Jirel != Jula */
- {HB_TAG('j','v','d',' '), HB_TAG('C','P','P',' ')}, /* Javindo -> Creoles */
- {HB_TAG('k','a','a',' '), HB_TAG('K','R','K',' ')}, /* Karakalpak */
- {HB_TAG('k','a','b',' '), HB_TAG('K','A','B','0')}, /* Kabyle */
- {HB_TAG('k','a','b',' '), HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */
- {HB_TAG('k','a','c',' '), HB_TAG_NONE }, /* Kachin != Kachchi */
- {HB_TAG('k','a','m',' '), HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
- {HB_TAG('k','a','r',' '), HB_TAG('K','R','N',' ')}, /* Karen [collection] */
-/*{HB_TAG('k','a','w',' '), HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */
- {HB_TAG('k','b','d',' '), HB_TAG('K','A','B',' ')}, /* Kabardian */
- {HB_TAG('k','b','y',' '), HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */
- {HB_TAG('k','c','a',' '), HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */
- {HB_TAG('k','c','a',' '), HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */
- {HB_TAG('k','c','a',' '), HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */
- {HB_TAG('k','c','n',' '), HB_TAG('C','P','P',' ')}, /* Nubi -> Creoles */
-/*{HB_TAG('k','d','e',' '), HB_TAG('K','D','E',' ')},*/ /* Makonde */
- {HB_TAG('k','d','r',' '), HB_TAG('K','R','M',' ')}, /* Karaim */
- {HB_TAG('k','d','t',' '), HB_TAG('K','U','Y',' ')}, /* Kuy */
- {HB_TAG('k','e','a',' '), HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */
- {HB_TAG('k','e','a',' '), HB_TAG('C','P','P',' ')}, /* Kabuverdianu -> Creoles */
- {HB_TAG('k','e','b',' '), HB_TAG_NONE }, /* Kélé != Kebena */
- {HB_TAG('k','e','k',' '), HB_TAG('K','E','K',' ')}, /* Kekchi */
- {HB_TAG('k','e','k',' '), HB_TAG('M','Y','N',' ')}, /* Kekchí -> Mayan */
- {HB_TAG('k','e','x',' '), HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */
- {HB_TAG('k','f','a',' '), HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */
- {HB_TAG('k','f','r',' '), HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */
- {HB_TAG('k','f','x',' '), HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */
- {HB_TAG('k','f','y',' '), HB_TAG('K','M','N',' ')}, /* Kumaoni */
- {HB_TAG('k','g','e',' '), HB_TAG_NONE }, /* Komering != Khutsuri Georgian */
- {HB_TAG('k','h','a',' '), HB_TAG('K','S','I',' ')}, /* Khasi */
- {HB_TAG('k','h','b',' '), HB_TAG('X','B','D',' ')}, /* Lü */
- {HB_TAG('k','h','k',' '), HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */
- {HB_TAG('k','h','n',' '), HB_TAG_NONE }, /* Khandesi != Khamti Shan (Microsoft fonts) */
- {HB_TAG('k','h','s',' '), HB_TAG_NONE }, /* Kasua != Khanty-Shurishkar */
- {HB_TAG('k','h','t',' '), HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan */
- {HB_TAG('k','h','t',' '), HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */
- {HB_TAG('k','h','v',' '), HB_TAG_NONE }, /* Khvarshi != Khanty-Vakhi */
-/*{HB_TAG('k','h','w',' '), HB_TAG('K','H','W',' ')},*/ /* Khowar */
- {HB_TAG('k','i','s',' '), HB_TAG_NONE }, /* Kis != Kisii */
- {HB_TAG('k','i','u',' '), HB_TAG('K','I','U',' ')}, /* Kirmanjki */
- {HB_TAG('k','i','u',' '), HB_TAG('Z','Z','A',' ')}, /* Kirmanjki -> Zazaki */
- {HB_TAG('k','j','b',' '), HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */
-/*{HB_TAG('k','j','d',' '), HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */
- {HB_TAG('k','j','h',' '), HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */
- {HB_TAG('k','j','p',' '), HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */
- {HB_TAG('k','j','p',' '), HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */
- {HB_TAG('k','j','t',' '), HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */
-/*{HB_TAG('k','j','z',' '), HB_TAG('K','J','Z',' ')},*/ /* Bumthangkha */
- {HB_TAG('k','k','n',' '), HB_TAG_NONE }, /* Kon Keu != Kokni */
- {HB_TAG('k','k','z',' '), HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */
- {HB_TAG('k','l','m',' '), HB_TAG_NONE }, /* Migum != Kalmyk */
- {HB_TAG('k','l','n',' '), HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */
- {HB_TAG('k','m','b',' '), HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */
- {HB_TAG('k','m','n',' '), HB_TAG_NONE }, /* Awtuw != Kumaoni */
- {HB_TAG('k','m','o',' '), HB_TAG_NONE }, /* Kwoma != Komo */
- {HB_TAG('k','m','r',' '), HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */
- {HB_TAG('k','m','s',' '), HB_TAG_NONE }, /* Kamasau != Komso */
- {HB_TAG('k','m','v',' '), HB_TAG('C','P','P',' ')}, /* Karipúna Creole French -> Creoles */
- {HB_TAG('k','m','w',' '), HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
-/*{HB_TAG('k','m','z',' '), HB_TAG('K','M','Z',' ')},*/ /* Khorasani Turkish -> Khorasani Turkic */
- {HB_TAG('k','n','c',' '), HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */
- {HB_TAG('k','n','g',' '), HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */
- {HB_TAG('k','n','j',' '), HB_TAG('M','Y','N',' ')}, /* Western Kanjobal -> Mayan */
- {HB_TAG('k','n','n',' '), HB_TAG('K','O','K',' ')}, /* Konkani */
- {HB_TAG('k','n','r',' '), HB_TAG_NONE }, /* Kaningra != Kanuri */
- {HB_TAG('k','o','d',' '), HB_TAG_NONE }, /* Kodi != Kodagu */
- {HB_TAG('k','o','h',' '), HB_TAG_NONE }, /* Koyo != Korean Old Hangul */
- {HB_TAG('k','o','i',' '), HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
- {HB_TAG('k','o','i',' '), HB_TAG('K','O','M',' ')}, /* Komi-Permyak -> Komi */
-/*{HB_TAG('k','o','k',' '), HB_TAG('K','O','K',' ')},*/ /* Konkani [macrolanguage] */
- {HB_TAG('k','o','p',' '), HB_TAG_NONE }, /* Waube != Komi-Permyak */
-/*{HB_TAG('k','o','s',' '), HB_TAG('K','O','S',' ')},*/ /* Kosraean */
- {HB_TAG('k','o','y',' '), HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */
- {HB_TAG('k','o','z',' '), HB_TAG_NONE }, /* Korak != Komi-Zyrian */
- {HB_TAG('k','p','e',' '), HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
- {HB_TAG('k','p','l',' '), HB_TAG_NONE }, /* Kpala != Kpelle */
- {HB_TAG('k','p','p',' '), HB_TAG('K','R','N',' ')}, /* Paku Karen (retired code) -> Karen */
- {HB_TAG('k','p','v',' '), HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
- {HB_TAG('k','p','v',' '), HB_TAG('K','O','M',' ')}, /* Komi-Zyrian -> Komi */
- {HB_TAG('k','p','y',' '), HB_TAG('K','Y','K',' ')}, /* Koryak */
- {HB_TAG('k','q','s',' '), HB_TAG('K','I','S',' ')}, /* Northern Kissi -> Kisii */
- {HB_TAG('k','q','y',' '), HB_TAG('K','R','T',' ')}, /* Koorete */
- {HB_TAG('k','r','c',' '), HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */
- {HB_TAG('k','r','c',' '), HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */
- {HB_TAG('k','r','i',' '), HB_TAG('K','R','I',' ')}, /* Krio */
- {HB_TAG('k','r','i',' '), HB_TAG('C','P','P',' ')}, /* Krio -> Creoles */
- {HB_TAG('k','r','k',' '), HB_TAG_NONE }, /* Kerek != Karakalpak */
-/*{HB_TAG('k','r','l',' '), HB_TAG('K','R','L',' ')},*/ /* Karelian */
- {HB_TAG('k','r','m',' '), HB_TAG_NONE }, /* Krim (retired code) != Karaim */
- {HB_TAG('k','r','n',' '), HB_TAG_NONE }, /* Sapo != Karen */
- {HB_TAG('k','r','t',' '), HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */
- {HB_TAG('k','r','u',' '), HB_TAG('K','U','U',' ')}, /* Kurukh */
- {HB_TAG('k','s','h',' '), HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */
- {HB_TAG('k','s','i',' '), HB_TAG_NONE }, /* Krisa != Khasi */
- {HB_TAG('k','s','m',' '), HB_TAG_NONE }, /* Kumba != Kildin Sami */
- {HB_TAG('k','s','s',' '), HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */
- {HB_TAG('k','s','w',' '), HB_TAG('K','S','W',' ')}, /* S’gaw Karen */
- {HB_TAG('k','s','w',' '), HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */
- {HB_TAG('k','t','b',' '), HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */
- {HB_TAG('k','t','u',' '), HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */
- {HB_TAG('k','t','w',' '), HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */
- {HB_TAG('k','u','i',' '), HB_TAG_NONE }, /* Kuikúro-Kalapálo != Kui */
- {HB_TAG('k','u','l',' '), HB_TAG_NONE }, /* Kulere != Kulvi */
-/*{HB_TAG('k','u','m',' '), HB_TAG('K','U','M',' ')},*/ /* Kumyk */
- {HB_TAG('k','u','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */
- {HB_TAG('k','u','w',' '), HB_TAG('B','A','D','0')}, /* Kpagua -> Banda */
- {HB_TAG('k','u','y',' '), HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */
- {HB_TAG('k','v','b',' '), HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */
- {HB_TAG('k','v','l',' '), HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */
- {HB_TAG('k','v','q',' '), HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */
- {HB_TAG('k','v','r',' '), HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */
- {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */
- {HB_TAG('k','v','u',' '), HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */
- {HB_TAG('k','v','y',' '), HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */
-/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */
- {HB_TAG('k','w','w',' '), HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */
- {HB_TAG('k','w','y',' '), HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */
- {HB_TAG('k','x','c',' '), HB_TAG('K','M','S',' ')}, /* Konso -> Komso */
- {HB_TAG('k','x','d',' '), HB_TAG('M','L','Y',' ')}, /* Brunei -> Malay */
- {HB_TAG('k','x','f',' '), HB_TAG('K','R','N',' ')}, /* Manumanaw Karen -> Karen */
- {HB_TAG('k','x','k',' '), HB_TAG('K','R','N',' ')}, /* Zayein Karen -> Karen */
- {HB_TAG('k','x','l',' '), HB_TAG('K','U','U',' ')}, /* Nepali Kurux (retired code) -> Kurukh */
- {HB_TAG('k','x','u',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) (retired code) */
- {HB_TAG('k','y','k',' '), HB_TAG_NONE }, /* Kamayo != Koryak */
- {HB_TAG('k','y','u',' '), HB_TAG('K','Y','U',' ')}, /* Western Kayah */
- {HB_TAG('k','y','u',' '), HB_TAG('K','R','N',' ')}, /* Western Kayah -> Karen */
- {HB_TAG('l','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Lacandon -> Mayan */
- {HB_TAG('l','a','d',' '), HB_TAG('J','U','D',' ')}, /* Ladino */
- {HB_TAG('l','a','h',' '), HB_TAG_NONE }, /* Lahnda [macrolanguage] != Lahuli */
- {HB_TAG('l','a','k',' '), HB_TAG_NONE }, /* Laka (Nigeria) (retired code) != Lak */
- {HB_TAG('l','a','m',' '), HB_TAG_NONE }, /* Lamba != Lambani */
- {HB_TAG('l','a','z',' '), HB_TAG_NONE }, /* Aribwatsa != Laz */
- {HB_TAG('l','b','e',' '), HB_TAG('L','A','K',' ')}, /* Lak */
- {HB_TAG('l','b','j',' '), HB_TAG('L','D','K',' ')}, /* Ladakhi */
- {HB_TAG('l','b','l',' '), HB_TAG('B','I','K',' ')}, /* Libon Bikol -> Bikol */
- {HB_TAG('l','c','e',' '), HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */
- {HB_TAG('l','c','f',' '), HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */
- {HB_TAG('l','d','i',' '), HB_TAG('K','O','N','0')}, /* Laari -> Kongo */
- {HB_TAG('l','d','k',' '), HB_TAG_NONE }, /* Leelau != Ladakhi */
-/*{HB_TAG('l','e','f',' '), HB_TAG('L','E','F',' ')},*/ /* Lelemi */
-/*{HB_TAG('l','e','z',' '), HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */
- {HB_TAG('l','i','f',' '), HB_TAG('L','M','B',' ')}, /* Limbu */
-/*{HB_TAG('l','i','j',' '), HB_TAG('L','I','J',' ')},*/ /* Ligurian */
- {HB_TAG('l','i','r',' '), HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */
-/*{HB_TAG('l','i','s',' '), HB_TAG('L','I','S',' ')},*/ /* Lisu */
- {HB_TAG('l','i','w',' '), HB_TAG('M','L','Y',' ')}, /* Col -> Malay */
- {HB_TAG('l','i','y',' '), HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */
-/*{HB_TAG('l','j','p',' '), HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */
- {HB_TAG('l','k','b',' '), HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */
-/*{HB_TAG('l','k','i',' '), HB_TAG('L','K','I',' ')},*/ /* Laki */
- {HB_TAG('l','k','o',' '), HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */
- {HB_TAG('l','k','s',' '), HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */
- {HB_TAG('l','l','d',' '), HB_TAG('L','A','D',' ')}, /* Ladin */
- {HB_TAG('l','m','a',' '), HB_TAG_NONE }, /* East Limba != Low Mari */
- {HB_TAG('l','m','b',' '), HB_TAG_NONE }, /* Merei != Limbu */
- {HB_TAG('l','m','n',' '), HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */
-/*{HB_TAG('l','m','o',' '), HB_TAG('L','M','O',' ')},*/ /* Lombard */
- {HB_TAG('l','m','w',' '), HB_TAG_NONE }, /* Lake Miwok != Lomwe */
- {HB_TAG('l','n','a',' '), HB_TAG('B','A','D','0')}, /* Langbashe -> Banda */
- {HB_TAG('l','n','l',' '), HB_TAG('B','A','D','0')}, /* South Central Banda -> Banda */
-/*{HB_TAG('l','o','m',' '), HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */
- {HB_TAG('l','o','u',' '), HB_TAG('C','P','P',' ')}, /* Louisiana Creole -> Creoles */
-/*{HB_TAG('l','p','o',' '), HB_TAG('L','P','O',' ')},*/ /* Lipo */
-/*{HB_TAG('l','r','c',' '), HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */
- {HB_TAG('l','r','i',' '), HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */
- {HB_TAG('l','r','m',' '), HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */
- {HB_TAG('l','r','t',' '), HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */
- {HB_TAG('l','s','b',' '), HB_TAG_NONE }, /* Burundian Sign Language != Lower Sorbian */
- {HB_TAG('l','s','m',' '), HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */
- {HB_TAG('l','t','g',' '), HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */
- {HB_TAG('l','t','h',' '), HB_TAG_NONE }, /* Thur != Lithuanian */
- {HB_TAG('l','t','o',' '), HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */
- {HB_TAG('l','t','s',' '), HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */
-/*{HB_TAG('l','u','a',' '), HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */
-/*{HB_TAG('l','u','o',' '), HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */
- {HB_TAG('l','u','s',' '), HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */
- {HB_TAG('l','u','s',' '), HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */
- {HB_TAG('l','u','y',' '), HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */
- {HB_TAG('l','u','z',' '), HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */
- {HB_TAG('l','v','i',' '), HB_TAG_NONE }, /* Lavi != Latvian */
- {HB_TAG('l','v','s',' '), HB_TAG('L','V','I',' ')}, /* Standard Latvian -> Latvian */
- {HB_TAG('l','w','g',' '), HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */
- {HB_TAG('l','z','h',' '), HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese, Traditional */
- {HB_TAG('l','z','z',' '), HB_TAG('L','A','Z',' ')}, /* Laz */
-/*{HB_TAG('m','a','d',' '), HB_TAG('M','A','D',' ')},*/ /* Madurese -> Madura */
-/*{HB_TAG('m','a','g',' '), HB_TAG('M','A','G',' ')},*/ /* Magahi */
- {HB_TAG('m','a','i',' '), HB_TAG('M','T','H',' ')}, /* Maithili */
- {HB_TAG('m','a','j',' '), HB_TAG_NONE }, /* Jalapa De Díaz Mazatec != Majang */
- {HB_TAG('m','a','k',' '), HB_TAG('M','K','R',' ')}, /* Makasar */
- {HB_TAG('m','a','m',' '), HB_TAG('M','A','M',' ')}, /* Mam */
- {HB_TAG('m','a','m',' '), HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */
- {HB_TAG('m','a','n',' '), HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */
- {HB_TAG('m','a','p',' '), HB_TAG_NONE }, /* Austronesian [collection] != Mapudungun */
- {HB_TAG('m','a','w',' '), HB_TAG_NONE }, /* Mampruli != Marwari */
- {HB_TAG('m','a','x',' '), HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */
- {HB_TAG('m','a','x',' '), HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */
- {HB_TAG('m','b','f',' '), HB_TAG('C','P','P',' ')}, /* Baba Malay -> Creoles */
- {HB_TAG('m','b','n',' '), HB_TAG_NONE }, /* Macaguán != Mbundu */
-/*{HB_TAG('m','b','o',' '), HB_TAG('M','B','O',' ')},*/ /* Mbo (Cameroon) */
- {HB_TAG('m','c','h',' '), HB_TAG_NONE }, /* Maquiritari != Manchu */
- {HB_TAG('m','c','m',' '), HB_TAG('C','P','P',' ')}, /* Malaccan Creole Portuguese -> Creoles */
- {HB_TAG('m','c','r',' '), HB_TAG_NONE }, /* Menya != Moose Cree */
- {HB_TAG('m','c','t',' '), HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */
- {HB_TAG('m','d','e',' '), HB_TAG_NONE }, /* Maba (Chad) != Mende */
- {HB_TAG('m','d','f',' '), HB_TAG('M','O','K',' ')}, /* Moksha */
-/*{HB_TAG('m','d','r',' '), HB_TAG('M','D','R',' ')},*/ /* Mandar */
- {HB_TAG('m','d','y',' '), HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
- {HB_TAG('m','e','n',' '), HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
- {HB_TAG('m','e','o',' '), HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */
-/*{HB_TAG('m','e','r',' '), HB_TAG('M','E','R',' ')},*/ /* Meru */
- {HB_TAG('m','f','a',' '), HB_TAG('M','F','A',' ')}, /* Pattani Malay */
- {HB_TAG('m','f','a',' '), HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */
- {HB_TAG('m','f','b',' '), HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */
- {HB_TAG('m','f','e',' '), HB_TAG('M','F','E',' ')}, /* Morisyen */
- {HB_TAG('m','f','e',' '), HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */
- {HB_TAG('m','f','p',' '), HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */
- {HB_TAG('m','h','c',' '), HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */
- {HB_TAG('m','h','r',' '), HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */
- {HB_TAG('m','h','v',' '), HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */
- {HB_TAG('m','i','n',' '), HB_TAG('M','I','N',' ')}, /* Minangkabau */
- {HB_TAG('m','i','n',' '), HB_TAG('M','L','Y',' ')}, /* Minangkabau -> Malay */
- {HB_TAG('m','i','z',' '), HB_TAG_NONE }, /* Coatzospan Mixtec != Mizo */
- {HB_TAG('m','k','n',' '), HB_TAG('C','P','P',' ')}, /* Kupang Malay -> Creoles */
- {HB_TAG('m','k','r',' '), HB_TAG_NONE }, /* Malas != Makasar */
- {HB_TAG('m','k','u',' '), HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */
-/*{HB_TAG('m','k','w',' '), HB_TAG('M','K','W',' ')},*/ /* Kituba (Congo) */
- {HB_TAG('m','l','e',' '), HB_TAG_NONE }, /* Manambu != Male */
- {HB_TAG('m','l','n',' '), HB_TAG_NONE }, /* Malango != Malinke */
- {HB_TAG('m','l','q',' '), HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */
- {HB_TAG('m','l','q',' '), HB_TAG('M','N','K',' ')}, /* Western Maninkakan -> Maninka */
- {HB_TAG('m','l','r',' '), HB_TAG_NONE }, /* Vame != Malayalam Reformed */
- {HB_TAG('m','m','r',' '), HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */
- {HB_TAG('m','n','c',' '), HB_TAG('M','C','H',' ')}, /* Manchu */
- {HB_TAG('m','n','d',' '), HB_TAG_NONE }, /* Mondé != Mandinka */
- {HB_TAG('m','n','g',' '), HB_TAG_NONE }, /* Eastern Mnong != Mongolian */
- {HB_TAG('m','n','h',' '), HB_TAG('B','A','D','0')}, /* Mono (Democratic Republic of Congo) -> Banda */
-/*{HB_TAG('m','n','i',' '), HB_TAG('M','N','I',' ')},*/ /* Manipuri */
- {HB_TAG('m','n','k',' '), HB_TAG('M','N','D',' ')}, /* Mandinka */
- {HB_TAG('m','n','k',' '), HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */
- {HB_TAG('m','n','p',' '), HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese, Simplified */
- {HB_TAG('m','n','s',' '), HB_TAG('M','A','N',' ')}, /* Mansi */
- {HB_TAG('m','n','w',' '), HB_TAG('M','O','N',' ')}, /* Mon */
- {HB_TAG('m','n','w',' '), HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */
- {HB_TAG('m','n','x',' '), HB_TAG_NONE }, /* Manikion != Manx */
- {HB_TAG('m','o','d',' '), HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */
-/*{HB_TAG('m','o','h',' '), HB_TAG('M','O','H',' ')},*/ /* Mohawk */
- {HB_TAG('m','o','k',' '), HB_TAG_NONE }, /* Morori != Moksha */
- {HB_TAG('m','o','p',' '), HB_TAG('M','Y','N',' ')}, /* Mopán Maya -> Mayan */
- {HB_TAG('m','o','r',' '), HB_TAG_NONE }, /* Moro != Moroccan */
-/*{HB_TAG('m','o','s',' '), HB_TAG('M','O','S',' ')},*/ /* Mossi */
- {HB_TAG('m','p','e',' '), HB_TAG('M','A','J',' ')}, /* Majang */
- {HB_TAG('m','q','g',' '), HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */
- {HB_TAG('m','r','h',' '), HB_TAG('Q','I','N',' ')}, /* Mara Chin -> Chin */
- {HB_TAG('m','r','j',' '), HB_TAG('H','M','A',' ')}, /* Western Mari -> High Mari */
- {HB_TAG('m','s','c',' '), HB_TAG('M','N','K',' ')}, /* Sankaran Maninka -> Maninka */
- {HB_TAG('m','s','h',' '), HB_TAG('M','L','G',' ')}, /* Masikoro Malagasy -> Malagasy */
- {HB_TAG('m','s','i',' '), HB_TAG('M','L','Y',' ')}, /* Sabah Malay -> Malay */
- {HB_TAG('m','s','i',' '), HB_TAG('C','P','P',' ')}, /* Sabah Malay -> Creoles */
- {HB_TAG('m','t','h',' '), HB_TAG_NONE }, /* Munggui != Maithili */
- {HB_TAG('m','t','r',' '), HB_TAG('M','A','W',' ')}, /* Mewari -> Marwari */
- {HB_TAG('m','t','s',' '), HB_TAG_NONE }, /* Yora != Maltese */
- {HB_TAG('m','u','d',' '), HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */
- {HB_TAG('m','u','i',' '), HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */
- {HB_TAG('m','u','n',' '), HB_TAG_NONE }, /* Munda [collection] != Mundari */
- {HB_TAG('m','u','p',' '), HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */
- {HB_TAG('m','u','q',' '), HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */
-/*{HB_TAG('m','u','s',' '), HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */
- {HB_TAG('m','v','b',' '), HB_TAG('A','T','H',' ')}, /* Mattole -> Athapaskan */
- {HB_TAG('m','v','e',' '), HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */
- {HB_TAG('m','v','f',' '), HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */
- {HB_TAG('m','w','k',' '), HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */
-/*{HB_TAG('m','w','l',' '), HB_TAG('M','W','L',' ')},*/ /* Mirandese */
- {HB_TAG('m','w','q',' '), HB_TAG('Q','I','N',' ')}, /* Mün Chin -> Chin */
- {HB_TAG('m','w','r',' '), HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
- {HB_TAG('m','w','w',' '), HB_TAG('M','W','W',' ')}, /* Hmong Daw */
- {HB_TAG('m','w','w',' '), HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */
- {HB_TAG('m','y','m',' '), HB_TAG('M','E','N',' ')}, /* Me’en */
-/*{HB_TAG('m','y','n',' '), HB_TAG('M','Y','N',' ')},*/ /* Mayan [collection] */
- {HB_TAG('m','y','q',' '), HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */
- {HB_TAG('m','y','v',' '), HB_TAG('E','R','Z',' ')}, /* Erzya */
- {HB_TAG('m','z','b',' '), HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */
-/*{HB_TAG('m','z','n',' '), HB_TAG('M','Z','N',' ')},*/ /* Mazanderani */
- {HB_TAG('m','z','s',' '), HB_TAG('C','P','P',' ')}, /* Macanese -> Creoles */
- {HB_TAG('n','a','g',' '), HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */
- {HB_TAG('n','a','g',' '), HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */
-/*{HB_TAG('n','a','h',' '), HB_TAG('N','A','H',' ')},*/ /* Nahuatl [collection] */
- {HB_TAG('n','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */
-/*{HB_TAG('n','a','p',' '), HB_TAG('N','A','P',' ')},*/ /* Neapolitan */
- {HB_TAG('n','a','s',' '), HB_TAG_NONE }, /* Naasioi != Naskapi */
- {HB_TAG('n','a','z',' '), HB_TAG('N','A','H',' ')}, /* Coatepec Nahuatl -> Nahuatl */
- {HB_TAG('n','c','h',' '), HB_TAG('N','A','H',' ')}, /* Central Huasteca Nahuatl -> Nahuatl */
- {HB_TAG('n','c','i',' '), HB_TAG('N','A','H',' ')}, /* Classical Nahuatl -> Nahuatl */
- {HB_TAG('n','c','j',' '), HB_TAG('N','A','H',' ')}, /* Northern Puebla Nahuatl -> Nahuatl */
- {HB_TAG('n','c','l',' '), HB_TAG('N','A','H',' ')}, /* Michoacán Nahuatl -> Nahuatl */
- {HB_TAG('n','c','r',' '), HB_TAG_NONE }, /* Ncane != N-Cree */
- {HB_TAG('n','c','x',' '), HB_TAG('N','A','H',' ')}, /* Central Puebla Nahuatl -> Nahuatl */
- {HB_TAG('n','d','b',' '), HB_TAG_NONE }, /* Kenswei Nsei != Ndebele */
-/*{HB_TAG('n','d','c',' '), HB_TAG('N','D','C',' ')},*/ /* Ndau */
- {HB_TAG('n','d','g',' '), HB_TAG_NONE }, /* Ndengereko != Ndonga */
-/*{HB_TAG('n','d','s',' '), HB_TAG('N','D','S',' ')},*/ /* Low Saxon */
- {HB_TAG('n','e','f',' '), HB_TAG('C','P','P',' ')}, /* Nefamese -> Creoles */
-/*{HB_TAG('n','e','w',' '), HB_TAG('N','E','W',' ')},*/ /* Newari */
-/*{HB_TAG('n','g','a',' '), HB_TAG('N','G','A',' ')},*/ /* Ngbaka */
- {HB_TAG('n','g','l',' '), HB_TAG('L','M','W',' ')}, /* Lomwe */
- {HB_TAG('n','g','m',' '), HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */
- {HB_TAG('n','g','o',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (retired code) -> Sutu */
- {HB_TAG('n','g','r',' '), HB_TAG_NONE }, /* Engdewu != Nagari */
- {HB_TAG('n','g','u',' '), HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */
- {HB_TAG('n','h','c',' '), HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */
- {HB_TAG('n','h','d',' '), HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */
- {HB_TAG('n','h','e',' '), HB_TAG('N','A','H',' ')}, /* Eastern Huasteca Nahuatl -> Nahuatl */
- {HB_TAG('n','h','g',' '), HB_TAG('N','A','H',' ')}, /* Tetelcingo Nahuatl -> Nahuatl */
- {HB_TAG('n','h','i',' '), HB_TAG('N','A','H',' ')}, /* Zacatlán-Ahuacatlán-Tepetzintla Nahuatl -> Nahuatl */
- {HB_TAG('n','h','k',' '), HB_TAG('N','A','H',' ')}, /* Isthmus-Cosoleacaque Nahuatl -> Nahuatl */
- {HB_TAG('n','h','m',' '), HB_TAG('N','A','H',' ')}, /* Morelos Nahuatl -> Nahuatl */
- {HB_TAG('n','h','n',' '), HB_TAG('N','A','H',' ')}, /* Central Nahuatl -> Nahuatl */
- {HB_TAG('n','h','p',' '), HB_TAG('N','A','H',' ')}, /* Isthmus-Pajapan Nahuatl -> Nahuatl */
- {HB_TAG('n','h','q',' '), HB_TAG('N','A','H',' ')}, /* Huaxcaleca Nahuatl -> Nahuatl */
- {HB_TAG('n','h','t',' '), HB_TAG('N','A','H',' ')}, /* Ometepec Nahuatl -> Nahuatl */
- {HB_TAG('n','h','v',' '), HB_TAG('N','A','H',' ')}, /* Temascaltepec Nahuatl -> Nahuatl */
- {HB_TAG('n','h','w',' '), HB_TAG('N','A','H',' ')}, /* Western Huasteca Nahuatl -> Nahuatl */
- {HB_TAG('n','h','x',' '), HB_TAG('N','A','H',' ')}, /* Isthmus-Mecayapan Nahuatl -> Nahuatl */
- {HB_TAG('n','h','y',' '), HB_TAG('N','A','H',' ')}, /* Northern Oaxaca Nahuatl -> Nahuatl */
- {HB_TAG('n','h','z',' '), HB_TAG('N','A','H',' ')}, /* Santa María La Alta Nahuatl -> Nahuatl */
- {HB_TAG('n','i','q',' '), HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */
- {HB_TAG('n','i','s',' '), HB_TAG_NONE }, /* Nimi != Nisi */
-/*{HB_TAG('n','i','u',' '), HB_TAG('N','I','U',' ')},*/ /* Niuean */
- {HB_TAG('n','i','v',' '), HB_TAG('G','I','L',' ')}, /* Gilyak */
- {HB_TAG('n','j','t',' '), HB_TAG('C','P','P',' ')}, /* Ndyuka-Trio Pidgin -> Creoles */
- {HB_TAG('n','j','z',' '), HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */
- {HB_TAG('n','k','o',' '), HB_TAG_NONE }, /* Nkonya != N’Ko */
- {HB_TAG('n','k','x',' '), HB_TAG('I','J','O',' ')}, /* Nkoroo -> Ijo */
- {HB_TAG('n','l','a',' '), HB_TAG('B','M','L',' ')}, /* Ngombale -> Bamileke */
- {HB_TAG('n','l','e',' '), HB_TAG('L','U','H',' ')}, /* East Nyala -> Luyia */
- {HB_TAG('n','l','n',' '), HB_TAG('N','A','H',' ')}, /* Durango Nahuatl (retired code) -> Nahuatl */
- {HB_TAG('n','l','v',' '), HB_TAG('N','A','H',' ')}, /* Orizaba Nahuatl -> Nahuatl */
- {HB_TAG('n','n','h',' '), HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */
- {HB_TAG('n','n','z',' '), HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */
- {HB_TAG('n','o','d',' '), HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */
-/*{HB_TAG('n','o','e',' '), HB_TAG('N','O','E',' ')},*/ /* Nimadi */
-/*{HB_TAG('n','o','g',' '), HB_TAG('N','O','G',' ')},*/ /* Nogai */
-/*{HB_TAG('n','o','v',' '), HB_TAG('N','O','V',' ')},*/ /* Novial */
- {HB_TAG('n','p','i',' '), HB_TAG('N','E','P',' ')}, /* Nepali */
- {HB_TAG('n','p','l',' '), HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */
- {HB_TAG('n','q','o',' '), HB_TAG('N','K','O',' ')}, /* N’Ko */
- {HB_TAG('n','s','k',' '), HB_TAG('N','A','S',' ')}, /* Naskapi */
- {HB_TAG('n','s','m',' '), HB_TAG_NONE }, /* Sumi Naga != Northern Sami */
-/*{HB_TAG('n','s','o',' '), HB_TAG('N','S','O',' ')},*/ /* Northern Sotho */
- {HB_TAG('n','s','u',' '), HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */
- {HB_TAG('n','t','o',' '), HB_TAG_NONE }, /* Ntomba != Esperanto */
- {HB_TAG('n','u','e',' '), HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */
- {HB_TAG('n','u','u',' '), HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */
- {HB_TAG('n','u','z',' '), HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */
- {HB_TAG('n','w','e',' '), HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */
- {HB_TAG('n','y','d',' '), HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */
-/*{HB_TAG('n','y','m',' '), HB_TAG('N','Y','M',' ')},*/ /* Nyamwezi */
- {HB_TAG('n','y','n',' '), HB_TAG('N','K','L',' ')}, /* Nyankole */
-/*{HB_TAG('n','z','a',' '), HB_TAG('N','Z','A',' ')},*/ /* Tigon Mbembe -> Mbembe Tigon */
-/*{HB_TAG('o','j','b',' '), HB_TAG('O','J','B',' ')},*/ /* Northwestern Ojibwa -> Ojibway */
- {HB_TAG('o','j','c',' '), HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */
- {HB_TAG('o','j','g',' '), HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */
- {HB_TAG('o','j','s',' '), HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */
- {HB_TAG('o','j','s',' '), HB_TAG('O','J','B',' ')}, /* Severn Ojibwa -> Ojibway */
- {HB_TAG('o','j','w',' '), HB_TAG('O','J','B',' ')}, /* Western Ojibwa -> Ojibway */
- {HB_TAG('o','k','d',' '), HB_TAG('I','J','O',' ')}, /* Okodia -> Ijo */
- {HB_TAG('o','k','i',' '), HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */
- {HB_TAG('o','k','m',' '), HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
- {HB_TAG('o','k','r',' '), HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */
- {HB_TAG('o','n','x',' '), HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */
- {HB_TAG('o','o','r',' '), HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */
- {HB_TAG('o','r','c',' '), HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */
- {HB_TAG('o','r','n',' '), HB_TAG('M','L','Y',' ')}, /* Orang Kanaq -> Malay */
- {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */
- {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */
- {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */
- {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */
- {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */
- {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */
- {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */
-/*{HB_TAG('p','a','g',' '), HB_TAG('P','A','G',' ')},*/ /* Pangasinan */
- {HB_TAG('p','a','l',' '), HB_TAG_NONE }, /* Pahlavi != Pali */
-/*{HB_TAG('p','a','m',' '), HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */
- {HB_TAG('p','a','p',' '), HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */
- {HB_TAG('p','a','p',' '), HB_TAG('C','P','P',' ')}, /* Papiamento -> Creoles */
- {HB_TAG('p','a','s',' '), HB_TAG_NONE }, /* Papasena != Pashto */
-/*{HB_TAG('p','a','u',' '), HB_TAG('P','A','U',' ')},*/ /* Palauan */
- {HB_TAG('p','b','t',' '), HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */
- {HB_TAG('p','b','u',' '), HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */
-/*{HB_TAG('p','c','c',' '), HB_TAG('P','C','C',' ')},*/ /* Bouyei */
-/*{HB_TAG('p','c','d',' '), HB_TAG('P','C','D',' ')},*/ /* Picard */
- {HB_TAG('p','c','e',' '), HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */
- {HB_TAG('p','c','k',' '), HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */
- {HB_TAG('p','c','m',' '), HB_TAG('C','P','P',' ')}, /* Nigerian Pidgin -> Creoles */
-/*{HB_TAG('p','d','c',' '), HB_TAG('P','D','C',' ')},*/ /* Pennsylvania German */
- {HB_TAG('p','d','u',' '), HB_TAG('K','R','N',' ')}, /* Kayan -> Karen */
- {HB_TAG('p','e','a',' '), HB_TAG('C','P','P',' ')}, /* Peranakan Indonesian -> Creoles */
- {HB_TAG('p','e','l',' '), HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */
- {HB_TAG('p','e','s',' '), HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */
- {HB_TAG('p','e','y',' '), HB_TAG('C','P','P',' ')}, /* Petjo -> Creoles */
- {HB_TAG('p','g','a',' '), HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */
- {HB_TAG('p','g','a',' '), HB_TAG('C','P','P',' ')}, /* Sudanese Creole Arabic -> Creoles */
-/*{HB_TAG('p','h','k',' '), HB_TAG('P','H','K',' ')},*/ /* Phake */
- {HB_TAG('p','i','h',' '), HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */
- {HB_TAG('p','i','h',' '), HB_TAG('C','P','P',' ')}, /* Pitcairn-Norfolk -> Creoles */
- {HB_TAG('p','i','l',' '), HB_TAG_NONE }, /* Yom != Filipino */
- {HB_TAG('p','i','s',' '), HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */
- {HB_TAG('p','k','h',' '), HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */
- {HB_TAG('p','k','o',' '), HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */
- {HB_TAG('p','l','g',' '), HB_TAG_NONE }, /* Pilagá != Palaung */
- {HB_TAG('p','l','k',' '), HB_TAG_NONE }, /* Kohistani Shina != Polish */
- {HB_TAG('p','l','l',' '), HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */
- {HB_TAG('p','l','n',' '), HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */
- {HB_TAG('p','l','p',' '), HB_TAG('P','A','P',' ')}, /* Palpa (retired code) */
- {HB_TAG('p','l','t',' '), HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */
- {HB_TAG('p','m','l',' '), HB_TAG('C','P','P',' ')}, /* Lingua Franca -> Creoles */
-/*{HB_TAG('p','m','s',' '), HB_TAG('P','M','S',' ')},*/ /* Piemontese */
- {HB_TAG('p','m','y',' '), HB_TAG('C','P','P',' ')}, /* Papuan Malay -> Creoles */
-/*{HB_TAG('p','n','b',' '), HB_TAG('P','N','B',' ')},*/ /* Western Panjabi */
- {HB_TAG('p','o','c',' '), HB_TAG('M','Y','N',' ')}, /* Poqomam -> Mayan */
- {HB_TAG('p','o','h',' '), HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */
- {HB_TAG('p','o','h',' '), HB_TAG('M','Y','N',' ')}, /* Poqomchi' -> Mayan */
-/*{HB_TAG('p','o','n',' '), HB_TAG('P','O','N',' ')},*/ /* Pohnpeian */
- {HB_TAG('p','o','v',' '), HB_TAG('C','P','P',' ')}, /* Upper Guinea Crioulo -> Creoles */
- {HB_TAG('p','p','a',' '), HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */
- {HB_TAG('p','r','e',' '), HB_TAG('C','P','P',' ')}, /* Principense -> Creoles */
-/*{HB_TAG('p','r','o',' '), HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */
- {HB_TAG('p','r','s',' '), HB_TAG('D','R','I',' ')}, /* Dari */
- {HB_TAG('p','r','s',' '), HB_TAG('F','A','R',' ')}, /* Dari -> Persian */
- {HB_TAG('p','s','e',' '), HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */
- {HB_TAG('p','s','t',' '), HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */
- {HB_TAG('p','u','b',' '), HB_TAG('Q','I','N',' ')}, /* Purum -> Chin */
- {HB_TAG('p','u','z',' '), HB_TAG('Q','I','N',' ')}, /* Purum Naga (retired code) -> Chin */
- {HB_TAG('p','w','o',' '), HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */
- {HB_TAG('p','w','o',' '), HB_TAG('K','R','N',' ')}, /* Pwo Western Karen -> Karen */
- {HB_TAG('p','w','w',' '), HB_TAG('K','R','N',' ')}, /* Pwo Northern Karen -> Karen */
- {HB_TAG('q','u','b',' '), HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */
- {HB_TAG('q','u','b',' '), HB_TAG('Q','U','Z',' ')}, /* Huallaga Huánuco Quechua -> Quechua */
- {HB_TAG('q','u','c',' '), HB_TAG('Q','U','C',' ')}, /* K’iche’ */
- {HB_TAG('q','u','c',' '), HB_TAG('M','Y','N',' ')}, /* K'iche' -> Mayan */
- {HB_TAG('q','u','d',' '), HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','u','d',' '), HB_TAG('Q','U','Z',' ')}, /* Calderón Highland Quichua -> Quechua */
- {HB_TAG('q','u','f',' '), HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */
- {HB_TAG('q','u','g',' '), HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','u','g',' '), HB_TAG('Q','U','Z',' ')}, /* Chimborazo Highland Quichua -> Quechua */
- {HB_TAG('q','u','h',' '), HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */
- {HB_TAG('q','u','h',' '), HB_TAG('Q','U','Z',' ')}, /* South Bolivian Quechua -> Quechua */
- {HB_TAG('q','u','k',' '), HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */
- {HB_TAG('q','u','l',' '), HB_TAG('Q','U','H',' ')}, /* North Bolivian Quechua -> Quechua (Bolivia) */
- {HB_TAG('q','u','l',' '), HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */
- {HB_TAG('q','u','m',' '), HB_TAG('M','Y','N',' ')}, /* Sipacapense -> Mayan */
- {HB_TAG('q','u','p',' '), HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */
- {HB_TAG('q','u','p',' '), HB_TAG('Q','U','Z',' ')}, /* Southern Pastaza Quechua -> Quechua */
- {HB_TAG('q','u','r',' '), HB_TAG('Q','W','H',' ')}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */
- {HB_TAG('q','u','r',' '), HB_TAG('Q','U','Z',' ')}, /* Yanahuanca Pasco Quechua -> Quechua */
- {HB_TAG('q','u','s',' '), HB_TAG('Q','U','H',' ')}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */
- {HB_TAG('q','u','s',' '), HB_TAG('Q','U','Z',' ')}, /* Santiago del Estero Quichua -> Quechua */
- {HB_TAG('q','u','v',' '), HB_TAG('M','Y','N',' ')}, /* Sacapulteco -> Mayan */
- {HB_TAG('q','u','w',' '), HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','u','w',' '), HB_TAG('Q','U','Z',' ')}, /* Tena Lowland Quichua -> Quechua */
- {HB_TAG('q','u','x',' '), HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */
- {HB_TAG('q','u','x',' '), HB_TAG('Q','U','Z',' ')}, /* Yauyos Quechua -> Quechua */
- {HB_TAG('q','u','y',' '), HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */
-/*{HB_TAG('q','u','z',' '), HB_TAG('Q','U','Z',' ')},*/ /* Cusco Quechua -> Quechua */
- {HB_TAG('q','v','a',' '), HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','a',' '), HB_TAG('Q','U','Z',' ')}, /* Ambo-Pasco Quechua -> Quechua */
- {HB_TAG('q','v','c',' '), HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */
- {HB_TAG('q','v','e',' '), HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */
- {HB_TAG('q','v','h',' '), HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','h',' '), HB_TAG('Q','U','Z',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua */
- {HB_TAG('q','v','i',' '), HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','v','i',' '), HB_TAG('Q','U','Z',' ')}, /* Imbabura Highland Quichua -> Quechua */
- {HB_TAG('q','v','j',' '), HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','v','j',' '), HB_TAG('Q','U','Z',' ')}, /* Loja Highland Quichua -> Quechua */
- {HB_TAG('q','v','l',' '), HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','l',' '), HB_TAG('Q','U','Z',' ')}, /* Cajatambo North Lima Quechua -> Quechua */
- {HB_TAG('q','v','m',' '), HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','m',' '), HB_TAG('Q','U','Z',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua */
- {HB_TAG('q','v','n',' '), HB_TAG('Q','W','H',' ')}, /* North Junín Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','n',' '), HB_TAG('Q','U','Z',' ')}, /* North Junín Quechua -> Quechua */
- {HB_TAG('q','v','o',' '), HB_TAG('Q','V','I',' ')}, /* Napo Lowland Quechua -> Quechua (Ecuador) */
- {HB_TAG('q','v','o',' '), HB_TAG('Q','U','Z',' ')}, /* Napo Lowland Quechua -> Quechua */
- {HB_TAG('q','v','p',' '), HB_TAG('Q','W','H',' ')}, /* Pacaraos Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','p',' '), HB_TAG('Q','U','Z',' ')}, /* Pacaraos Quechua -> Quechua */
- {HB_TAG('q','v','s',' '), HB_TAG('Q','U','Z',' ')}, /* San Martín Quechua -> Quechua */
- {HB_TAG('q','v','w',' '), HB_TAG('Q','W','H',' ')}, /* Huaylla Wanca Quechua -> Quechua (Peru) */
- {HB_TAG('q','v','w',' '), HB_TAG('Q','U','Z',' ')}, /* Huaylla Wanca Quechua -> Quechua */
- {HB_TAG('q','v','z',' '), HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','v','z',' '), HB_TAG('Q','U','Z',' ')}, /* Northern Pastaza Quichua -> Quechua */
- {HB_TAG('q','w','a',' '), HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','w','a',' '), HB_TAG('Q','U','Z',' ')}, /* Corongo Ancash Quechua -> Quechua */
- {HB_TAG('q','w','c',' '), HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */
- {HB_TAG('q','w','h',' '), HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','w','h',' '), HB_TAG('Q','U','Z',' ')}, /* Huaylas Ancash Quechua -> Quechua */
- {HB_TAG('q','w','s',' '), HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','w','s',' '), HB_TAG('Q','U','Z',' ')}, /* Sihuas Ancash Quechua -> Quechua */
- {HB_TAG('q','w','t',' '), HB_TAG('A','T','H',' ')}, /* Kwalhioqua-Tlatskanai -> Athapaskan */
- {HB_TAG('q','x','a',' '), HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','a',' '), HB_TAG('Q','U','Z',' ')}, /* Chiquián Ancash Quechua -> Quechua */
- {HB_TAG('q','x','c',' '), HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','c',' '), HB_TAG('Q','U','Z',' ')}, /* Chincha Quechua -> Quechua */
- {HB_TAG('q','x','h',' '), HB_TAG('Q','W','H',' ')}, /* Panao Huánuco Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','h',' '), HB_TAG('Q','U','Z',' ')}, /* Panao Huánuco Quechua -> Quechua */
- {HB_TAG('q','x','l',' '), HB_TAG('Q','V','I',' ')}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','x','l',' '), HB_TAG('Q','U','Z',' ')}, /* Salasaca Highland Quichua -> Quechua */
- {HB_TAG('q','x','n',' '), HB_TAG('Q','W','H',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','n',' '), HB_TAG('Q','U','Z',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua */
- {HB_TAG('q','x','o',' '), HB_TAG('Q','W','H',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','o',' '), HB_TAG('Q','U','Z',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua */
- {HB_TAG('q','x','p',' '), HB_TAG('Q','U','Z',' ')}, /* Puno Quechua -> Quechua */
- {HB_TAG('q','x','r',' '), HB_TAG('Q','V','I',' ')}, /* Cañar Highland Quichua -> Quechua (Ecuador) */
- {HB_TAG('q','x','r',' '), HB_TAG('Q','U','Z',' ')}, /* Cañar Highland Quichua -> Quechua */
- {HB_TAG('q','x','t',' '), HB_TAG('Q','W','H',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','t',' '), HB_TAG('Q','U','Z',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua */
- {HB_TAG('q','x','u',' '), HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */
- {HB_TAG('q','x','w',' '), HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */
- {HB_TAG('q','x','w',' '), HB_TAG('Q','U','Z',' ')}, /* Jauja Wanca Quechua -> Quechua */
- {HB_TAG('r','a','g',' '), HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */
-/*{HB_TAG('r','a','j',' '), HB_TAG('R','A','J',' ')},*/ /* Rajasthani [macrolanguage] */
- {HB_TAG('r','a','l',' '), HB_TAG('Q','I','N',' ')}, /* Ralte -> Chin */
-/*{HB_TAG('r','a','r',' '), HB_TAG('R','A','R',' ')},*/ /* Rarotongan */
- {HB_TAG('r','b','b',' '), HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */
- {HB_TAG('r','b','l',' '), HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */
- {HB_TAG('r','c','f',' '), HB_TAG('C','P','P',' ')}, /* Réunion Creole French -> Creoles */
-/*{HB_TAG('r','e','j',' '), HB_TAG('R','E','J',' ')},*/ /* Rejang */
-/*{HB_TAG('r','h','g',' '), HB_TAG('R','H','G',' ')},*/ /* Rohingya */
-/*{HB_TAG('r','i','a',' '), HB_TAG('R','I','A',' ')},*/ /* Riang (India) */
- {HB_TAG('r','i','f',' '), HB_TAG('R','I','F',' ')}, /* Tarifit */
- {HB_TAG('r','i','f',' '), HB_TAG('B','B','R',' ')}, /* Tarifit -> Berber */
-/*{HB_TAG('r','i','t',' '), HB_TAG('R','I','T',' ')},*/ /* Ritharrngu -> Ritarungo */
- {HB_TAG('r','k','i',' '), HB_TAG('A','R','K',' ')}, /* Rakhine */
-/*{HB_TAG('r','k','w',' '), HB_TAG('R','K','W',' ')},*/ /* Arakwal */
- {HB_TAG('r','m','c',' '), HB_TAG('R','O','Y',' ')}, /* Carpathian Romani -> Romany */
- {HB_TAG('r','m','f',' '), HB_TAG('R','O','Y',' ')}, /* Kalo Finnish Romani -> Romany */
- {HB_TAG('r','m','l',' '), HB_TAG('R','O','Y',' ')}, /* Baltic Romani -> Romany */
- {HB_TAG('r','m','n',' '), HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */
- {HB_TAG('r','m','o',' '), HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */
- {HB_TAG('r','m','s',' '), HB_TAG_NONE }, /* Romanian Sign Language != Romansh */
- {HB_TAG('r','m','w',' '), HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */
- {HB_TAG('r','m','y',' '), HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
- {HB_TAG('r','m','y',' '), HB_TAG('R','O','Y',' ')}, /* Vlax Romani -> Romany */
- {HB_TAG('r','m','z',' '), HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */
- {HB_TAG('r','o','m',' '), HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
- {HB_TAG('r','o','p',' '), HB_TAG('C','P','P',' ')}, /* Kriol -> Creoles */
- {HB_TAG('r','t','c',' '), HB_TAG('Q','I','N',' ')}, /* Rungtu Chin -> Chin */
-/*{HB_TAG('r','t','m',' '), HB_TAG('R','T','M',' ')},*/ /* Rotuman */
- {HB_TAG('r','u','e',' '), HB_TAG('R','S','Y',' ')}, /* Rusyn */
-/*{HB_TAG('r','u','p',' '), HB_TAG('R','U','P',' ')},*/ /* Aromanian */
- {HB_TAG('r','w','r',' '), HB_TAG('M','A','W',' ')}, /* Marwari (India) */
- {HB_TAG('s','a','d',' '), HB_TAG_NONE }, /* Sandawe != Sadri */
- {HB_TAG('s','a','h',' '), HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */
- {HB_TAG('s','a','m',' '), HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */
-/*{HB_TAG('s','a','s',' '), HB_TAG('S','A','S',' ')},*/ /* Sasak */
-/*{HB_TAG('s','a','t',' '), HB_TAG('S','A','T',' ')},*/ /* Santali */
- {HB_TAG('s','a','y',' '), HB_TAG_NONE }, /* Saya != Sayisi */
- {HB_TAG('s','c','f',' '), HB_TAG('C','P','P',' ')}, /* San Miguel Creole French -> Creoles */
- {HB_TAG('s','c','h',' '), HB_TAG('Q','I','N',' ')}, /* Sakachep -> Chin */
- {HB_TAG('s','c','i',' '), HB_TAG('C','P','P',' ')}, /* Sri Lankan Creole Malay -> Creoles */
- {HB_TAG('s','c','k',' '), HB_TAG('S','A','D',' ')}, /* Sadri */
-/*{HB_TAG('s','c','n',' '), HB_TAG('S','C','N',' ')},*/ /* Sicilian */
-/*{HB_TAG('s','c','o',' '), HB_TAG('S','C','O',' ')},*/ /* Scots */
- {HB_TAG('s','c','s',' '), HB_TAG('S','C','S',' ')}, /* North Slavey */
- {HB_TAG('s','c','s',' '), HB_TAG('S','L','A',' ')}, /* North Slavey -> Slavey */
- {HB_TAG('s','c','s',' '), HB_TAG('A','T','H',' ')}, /* North Slavey -> Athapaskan */
- {HB_TAG('s','d','c',' '), HB_TAG('S','R','D',' ')}, /* Sassarese Sardinian -> Sardinian */
- {HB_TAG('s','d','h',' '), HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */
- {HB_TAG('s','d','n',' '), HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */
- {HB_TAG('s','d','s',' '), HB_TAG('B','B','R',' ')}, /* Sened -> Berber */
- {HB_TAG('s','e','h',' '), HB_TAG('S','N','A',' ')}, /* Sena */
- {HB_TAG('s','e','k',' '), HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */
-/*{HB_TAG('s','e','l',' '), HB_TAG('S','E','L',' ')},*/ /* Selkup */
- {HB_TAG('s','e','z',' '), HB_TAG('Q','I','N',' ')}, /* Senthang Chin -> Chin */
- {HB_TAG('s','f','m',' '), HB_TAG('S','F','M',' ')}, /* Small Flowery Miao */
- {HB_TAG('s','f','m',' '), HB_TAG('H','M','N',' ')}, /* Small Flowery Miao -> Hmong */
-/*{HB_TAG('s','g','a',' '), HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */
- {HB_TAG('s','g','c',' '), HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */
- {HB_TAG('s','g','o',' '), HB_TAG_NONE }, /* Songa (retired code) != Sango */
-/*{HB_TAG('s','g','s',' '), HB_TAG('S','G','S',' ')},*/ /* Samogitian */
- {HB_TAG('s','g','w',' '), HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */
- {HB_TAG('s','h','i',' '), HB_TAG('S','H','I',' ')}, /* Tachelhit */
- {HB_TAG('s','h','i',' '), HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */
- {HB_TAG('s','h','l',' '), HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */
-/*{HB_TAG('s','h','n',' '), HB_TAG('S','H','N',' ')},*/ /* Shan */
- {HB_TAG('s','h','u',' '), HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */
- {HB_TAG('s','h','y',' '), HB_TAG('B','B','R',' ')}, /* Tachawit -> Berber */
- {HB_TAG('s','i','b',' '), HB_TAG_NONE }, /* Sebop != Sibe */
-/*{HB_TAG('s','i','d',' '), HB_TAG('S','I','D',' ')},*/ /* Sidamo */
- {HB_TAG('s','i','g',' '), HB_TAG_NONE }, /* Paasaal != Silte Gurage */
- {HB_TAG('s','i','z',' '), HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */
- {HB_TAG('s','j','d',' '), HB_TAG('K','S','M',' ')}, /* Kildin Sami */
- {HB_TAG('s','j','o',' '), HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */
- {HB_TAG('s','j','s',' '), HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */
- {HB_TAG('s','k','g',' '), HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */
- {HB_TAG('s','k','r',' '), HB_TAG('S','R','K',' ')}, /* Saraiki */
- {HB_TAG('s','k','s',' '), HB_TAG_NONE }, /* Maia != Skolt Sami */
- {HB_TAG('s','k','w',' '), HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */
- {HB_TAG('s','k','y',' '), HB_TAG_NONE }, /* Sikaiana != Slovak */
- {HB_TAG('s','l','a',' '), HB_TAG_NONE }, /* Slavic [collection] != Slavey */
- {HB_TAG('s','m','a',' '), HB_TAG('S','S','M',' ')}, /* Southern Sami */
- {HB_TAG('s','m','d',' '), HB_TAG('M','B','N',' ')}, /* Sama (retired code) -> Mbundu */
- {HB_TAG('s','m','j',' '), HB_TAG('L','S','M',' ')}, /* Lule Sami */
- {HB_TAG('s','m','l',' '), HB_TAG_NONE }, /* Central Sama != Somali */
- {HB_TAG('s','m','n',' '), HB_TAG('I','S','M',' ')}, /* Inari Sami */
- {HB_TAG('s','m','s',' '), HB_TAG('S','K','S',' ')}, /* Skolt Sami */
- {HB_TAG('s','m','t',' '), HB_TAG('Q','I','N',' ')}, /* Simte -> Chin */
- {HB_TAG('s','n','b',' '), HB_TAG('I','B','A',' ')}, /* Sebuyau (retired code) -> Iban */
- {HB_TAG('s','n','h',' '), HB_TAG_NONE }, /* Shinabo (retired code) != Sinhala (Sinhalese) */
-/*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */
- {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */
-/*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */
- {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */
- {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */
- {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */
- {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */
- {HB_TAG('s','r','k',' '), HB_TAG_NONE }, /* Serudung Murut != Saraiki */
- {HB_TAG('s','r','m',' '), HB_TAG('C','P','P',' ')}, /* Saramaccan -> Creoles */
- {HB_TAG('s','r','n',' '), HB_TAG('C','P','P',' ')}, /* Sranan Tongo -> Creoles */
- {HB_TAG('s','r','o',' '), HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */
-/*{HB_TAG('s','r','r',' '), HB_TAG('S','R','R',' ')},*/ /* Serer */
- {HB_TAG('s','r','s',' '), HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */
- {HB_TAG('s','s','h',' '), HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */
- {HB_TAG('s','s','l',' '), HB_TAG_NONE }, /* Western Sisaala != South Slavey */
- {HB_TAG('s','s','m',' '), HB_TAG_NONE }, /* Semnam != Southern Sami */
- {HB_TAG('s','t','a',' '), HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */
-/*{HB_TAG('s','t','q',' '), HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */
- {HB_TAG('s','t','v',' '), HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */
-/*{HB_TAG('s','u','k',' '), HB_TAG('S','U','K',' ')},*/ /* Sukuma */
- {HB_TAG('s','u','q',' '), HB_TAG('S','U','R',' ')}, /* Suri */
- {HB_TAG('s','u','r',' '), HB_TAG_NONE }, /* Mwaghavul != Suri */
-/*{HB_TAG('s','v','a',' '), HB_TAG('S','V','A',' ')},*/ /* Svan */
- {HB_TAG('s','v','c',' '), HB_TAG('C','P','P',' ')}, /* Vincentian Creole English -> Creoles */
- {HB_TAG('s','v','e',' '), HB_TAG_NONE }, /* Serili != Swedish */
- {HB_TAG('s','w','b',' '), HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */
- {HB_TAG('s','w','c',' '), HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */
- {HB_TAG('s','w','h',' '), HB_TAG('S','W','K',' ')}, /* Swahili */
- {HB_TAG('s','w','k',' '), HB_TAG_NONE }, /* Malawi Sena != Swahili */
- {HB_TAG('s','w','n',' '), HB_TAG('B','B','R',' ')}, /* Sawknah -> Berber */
- {HB_TAG('s','w','v',' '), HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */
-/*{HB_TAG('s','x','u',' '), HB_TAG('S','X','U',' ')},*/ /* Upper Saxon */
- {HB_TAG('s','y','c',' '), HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */
-/*{HB_TAG('s','y','l',' '), HB_TAG('S','Y','L',' ')},*/ /* Sylheti */
-/*{HB_TAG('s','y','r',' '), HB_TAG('S','Y','R',' ')},*/ /* Syriac [macrolanguage] */
-/*{HB_TAG('s','z','l',' '), HB_TAG('S','Z','L',' ')},*/ /* Silesian */
- {HB_TAG('t','a','a',' '), HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */
-/*{HB_TAG('t','a','b',' '), HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */
- {HB_TAG('t','a','j',' '), HB_TAG_NONE }, /* Eastern Tamang != Tajiki */
- {HB_TAG('t','a','q',' '), HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */
- {HB_TAG('t','a','q',' '), HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */
- {HB_TAG('t','a','s',' '), HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */
- {HB_TAG('t','a','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */
- {HB_TAG('t','c','b',' '), HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */
- {HB_TAG('t','c','e',' '), HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */
- {HB_TAG('t','c','h',' '), HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */
- {HB_TAG('t','c','p',' '), HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */
- {HB_TAG('t','c','s',' '), HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */
- {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */
- {HB_TAG('t','c','z',' '), HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */
-/*{HB_TAG('t','d','d',' '), HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */
- {HB_TAG('t','d','x',' '), HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */
- {HB_TAG('t','e','c',' '), HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */
- {HB_TAG('t','e','m',' '), HB_TAG('T','M','N',' ')}, /* Timne -> Temne */
-/*{HB_TAG('t','e','t',' '), HB_TAG('T','E','T',' ')},*/ /* Tetum */
- {HB_TAG('t','e','z',' '), HB_TAG('B','B','R',' ')}, /* Tetserret -> Berber */
- {HB_TAG('t','f','n',' '), HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */
- {HB_TAG('t','g','h',' '), HB_TAG('C','P','P',' ')}, /* Tobagonian Creole English -> Creoles */
- {HB_TAG('t','g','j',' '), HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */
- {HB_TAG('t','g','n',' '), HB_TAG_NONE }, /* Tandaganon != Tongan */
- {HB_TAG('t','g','r',' '), HB_TAG_NONE }, /* Tareng != Tigre */
- {HB_TAG('t','g','x',' '), HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */
- {HB_TAG('t','g','y',' '), HB_TAG_NONE }, /* Togoyo != Tigrinya */
- {HB_TAG('t','h','t',' '), HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */
- {HB_TAG('t','h','v',' '), HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */
- {HB_TAG('t','h','v',' '), HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */
- {HB_TAG('t','h','z',' '), HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */
- {HB_TAG('t','h','z',' '), HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */
- {HB_TAG('t','i','a',' '), HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */
- {HB_TAG('t','i','g',' '), HB_TAG('T','G','R',' ')}, /* Tigre */
-/*{HB_TAG('t','i','v',' '), HB_TAG('T','I','V',' ')},*/ /* Tiv */
-/*{HB_TAG('t','j','l',' '), HB_TAG('T','J','L',' ')},*/ /* Tai Laing */
- {HB_TAG('t','j','o',' '), HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */
- {HB_TAG('t','k','g',' '), HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */
- {HB_TAG('t','k','m',' '), HB_TAG_NONE }, /* Takelma != Turkmen */
-/*{HB_TAG('t','l','i',' '), HB_TAG('T','L','I',' ')},*/ /* Tlingit */
- {HB_TAG('t','m','g',' '), HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */
- {HB_TAG('t','m','h',' '), HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */
- {HB_TAG('t','m','h',' '), HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */
- {HB_TAG('t','m','n',' '), HB_TAG_NONE }, /* Taman (Indonesia) != Temne */
- {HB_TAG('t','m','w',' '), HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */
- {HB_TAG('t','n','a',' '), HB_TAG_NONE }, /* Tacana != Tswana */
- {HB_TAG('t','n','e',' '), HB_TAG_NONE }, /* Tinoc Kallahan (retired code) != Tundra Enets */
- {HB_TAG('t','n','f',' '), HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */
- {HB_TAG('t','n','f',' '), HB_TAG('F','A','R',' ')}, /* Tangshewi (retired code) -> Persian */
- {HB_TAG('t','n','g',' '), HB_TAG_NONE }, /* Tobanga != Tonga */
- {HB_TAG('t','o','d',' '), HB_TAG('T','O','D','0')}, /* Toma */
- {HB_TAG('t','o','i',' '), HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */
- {HB_TAG('t','o','j',' '), HB_TAG('M','Y','N',' ')}, /* Tojolabal -> Mayan */
- {HB_TAG('t','o','l',' '), HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */
- {HB_TAG('t','o','r',' '), HB_TAG('B','A','D','0')}, /* Togbo-Vara Banda -> Banda */
- {HB_TAG('t','p','i',' '), HB_TAG('T','P','I',' ')}, /* Tok Pisin */
- {HB_TAG('t','p','i',' '), HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */
- {HB_TAG('t','r','f',' '), HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */
- {HB_TAG('t','r','k',' '), HB_TAG_NONE }, /* Turkic [collection] != Turkish */
- {HB_TAG('t','r','u',' '), HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */
- {HB_TAG('t','r','u',' '), HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */
- {HB_TAG('t','s','g',' '), HB_TAG_NONE }, /* Tausug != Tsonga */
-/*{HB_TAG('t','s','j',' '), HB_TAG('T','S','J',' ')},*/ /* Tshangla */
- {HB_TAG('t','t','c',' '), HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */
- {HB_TAG('t','t','m',' '), HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */
- {HB_TAG('t','t','q',' '), HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */
- {HB_TAG('t','t','q',' '), HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */
- {HB_TAG('t','u','a',' '), HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */
- {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tumbuka */
-/*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka -> Tulu */
- {HB_TAG('t','u','u',' '), HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */
- {HB_TAG('t','u','v',' '), HB_TAG_NONE }, /* Turkana != Tuvin */
- {HB_TAG('t','u','y',' '), HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */
-/*{HB_TAG('t','v','l',' '), HB_TAG('T','V','L',' ')},*/ /* Tuvalu */
- {HB_TAG('t','v','y',' '), HB_TAG('C','P','P',' ')}, /* Timor Pidgin -> Creoles */
- {HB_TAG('t','x','c',' '), HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */
- {HB_TAG('t','x','y',' '), HB_TAG('M','L','G',' ')}, /* Tanosy Malagasy -> Malagasy */
- {HB_TAG('t','y','v',' '), HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */
-/*{HB_TAG('t','y','z',' '), HB_TAG('T','Y','Z',' ')},*/ /* Tày */
- {HB_TAG('t','z','h',' '), HB_TAG('M','Y','N',' ')}, /* Tzeltal -> Mayan */
- {HB_TAG('t','z','j',' '), HB_TAG('M','Y','N',' ')}, /* Tz'utujil -> Mayan */
- {HB_TAG('t','z','m',' '), HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */
- {HB_TAG('t','z','m',' '), HB_TAG('B','B','R',' ')}, /* Central Atlas Tamazight -> Berber */
- {HB_TAG('t','z','o',' '), HB_TAG('T','Z','O',' ')}, /* Tzotzil */
- {HB_TAG('t','z','o',' '), HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */
- {HB_TAG('u','b','l',' '), HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */
-/*{HB_TAG('u','d','m',' '), HB_TAG('U','D','M',' ')},*/ /* Udmurt */
- {HB_TAG('u','k','i',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) */
- {HB_TAG('u','l','n',' '), HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */
-/*{HB_TAG('u','m','b',' '), HB_TAG('U','M','B',' ')},*/ /* Umbundu */
- {HB_TAG('u','n','r',' '), HB_TAG('M','U','N',' ')}, /* Mundari */
- {HB_TAG('u','r','k',' '), HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */
- {HB_TAG('u','s','p',' '), HB_TAG('M','Y','N',' ')}, /* Uspanteco -> Mayan */
- {HB_TAG('u','z','n',' '), HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */
- {HB_TAG('u','z','s',' '), HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */
- {HB_TAG('v','a','p',' '), HB_TAG('Q','I','N',' ')}, /* Vaiphei -> Chin */
-/*{HB_TAG('v','e','c',' '), HB_TAG('V','E','C',' ')},*/ /* Venetian */
- {HB_TAG('v','i','c',' '), HB_TAG('C','P','P',' ')}, /* Virgin Islands Creole English -> Creoles */
- {HB_TAG('v','i','t',' '), HB_TAG_NONE }, /* Viti != Vietnamese */
- {HB_TAG('v','k','k',' '), HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */
- {HB_TAG('v','k','p',' '), HB_TAG('C','P','P',' ')}, /* Korlai Creole Portuguese -> Creoles */
- {HB_TAG('v','k','t',' '), HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */
- {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */
- {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */
-/*{HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')},*/ /* Võro */
- {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */
-/*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */
- {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */
- {HB_TAG('w','b','r',' '), HB_TAG('W','A','G',' ')}, /* Wagdi */
- {HB_TAG('w','b','r',' '), HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */
-/*{HB_TAG('w','c','i',' '), HB_TAG('W','C','I',' ')},*/ /* Waci Gbe */
- {HB_TAG('w','e','a',' '), HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */
- {HB_TAG('w','e','s',' '), HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */
- {HB_TAG('w','e','u',' '), HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */
- {HB_TAG('w','l','c',' '), HB_TAG('C','M','R',' ')}, /* Mwali Comorian -> Comorian */
- {HB_TAG('w','l','e',' '), HB_TAG('S','I','G',' ')}, /* Wolane -> Silte Gurage */
- {HB_TAG('w','l','k',' '), HB_TAG('A','T','H',' ')}, /* Wailaki -> Athapaskan */
- {HB_TAG('w','n','i',' '), HB_TAG('C','M','R',' ')}, /* Ndzwani Comorian -> Comorian */
- {HB_TAG('w','r','y',' '), HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */
- {HB_TAG('w','s','g',' '), HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */
-/*{HB_TAG('w','t','m',' '), HB_TAG('W','T','M',' ')},*/ /* Mewati */
- {HB_TAG('w','u','u',' '), HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */
- {HB_TAG('x','a','l',' '), HB_TAG('K','L','M',' ')}, /* Kalmyk */
- {HB_TAG('x','a','l',' '), HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */
- {HB_TAG('x','a','n',' '), HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */
- {HB_TAG('x','b','d',' '), HB_TAG_NONE }, /* Bindal != Lü */
-/*{HB_TAG('x','j','b',' '), HB_TAG('X','J','B',' ')},*/ /* Minjungbal -> Minjangbal */
-/*{HB_TAG('x','k','f',' '), HB_TAG('X','K','F',' ')},*/ /* Khengkha */
- {HB_TAG('x','m','g',' '), HB_TAG('B','M','L',' ')}, /* Mengaka -> Bamileke */
- {HB_TAG('x','m','m',' '), HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */
- {HB_TAG('x','m','m',' '), HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */
- {HB_TAG('x','m','v',' '), HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */
- {HB_TAG('x','m','w',' '), HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */
- {HB_TAG('x','n','j',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (Tanzania) -> Sutu */
- {HB_TAG('x','n','q',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (Mozambique) -> Sutu */
- {HB_TAG('x','n','r',' '), HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */
-/*{HB_TAG('x','o','g',' '), HB_TAG('X','O','G',' ')},*/ /* Soga */
- {HB_TAG('x','p','e',' '), HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */
- {HB_TAG('x','p','e',' '), HB_TAG('K','P','L',' ')}, /* Liberia Kpelle -> Kpelle */
- {HB_TAG('x','s','l',' '), HB_TAG('S','S','L',' ')}, /* South Slavey */
- {HB_TAG('x','s','l',' '), HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */
- {HB_TAG('x','s','l',' '), HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */
- {HB_TAG('x','s','t',' '), HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */
-/*{HB_TAG('x','u','b',' '), HB_TAG('X','U','B',' ')},*/ /* Betta Kurumba -> Bette Kuruma */
-/*{HB_TAG('x','u','j',' '), HB_TAG('X','U','J',' ')},*/ /* Jennu Kurumba -> Jennu Kuruma */
- {HB_TAG('x','u','p',' '), HB_TAG('A','T','H',' ')}, /* Upper Umpqua -> Athapaskan */
- {HB_TAG('x','w','o',' '), HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */
- {HB_TAG('y','a','j',' '), HB_TAG('B','A','D','0')}, /* Banda-Yangere -> Banda */
- {HB_TAG('y','a','k',' '), HB_TAG_NONE }, /* Yakama != Sakha */
-/*{HB_TAG('y','a','o',' '), HB_TAG('Y','A','O',' ')},*/ /* Yao */
-/*{HB_TAG('y','a','p',' '), HB_TAG('Y','A','P',' ')},*/ /* Yapese */
- {HB_TAG('y','b','a',' '), HB_TAG_NONE }, /* Yala != Yoruba */
- {HB_TAG('y','b','b',' '), HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */
- {HB_TAG('y','b','d',' '), HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */
- {HB_TAG('y','d','d',' '), HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */
-/*{HB_TAG('y','g','p',' '), HB_TAG('Y','G','P',' ')},*/ /* Gepo */
- {HB_TAG('y','i','h',' '), HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */
- {HB_TAG('y','i','m',' '), HB_TAG_NONE }, /* Yimchungru Naga != Yi Modern */
-/*{HB_TAG('y','n','a',' '), HB_TAG('Y','N','A',' ')},*/ /* Aluo */
- {HB_TAG('y','o','s',' '), HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */
- {HB_TAG('y','u','a',' '), HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */
- {HB_TAG('y','u','e',' '), HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */
-/*{HB_TAG('y','w','q',' '), HB_TAG('Y','W','Q',' ')},*/ /* Wuding-Luquan Yi */
- {HB_TAG('z','c','h',' '), HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */
- {HB_TAG('z','d','j',' '), HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */
-/*{HB_TAG('z','e','a',' '), HB_TAG('Z','E','A',' ')},*/ /* Zeeuws -> Zealandic */
- {HB_TAG('z','e','h',' '), HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */
- {HB_TAG('z','e','n',' '), HB_TAG('B','B','R',' ')}, /* Zenaga -> Berber */
- {HB_TAG('z','g','b',' '), HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */
- {HB_TAG('z','g','h',' '), HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */
- {HB_TAG('z','g','h',' '), HB_TAG('B','B','R',' ')}, /* Standard Moroccan Tamazight -> Berber */
- {HB_TAG('z','g','m',' '), HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */
- {HB_TAG('z','g','n',' '), HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */
- {HB_TAG('z','h','d',' '), HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */
- {HB_TAG('z','h','n',' '), HB_TAG('Z','H','A',' ')}, /* Nong Zhuang -> Zhuang */
- {HB_TAG('z','l','j',' '), HB_TAG('Z','H','A',' ')}, /* Liujiang Zhuang -> Zhuang */
- {HB_TAG('z','l','m',' '), HB_TAG('M','L','Y',' ')}, /* Malay */
- {HB_TAG('z','l','n',' '), HB_TAG('Z','H','A',' ')}, /* Lianshan Zhuang -> Zhuang */
- {HB_TAG('z','l','q',' '), HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */
- {HB_TAG('z','m','i',' '), HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */
- {HB_TAG('z','m','z',' '), HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */
- {HB_TAG('z','n','d',' '), HB_TAG_NONE }, /* Zande [collection] != Zande */
- {HB_TAG('z','n','e',' '), HB_TAG('Z','N','D',' ')}, /* Zande */
- {HB_TAG('z','o','m',' '), HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */
- {HB_TAG('z','q','e',' '), HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */
- {HB_TAG('z','s','m',' '), HB_TAG('M','L','Y',' ')}, /* Standard Malay -> Malay */
- {HB_TAG('z','u','m',' '), HB_TAG('L','R','C',' ')}, /* Kumzari -> Luri */
- {HB_TAG('z','y','b',' '), HB_TAG('Z','H','A',' ')}, /* Yongbei Zhuang -> Zhuang */
- {HB_TAG('z','y','g',' '), HB_TAG('Z','H','A',' ')}, /* Yang Zhuang -> Zhuang */
- {HB_TAG('z','y','j',' '), HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */
- {HB_TAG('z','y','n',' '), HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */
- {HB_TAG('z','y','p',' '), HB_TAG('Q','I','N',' ')}, /* Zyphe Chin -> Chin */
-/*{HB_TAG('z','z','a',' '), HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */
- {HB_TAG('z','z','j',' '), HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */
-};
-#endif
-
-/**
- * hb_ot_tags_from_complex_language:
- * @lang_str: a BCP 47 language tag to convert.
- * @limit: a pointer to the end of the substring of @lang_str to consider for
- * conversion.
- * @count: maximum number of language tags to retrieve (IN) and actual number of
- * language tags retrieved (OUT). If no tags are retrieved, it is not modified.
- * @tags: array of size at least @language_count to store the language tag
- * results
- *
- * Converts a multi-subtag BCP 47 language tag to language tags.
- *
- * Return value: Whether any language systems were retrieved.
- **/
-static inline bool
-hb_ot_tags_from_complex_language (const char *lang_str,
- const char *limit,
- unsigned int *count /* IN/OUT */,
- hb_tag_t *tags /* OUT */)
-{
- if (limit - lang_str >= 7)
- {
- const char *p = strchr (lang_str, '-');
- if (!p || p >= limit || limit - p < 5) goto out;
- if (subtag_matches (p, limit, "-fonnapa", 8))
- {
- /* Undetermined; North American Phonetic Alphabet */
- tags[0] = HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-polyton", 8))
- {
- /* Modern Greek (1453-); Polytonic Greek */
- tags[0] = HB_TAG('P','G','R',' '); /* Polytonic Greek */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-arevmda", 8))
- {
- /* Armenian; Western Armenian (retired code) */
- tags[0] = HB_TAG('H','Y','E',' '); /* Armenian */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-provenc", 8))
- {
- /* Occitan (post 1500); Provençal */
- tags[0] = HB_TAG('P','R','O',' '); /* Provençal / Old Provençal */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-fonipa", 7))
- {
- /* Undetermined; International Phonetic Alphabet */
- tags[0] = HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-geok", 5))
- {
- /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */
- tags[0] = HB_TAG('K','G','E',' '); /* Khutsuri Georgian */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-syre", 5))
- {
- /* Undetermined; Syriac (Estrangelo variant) */
- tags[0] = HB_TAG('S','Y','R','E'); /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-syrj", 5))
- {
- /* Undetermined; Syriac (Western variant) */
- tags[0] = HB_TAG('S','Y','R','J'); /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */
- *count = 1;
- return true;
- }
- if (subtag_matches (p, limit, "-syrn", 5))
- {
- /* Undetermined; Syriac (Eastern variant) */
- tags[0] = HB_TAG('S','Y','R','N'); /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */
- *count = 1;
- return true;
- }
- }
-out:
- switch (lang_str[0])
- {
- case 'a':
- if (0 == strcmp (&lang_str[1], "rt-lojban"))
- {
- /* Lojban (retired code) */
- tags[0] = HB_TAG('J','B','O',' '); /* Lojban */
- *count = 1;
- return true;
- }
- break;
- case 'c':
- if (lang_matches (&lang_str[1], limit, "do-hant-hk", 10))
- {
- /* Min Dong Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "do-hant-mo", 10))
- {
- /* Min Dong Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "jy-hant-hk", 10))
- {
- /* Jinyu Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "jy-hant-mo", 10))
- {
- /* Jinyu Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "mn-hant-hk", 10))
- {
- /* Mandarin Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "mn-hant-mo", 10))
- {
- /* Mandarin Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10))
- {
- /* Northern Ping Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hant-mo", 10))
- {
- /* Northern Ping Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "px-hant-hk", 10))
- {
- /* Pu-Xian Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "px-hant-mo", 10))
- {
- /* Pu-Xian Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sp-hant-hk", 10))
- {
- /* Southern Ping Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sp-hant-mo", 10))
- {
- /* Southern Ping Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zh-hant-hk", 10))
- {
- /* Huizhou Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zh-hant-mo", 10))
- {
- /* Huizhou Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zo-hant-hk", 10))
- {
- /* Min Zhong Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zo-hant-mo", 10))
- {
- /* Min Zhong Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "do-hans", 7))
- {
- /* Min Dong Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "do-hant", 7))
- {
- /* Min Dong Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "jy-hans", 7))
- {
- /* Jinyu Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "jy-hant", 7))
- {
- /* Jinyu Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "mn-hans", 7))
- {
- /* Mandarin Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "mn-hant", 7))
- {
- /* Mandarin Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hans", 7))
- {
- /* Northern Ping Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hant", 7))
- {
- /* Northern Ping Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "px-hans", 7))
- {
- /* Pu-Xian Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "px-hant", 7))
- {
- /* Pu-Xian Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sp-hans", 7))
- {
- /* Southern Ping Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sp-hant", 7))
- {
- /* Southern Ping Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zh-hans", 7))
- {
- /* Huizhou Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zh-hant", 7))
- {
- /* Huizhou Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zo-hans", 7))
- {
- /* Min Zhong Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "zo-hant", 7))
- {
- /* Min Zhong Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "do-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Min Dong Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "do-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Min Dong Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "do-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Min Dong Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "jy-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Jinyu Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "jy-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Jinyu Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "jy-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Jinyu Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "mn-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Mandarin Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "mn-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Mandarin Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "mn-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Mandarin Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Northern Ping Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Northern Ping Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Northern Ping Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "px-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Pu-Xian Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "px-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Pu-Xian Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "px-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Pu-Xian Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sp-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Southern Ping Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sp-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Southern Ping Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sp-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Southern Ping Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zh-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Huizhou Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zh-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Huizhou Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zh-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Huizhou Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zo-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Min Zhong Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zo-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Min Zhong Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "zo-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Min Zhong Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- break;
- case 'g':
- if (lang_matches (&lang_str[1], limit, "an-hant-hk", 10))
- {
- /* Gan Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hant-mo", 10))
- {
- /* Gan Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hans", 7))
- {
- /* Gan Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hant", 7))
- {
- /* Gan Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "a-latg", 6))
- {
- /* Irish; Latin (Gaelic variant) */
- tags[0] = HB_TAG('I','R','T',' '); /* Irish Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Gan Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Gan Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Gan Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- break;
- case 'h':
- if (lang_matches (&lang_str[1], limit, "ak-hant-hk", 10))
- {
- /* Hakka Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "ak-hant-mo", 10))
- {
- /* Hakka Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sn-hant-hk", 10))
- {
- /* Xiang Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sn-hant-mo", 10))
- {
- /* Xiang Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "ak-hans", 7))
- {
- /* Hakka Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "ak-hant", 7))
- {
- /* Hakka Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sn-hans", 7))
- {
- /* Xiang Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "sn-hant", 7))
- {
- /* Xiang Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "ak-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Hakka Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "ak-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Hakka Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "ak-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Hakka Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sn-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Xiang Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sn-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Xiang Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "sn-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Xiang Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- break;
- case 'i':
- if (0 == strcmp (&lang_str[1], "-navajo"))
- {
- /* Navajo (retired code) */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('N','A','V',' '), /* Navajo */
- HB_TAG('A','T','H',' '), /* Athapaskan */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "-hak"))
- {
- /* Hakka (retired code) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "-lux"))
- {
- /* Luxembourgish (retired code) */
- tags[0] = HB_TAG('L','T','Z',' '); /* Luxembourgish */
- *count = 1;
- return true;
- }
- break;
- case 'l':
- if (lang_matches (&lang_str[1], limit, "zh-hans", 7))
- {
- /* Literary Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- break;
- case 'm':
- if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10))
- {
- /* Min Bei Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hant-mo", 10))
- {
- /* Min Bei Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hans", 7))
- {
- /* Min Bei Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "np-hant", 7))
- {
- /* Min Bei Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Min Bei Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Min Bei Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "np-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Min Bei Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "nw-", 3)
- && subtag_matches (lang_str, limit, "-th", 3))
- {
- /* Mon; Thailand */
- tags[0] = HB_TAG('M','O','N','T'); /* Thailand Mon */
- *count = 1;
- return true;
- }
- break;
- case 'n':
- if (lang_matches (&lang_str[1], limit, "an-hant-hk", 10))
- {
- /* Min Nan Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hant-mo", 10))
- {
- /* Min Nan Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hans", 7))
- {
- /* Min Nan Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "an-hant", 7))
- {
- /* Min Nan Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Min Nan Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Min Nan Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "an-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Min Nan Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "o-bok"))
- {
- /* Norwegian Bokmal (retired code) */
- tags[0] = HB_TAG('N','O','R',' '); /* Norwegian */
- *count = 1;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "o-nyn"))
- {
- /* Norwegian Nynorsk (retired code) */
- tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */
- *count = 1;
- return true;
- }
- break;
- case 'r':
- if (0 == strncmp (&lang_str[1], "o-", 2)
- && subtag_matches (lang_str, limit, "-md", 3))
- {
- /* Romanian; Moldova */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('M','O','L',' '), /* Moldavian */
- HB_TAG('R','O','M',' '), /* Romanian */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- break;
- case 'w':
- if (lang_matches (&lang_str[1], limit, "uu-hant-hk", 10))
- {
- /* Wu Chinese; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "uu-hant-mo", 10))
- {
- /* Wu Chinese; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "uu-hans", 7))
- {
- /* Wu Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "uu-hant", 7))
- {
- /* Wu Chinese; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "uu-", 3)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Wu Chinese; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "uu-", 3)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Wu Chinese; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "uu-", 3)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Wu Chinese; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- break;
- case 'y':
- if (lang_matches (&lang_str[1], limit, "ue-hans", 7))
- {
- /* Yue Chinese; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- break;
- case 'z':
- if (lang_matches (&lang_str[1], limit, "h-hant-hk", 9))
- {
- /* Chinese [macrolanguage]; Han (Traditional variant); Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "h-hant-mo", 9))
- {
- /* Chinese [macrolanguage]; Han (Traditional variant); Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "h-min-nan"))
- {
- /* Minnan, Hokkien, Amoy, Taiwanese, Southern Min, Southern Fujian, Hoklo, Southern Fukien, Ho-lo (retired code) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "h-hans", 6))
- {
- /* Chinese [macrolanguage]; Han (Simplified variant) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (lang_matches (&lang_str[1], limit, "h-hant", 6))
- {
- /* Chinese [macrolanguage]; Han (Traditional variant) */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- if (0 == strcmp (&lang_str[1], "h-min"))
- {
- /* Min, Fuzhou, Hokkien, Amoy, or Taiwanese (retired code) */
- tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "h-", 2)
- && subtag_matches (lang_str, limit, "-hk", 3))
- {
- /* Chinese [macrolanguage]; Hong Kong */
- tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */
- *count = 1;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "h-", 2)
- && subtag_matches (lang_str, limit, "-mo", 3))
- {
- /* Chinese [macrolanguage]; Macao */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */
- HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
- return true;
- }
- if (0 == strncmp (&lang_str[1], "h-", 2)
- && subtag_matches (lang_str, limit, "-tw", 3))
- {
- /* Chinese [macrolanguage]; Taiwan, Province of China */
- tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */
- *count = 1;
- return true;
- }
- break;
- }
- return false;
-}
-
-/**
- * hb_ot_ambiguous_tag_to_language
- * @tag: A language tag.
- *
- * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to
- * many language tags) and the best tag is not the alphabetically first, or if
- * the best tag consists of multiple subtags, or if the best tag does not appear
- * in #ot_languages.
- *
- * Return value: The #hb_language_t corresponding to the BCP 47 language tag,
- * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.
- **/
-static inline hb_language_t
-hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
-{
- switch (tag)
- {
- case HB_TAG('A','L','T',' '): /* Altai */
- return hb_language_from_string ("alt", -1); /* Southern Altai */
- case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
- return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */
- case HB_TAG('A','R','A',' '): /* Arabic */
- return hb_language_from_string ("ar", -1); /* Arabic [macrolanguage] */
- case HB_TAG('A','R','K',' '): /* Rakhine */
- return hb_language_from_string ("rki", -1); /* Rakhine */
- case HB_TAG('A','T','H',' '): /* Athapaskan */
- return hb_language_from_string ("ath", -1); /* Athapascan [collection] */
- case HB_TAG('B','B','R',' '): /* Berber */
- return hb_language_from_string ("ber", -1); /* Berber [collection] */
- case HB_TAG('B','I','K',' '): /* Bikol */
- return hb_language_from_string ("bik", -1); /* Bikol [macrolanguage] */
- case HB_TAG('B','T','K',' '): /* Batak */
- return hb_language_from_string ("btk", -1); /* Batak [collection] */
- case HB_TAG('C','P','P',' '): /* Creoles */
- return hb_language_from_string ("crp", -1); /* Creoles and pidgins [collection] */
- case HB_TAG('C','R','R',' '): /* Carrier */
- return hb_language_from_string ("crx", -1); /* Carrier */
- case HB_TAG('D','G','R',' '): /* Dogri (macrolanguage) */
- return hb_language_from_string ("doi", -1); /* Dogri [macrolanguage] */
- case HB_TAG('D','N','K',' '): /* Dinka */
- return hb_language_from_string ("din", -1); /* Dinka [macrolanguage] */
- case HB_TAG('D','R','I',' '): /* Dari */
- return hb_language_from_string ("prs", -1); /* Dari */
- case HB_TAG('D','Z','N',' '): /* Dzongkha */
- return hb_language_from_string ("dz", -1); /* Dzongkha */
- case HB_TAG('E','T','I',' '): /* Estonian */
- return hb_language_from_string ("et", -1); /* Estonian [macrolanguage] */
- case HB_TAG('F','A','R',' '): /* Persian */
- return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */
- case HB_TAG('G','O','N',' '): /* Gondi */
- return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */
- case HB_TAG('H','M','A',' '): /* High Mari */
- return hb_language_from_string ("mrj", -1); /* Western Mari */
- case HB_TAG('H','M','N',' '): /* Hmong */
- return hb_language_from_string ("hmn", -1); /* Hmong [macrolanguage] */
- case HB_TAG('H','N','D',' '): /* Hindko */
- return hb_language_from_string ("hnd", -1); /* Southern Hindko */
- case HB_TAG('H','Y','E',' '): /* Armenian */
- return hb_language_from_string ("hyw", -1); /* Western Armenian */
- case HB_TAG('I','B','A',' '): /* Iban */
- return hb_language_from_string ("iba", -1); /* Iban */
- case HB_TAG('I','J','O',' '): /* Ijo */
- return hb_language_from_string ("ijo", -1); /* Ijo [collection] */
- case HB_TAG('I','N','U',' '): /* Inuktitut */
- return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */
- case HB_TAG('I','P','K',' '): /* Inupiat */
- return hb_language_from_string ("ik", -1); /* Inupiaq [macrolanguage] */
- case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
- return hb_language_from_string ("und-fonipa", -1); /* Undetermined; International Phonetic Alphabet */
- case HB_TAG('I','R','T',' '): /* Irish Traditional */
- return hb_language_from_string ("ga-Latg", -1); /* Irish; Latin (Gaelic variant) */
- case HB_TAG('J','I','I',' '): /* Yiddish */
- return hb_language_from_string ("yi", -1); /* Yiddish [macrolanguage] */
- case HB_TAG('K','A','L',' '): /* Kalenjin */
- return hb_language_from_string ("kln", -1); /* Kalenjin [macrolanguage] */
- case HB_TAG('K','G','E',' '): /* Khutsuri Georgian */
- return hb_language_from_string ("und-Geok", -1); /* Undetermined; Khutsuri (Asomtavruli and Nuskhuri) */
- case HB_TAG('K','N','R',' '): /* Kanuri */
- return hb_language_from_string ("kr", -1); /* Kanuri [macrolanguage] */
- case HB_TAG('K','O','H',' '): /* Korean Old Hangul */
- return hb_language_from_string ("okm", -1); /* Middle Korean (10th-16th cent.) */
- case HB_TAG('K','O','K',' '): /* Konkani */
- return hb_language_from_string ("kok", -1); /* Konkani [macrolanguage] */
- case HB_TAG('K','O','M',' '): /* Komi */
- return hb_language_from_string ("kv", -1); /* Komi [macrolanguage] */
- case HB_TAG('K','P','L',' '): /* Kpelle */
- return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */
- case HB_TAG('K','R','N',' '): /* Karen */
- return hb_language_from_string ("kar", -1); /* Karen [collection] */
- case HB_TAG('K','U','I',' '): /* Kui */
- return hb_language_from_string ("uki", -1); /* Kui (India) */
- case HB_TAG('K','U','R',' '): /* Kurdish */
- return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */
- case HB_TAG('L','M','A',' '): /* Low Mari */
- return hb_language_from_string ("mhr", -1); /* Eastern Mari */
- case HB_TAG('L','U','H',' '): /* Luyia */
- return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */
- case HB_TAG('L','V','I',' '): /* Latvian */
- return hb_language_from_string ("lv", -1); /* Latvian [macrolanguage] */
- case HB_TAG('M','A','W',' '): /* Marwari */
- return hb_language_from_string ("mwr", -1); /* Marwari [macrolanguage] */
- case HB_TAG('M','L','G',' '): /* Malagasy */
- return hb_language_from_string ("mg", -1); /* Malagasy [macrolanguage] */
- case HB_TAG('M','L','Y',' '): /* Malay */
- return hb_language_from_string ("ms", -1); /* Malay [macrolanguage] */
- case HB_TAG('M','N','G',' '): /* Mongolian */
- return hb_language_from_string ("mn", -1); /* Mongolian [macrolanguage] */
- case HB_TAG('M','N','K',' '): /* Maninka */
- return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */
- case HB_TAG('M','O','L',' '): /* Moldavian */
- return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */
- case HB_TAG('M','O','N','T'): /* Thailand Mon */
- return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */
- case HB_TAG('M','Y','N',' '): /* Mayan */
- return hb_language_from_string ("myn", -1); /* Mayan [collection] */
- case HB_TAG('N','A','H',' '): /* Nahuatl */
- return hb_language_from_string ("nah", -1); /* Nahuatl [collection] */
- case HB_TAG('N','E','P',' '): /* Nepali */
- return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */
- case HB_TAG('N','I','S',' '): /* Nisi */
- return hb_language_from_string ("njz", -1); /* Nyishi */
- case HB_TAG('N','O','R',' '): /* Norwegian */
- return hb_language_from_string ("no", -1); /* Norwegian [macrolanguage] */
- case HB_TAG('O','J','B',' '): /* Ojibway */
- return hb_language_from_string ("oj", -1); /* Ojibwa [macrolanguage] */
- case HB_TAG('O','R','O',' '): /* Oromo */
- return hb_language_from_string ("om", -1); /* Oromo [macrolanguage] */
- case HB_TAG('P','A','S',' '): /* Pashto */
- return hb_language_from_string ("ps", -1); /* Pashto [macrolanguage] */
- case HB_TAG('P','G','R',' '): /* Polytonic Greek */
- return hb_language_from_string ("el-polyton", -1); /* Modern Greek (1453-); Polytonic Greek */
- case HB_TAG('P','R','O',' '): /* Provençal / Old Provençal */
- return hb_language_from_string ("pro", -1); /* Old Provençal (to 1500) */
- case HB_TAG('Q','U','H',' '): /* Quechua (Bolivia) */
- return hb_language_from_string ("quh", -1); /* South Bolivian Quechua */
- case HB_TAG('Q','U','Z',' '): /* Quechua */
- return hb_language_from_string ("qu", -1); /* Quechua [macrolanguage] */
- case HB_TAG('Q','V','I',' '): /* Quechua (Ecuador) */
- return hb_language_from_string ("qvi", -1); /* Imbabura Highland Quichua */
- case HB_TAG('Q','W','H',' '): /* Quechua (Peru) */
- return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */
- case HB_TAG('R','A','J',' '): /* Rajasthani */
- return hb_language_from_string ("raj", -1); /* Rajasthani [macrolanguage] */
- case HB_TAG('R','O','M',' '): /* Romanian */
- return hb_language_from_string ("ro", -1); /* Romanian */
- case HB_TAG('R','O','Y',' '): /* Romany */
- return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */
- case HB_TAG('S','Q','I',' '): /* Albanian */
- return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */
- case HB_TAG('S','R','B',' '): /* Serbian */
- return hb_language_from_string ("sr", -1); /* Serbian */
- case HB_TAG('S','X','T',' '): /* Sutu */
- return hb_language_from_string ("xnj", -1); /* Ngoni (Tanzania) */
- case HB_TAG('S','Y','R',' '): /* Syriac */
- return hb_language_from_string ("syr", -1); /* Syriac [macrolanguage] */
- case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */
- return hb_language_from_string ("und-Syre", -1); /* Undetermined; Syriac (Estrangelo variant) */
- case HB_TAG('S','Y','R','J'): /* Syriac, Western script-variant (equivalent to ISO 15924 'Syrj') */
- return hb_language_from_string ("und-Syrj", -1); /* Undetermined; Syriac (Western variant) */
- case HB_TAG('S','Y','R','N'): /* Syriac, Eastern script-variant (equivalent to ISO 15924 'Syrn') */
- return hb_language_from_string ("und-Syrn", -1); /* Undetermined; Syriac (Eastern variant) */
- case HB_TAG('T','M','H',' '): /* Tamashek */
- return hb_language_from_string ("tmh", -1); /* Tamashek [macrolanguage] */
- case HB_TAG('T','O','D',' '): /* Todo */
- return hb_language_from_string ("xwo", -1); /* Written Oirat */
- case HB_TAG('Z','H','H',' '): /* Chinese, Traditional, Hong Kong SAR */
- return hb_language_from_string ("zh-HK", -1); /* Chinese [macrolanguage]; Hong Kong */
- case HB_TAG('Z','H','S',' '): /* Chinese, Simplified */
- return hb_language_from_string ("zh-Hans", -1); /* Chinese [macrolanguage]; Han (Simplified variant) */
- case HB_TAG('Z','H','T',' '): /* Chinese, Traditional */
- return hb_language_from_string ("zh-Hant", -1); /* Chinese [macrolanguage]; Han (Traditional variant) */
- case HB_TAG('Z','H','T','M'): /* Chinese, Traditional, Macao SAR */
- return hb_language_from_string ("zh-MO", -1); /* Chinese [macrolanguage]; Macao */
- case HB_TAG('Z','Z','A',' '): /* Zazaki */
- return hb_language_from_string ("zza", -1); /* Zazaki [macrolanguage] */
- default:
- return HB_LANGUAGE_INVALID;
- }
-}
-
-#endif /* HB_OT_TAG_TABLE_HH */
-
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
index 547f9573d05..1338c31732f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
@@ -26,9 +26,7 @@
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
*/
-#include "hb.hh"
-
-#ifndef HB_NO_OT_TAG
+#include "hb-private.hh"
/* hb_script_t */
@@ -38,10 +36,8 @@ hb_ot_old_tag_from_script (hb_script_t script)
{
/* This seems to be accurate as of end of 2012. */
- switch ((hb_tag_t) script)
- {
+ switch ((hb_tag_t) script) {
case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT;
- case HB_SCRIPT_MATH: return HB_OT_TAG_MATH_SCRIPT;
/* KATAKANA and HIRAGANA both map to 'kana' */
case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
@@ -53,6 +49,8 @@ hb_ot_old_tag_from_script (hb_script_t script)
case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
/* Unicode-5.1 additions */
case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
+ /* Unicode-5.2 additions */
+ /* Unicode-6.0 additions */
}
/* Else, just change first char to lowercase and return */
@@ -64,8 +62,6 @@ hb_ot_old_tag_to_script (hb_tag_t tag)
{
if (unlikely (tag == HB_OT_TAG_DEFAULT_SCRIPT))
return HB_SCRIPT_INVALID;
- if (unlikely (tag == HB_OT_TAG_MATH_SCRIPT))
- return HB_SCRIPT_MATH;
/* This side of the conversion is fully algorithmic. */
@@ -118,81 +114,37 @@ hb_ot_new_tag_to_script (hb_tag_t tag)
return HB_SCRIPT_UNKNOWN;
}
-#ifndef HB_DISABLE_DEPRECATED
-/**
- * hb_ot_tags_from_script:
- * @script: an #hb_script_t to convert.
- * @script_tag_1: (out): output #hb_tag_t.
- * @script_tag_2: (out): output #hb_tag_t.
- *
- * Converts an #hb_script_t to script tags.
- *
- * Since: 0.6.0
- * Deprecated: 2.0.0: use hb_ot_tags_from_script_and_language() instead
- **/
-void
-hb_ot_tags_from_script (hb_script_t script,
- hb_tag_t *script_tag_1,
- hb_tag_t *script_tag_2)
-{
- unsigned int count = 2;
- hb_tag_t tags[2];
- hb_ot_tags_from_script_and_language (script, HB_LANGUAGE_INVALID, &count, tags, nullptr, nullptr);
- *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT;
- *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT;
-}
-#endif
-
/*
* Complete list at:
- * https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags
+ * https://www.microsoft.com/typography/otspec/scripttags.htm
+ * https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm
*
* Most of the script tags are the same as the ISO 15924 tag but lowercased.
* So we just do that, and handle the exceptional cases in a switch.
*/
-static void
-hb_ot_all_tags_from_script (hb_script_t script,
- unsigned int *count /* IN/OUT */,
- hb_tag_t *tags /* OUT */)
+void
+hb_ot_tags_from_script (hb_script_t script,
+ hb_tag_t *script_tag_1,
+ hb_tag_t *script_tag_2)
{
- unsigned int i = 0;
+ hb_tag_t new_tag;
- hb_tag_t new_tag = hb_ot_new_tag_from_script (script);
- if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT))
- {
- /* HB_SCRIPT_MYANMAR maps to 'mym2', but there is no 'mym3'. */
- if (new_tag != HB_TAG('m','y','m','2'))
- tags[i++] = new_tag | '3';
- if (*count > i)
- tags[i++] = new_tag;
- }
+ *script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT;
+ *script_tag_1 = hb_ot_old_tag_from_script (script);
- if (*count > i)
- {
- hb_tag_t old_tag = hb_ot_old_tag_from_script (script);
- if (old_tag != HB_OT_TAG_DEFAULT_SCRIPT)
- tags[i++] = old_tag;
+ new_tag = hb_ot_new_tag_from_script (script);
+ if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) {
+ *script_tag_2 = *script_tag_1;
+ *script_tag_1 = new_tag;
}
-
- *count = i;
}
-/**
- * hb_ot_tag_to_script:
- * @tag: a script tag
- *
- * Converts a script tag to an #hb_script_t.
- *
- * Return value: The #hb_script_t corresponding to @tag.
- *
- **/
hb_script_t
hb_ot_tag_to_script (hb_tag_t tag)
{
- unsigned char digit = tag & 0x000000FFu;
- if (unlikely (digit == '2' || digit == '3'))
- return hb_ot_new_tag_to_script (tag & 0xFFFFFF32);
+ if (unlikely ((tag & 0x000000FFu) == '2'))
+ return hb_ot_new_tag_to_script (tag);
return hb_ot_old_tag_to_script (tag);
}
@@ -200,298 +152,867 @@ hb_ot_tag_to_script (hb_tag_t tag)
/* hb_language_t */
-static inline bool
-subtag_matches (const char *lang_str,
- const char *limit,
- const char *subtag,
- unsigned subtag_len)
-{
- if (likely ((unsigned) (limit - lang_str) < subtag_len))
- return false;
-
- do {
- const char *s = strstr (lang_str, subtag);
- if (!s || s >= limit)
- return false;
- if (!ISALNUM (s[subtag_len]))
- return true;
- lang_str = s + subtag_len;
- } while (true);
-}
-
-static bool
-lang_matches (const char *lang_str,
- const char *limit,
- const char *spec,
- unsigned spec_len)
-{
- /* Same as hb_language_matches(); duplicated. */
+typedef struct {
+ char language[4];
+ hb_tag_t tag;
+} LangTag;
- if (likely ((unsigned) (limit - lang_str) < spec_len))
- return false;
+/*
+ * Complete list at:
+ * http://www.microsoft.com/typography/otspec/languagetags.htm
+ *
+ * Generated by intersecting the OpenType language tag list from
+ * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
+ * 2008-08-04, matching on name, and finally adjusted manually.
+ *
+ * Updated on 2012-12-07 with more research into remaining codes.
+ *
+ * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
+ * the new proposal from Microsoft, and latest ISO 639-3 names.
+ *
+ * Some items still missing. Those are commented out at the end.
+ * Keep sorted for bsearch.
+ *
+ * Updated as of 2015-05-06: OT1.7 on MS website has some newer
+ * items that we don't have here, eg. Zazaki. This is the new
+ * items in OpenType 1.7 (red items), most of which we have:
+ * http://www.microsoft.com/typography/otspec170/languagetags.htm
+ */
- return strncmp (lang_str, spec, spec_len) == 0 &&
- (lang_str[spec_len] == '\0' || lang_str[spec_len] == '-');
-}
+static const LangTag ot_languages[] = {
+ {"aa", HB_TAG('A','F','R',' ')}, /* Afar */
+ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
+ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"acf", HB_TAG('F','A','N',' ')}, /* French Antillean */
+ {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */
+ {"acr", HB_TAG('A','C','R',' ')}, /* Achi */
+ {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
+ {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
+ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
+ {"ahg", HB_TAG('A','G','W',' ')}, /* Agaw */
+ {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
+ {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */
+ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */
+ {"aka", HB_TAG('A','K','A',' ')}, /* Akan */
+ {"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] */
+ {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */
+ {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
+ {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */
+ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */
+ {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
+ {"atj", HB_TAG('R','C','R',' ')}, /* R-Cree */
+ {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
+ {"av", HB_TAG('A','V','R',' ')}, /* Avaric */
+ {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
+ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */
+ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
+ {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */
+ {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */
+ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
+ {"bad", HB_TAG('B','A','D','0')}, /* Banda */
+ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
+ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */
+ {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */
+ {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */
+ {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */
+ {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */
+ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */
+ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
+ {"bdy", HB_TAG('B','D','Y',' ')}, /* Bandjalang */
+ {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */
+ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
+ {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
+ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
+ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */
+ {"bfu", HB_TAG('L','A','H',' ')}, /* Lahuli */
+ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
+ {"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 */
+ {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */
+ {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */
+ {"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */
+ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
+ {"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
+ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
+ {"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */
+ {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */
+ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
+ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
+ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */
+ {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */
+ {"br", HB_TAG('B','R','E',' ')}, /* Breton */
+ {"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
+ {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
+ {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */
+ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
+ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */
+ {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
+ {"bug", HB_TAG('B','U','G',' ')}, /* Buginese */
+ {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
+ {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
+ {"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 */
+ {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
+ {"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */
+ {"crk", HB_TAG('W','C','R',' ')}, /* West-Cree */
+ {"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */
+ {"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 */
+ {"de", HB_TAG('D','E','U',' ')}, /* German */
+ {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */
+ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */
+ {"dhg", HB_TAG('D','H','G',' ')}, /* Dhangu */
+ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
+ {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */
+ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */
+ {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */
+ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
+ {"dnj", HB_TAG('D','N','J',' ')}, /* Dan */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */
+ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
+ {"duj", HB_TAG('D','U','J',' ')}, /* Dhuwal */
+ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */
+ {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
+ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
+ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
+ {"efi", HB_TAG('E','F','I',' ')}, /* Efik */
+ {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */
+ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
+ {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */
+ {"en", HB_TAG('E','N','G',' ')}, /* English */
+ {"enf", HB_TAG('F','N','E',' ')}, /* Forest Nenets */
+ {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Nenets */
+ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
+ {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
+ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */
+ {"esu", HB_TAG('E','S','U',' ')}, /* Central Yupik */
+ {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
+ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
+ {"eve", HB_TAG('E','V','N',' ')}, /* Even */
+ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
+ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
+ {"fan", HB_TAG('F','A','N','0')}, /* Fang */
+ {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */
+ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
+ {"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/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 */
+ {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */
+ {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */
+ {"fuf", HB_TAG('F','T','A',' ')}, /* Futa */
+ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
+ {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
+ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
+ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */
+ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
+ {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
+ {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
+ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
+ {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
+ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */
+ {"gih", HB_TAG('G','I','H',' ')}, /* Githabul */
+ {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */
+ {"gkp", HB_TAG('G','K','P',' ')}, /* Kpelle (Guinea) */
+ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */
+ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
+ {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
+ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
+ {"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */
+ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */
+ {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */
+ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */
+ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */
+ {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
+ {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */
+ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */
+ {"guf", HB_TAG('G','U','F',' ')}, /* Gupapuyngu */
+ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
+/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */
+ {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */
+ {"gv", HB_TAG('M','N','X',' ')}, /* Manx */
+ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
+ {"har", HB_TAG('H','R','I',' ')}, /* Harari */
+ {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */
+ {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */
+ {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */
+ {"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 */
+ {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
+ {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */
+ {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
+ {"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
+ {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
+ {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
+ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */
+ {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
+ {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
+ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */
+ {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
+ {"iba", HB_TAG('I','B','A',' ')}, /* Iban */
+ {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */
+ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */
+ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
+ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ii", HB_TAG('Y','I','M',' ')}, /* Yi Modern */
+ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */
+ {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
+ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */
+ {"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
+ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
+ {"io", HB_TAG('I','D','O',' ')}, /* Ido */
+ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
+ {"it", HB_TAG('I','T','A',' ')}, /* Italian */
+ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
+ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */
+ {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */
+ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
+ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
+ {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
+ {"kab", HB_TAG('K','A','B','0')}, /* Kabyle */
+ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
+ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
+ {"kat", HB_TAG('K','G','E',' ')}, /* Khutsuri Georgian */
+ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
+ {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */
+ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
+ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
+ {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */
+ {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */
+ {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
+ {"kfa", HB_TAG('K','O','D',' ')}, /* Kodagu */
+ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
+ {"kfx", HB_TAG('K','U','L',' ')}, /* Kulvi */
+ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
+ {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */
+ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
+ {"khb", HB_TAG('X','B','D',' ')}, /* Lü */
+ {"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */
+/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */
+ {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
+ {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */
+ {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */
+ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */
+ {"kjd", HB_TAG('K','J','D',' ')}, /* Southern Kiwai */
+ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
+ {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */
+ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
+ {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
+ {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
+ {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
+ {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */
+ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
+ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
+ {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */
+ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */
+ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
+ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */
+ {"kon", HB_TAG('K','O','N','0')}, /* Kongo */
+ {"kos", HB_TAG('K','O','S',' ')}, /* Kosraean */
+ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
+ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
+ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
+ {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
+ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
+ {"kri", HB_TAG('K','R','I',' ')}, /* Krio */
+ {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
+ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
+ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
+ {"ksh", HB_TAG('K','S','H','0')}, /* Ripuarian, Kölsch */
+/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */
+ {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */
+ {"ktb", HB_TAG('K','E','B',' ')}, /* Kebena */
+ {"ktu", HB_TAG('K','O','N',' ')}, /* Kikongo */
+ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
+ {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
+ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
+ {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */
+ {"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
+ {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
+ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */
+ {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */
+ {"la", HB_TAG('L','A','T',' ')}, /* Latin */
+ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
+ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
+ {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
+ {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
+ {"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
+ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */
+ {"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */
+ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
+ {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */
+ {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */
+ {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */
+ {"lki", HB_TAG('L','K','I',' ')}, /* Laki */
+ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
+ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
+ {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */
+ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
+ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */
+ {"lom", HB_TAG('L','O','M',' ')}, /* Loma */
+ {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */
+ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
+ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
+ {"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
+ {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
+ {"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
+ {"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */
+ {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */
+ {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
+ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
+ {"mad", HB_TAG('M','A','D',' ')}, /* Madurese */
+ {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
+ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
+ {"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) */
+ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
+ {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */
+ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
+ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
+ {"mer", HB_TAG('M','E','R',' ')}, /* Meru */
+ {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */
+ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
+ {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */
+ {"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
+ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */
+ {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */
+ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */
+ {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */
+ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
+ {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */
+ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
+ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
+ {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
+ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
+ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
+ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
+ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
+ {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
+ {"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 */
+ {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
+ {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */
+ {"mus", HB_TAG('M','U','S',' ')}, /* Creek */
+ {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */
+ {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */
+ {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */
+ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
+ {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */
+ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */
+ {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
+ {"myn", HB_TAG('M','Y','N',' ')}, /* Mayan */
+ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */
+ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */
+ {"na", HB_TAG('N','A','U',' ')}, /* Nauru */
+ {"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
+ {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */
+ {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */
+ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
+ {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
+ {"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
+ {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */
+ {"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */
+ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
+ {"new", HB_TAG('N','E','W',' ')}, /* Newari */
+ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
+ {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */
+ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
+ {"ngo", HB_TAG('S','X','T',' ')}, /* Sutu */
+ {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
+ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
+ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
+ {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
+ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
+ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */
+ {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */
+ {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
+ {"nov", HB_TAG('N','O','V',' ')}, /* Novial */
+ {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
+ {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
+ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
+ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
+ {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */
+ {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */
+ {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */
+ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */
+ {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
+ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */
+ {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
+ {"okm", HB_TAG('K','O','H',' ')}, /* Korean Old Hangul */
+ {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
+ {"or", HB_TAG('O','R','I',' ')}, /* Oriya */
+ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
+ {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */
+ {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */
+ {"pap", HB_TAG('P','A','P','0')}, /* Papiamento */
+ {"pau", HB_TAG('P','A','U',' ')}, /* Palauan */
+ {"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 */
+ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */
+ {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */
+ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */
+ {"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
+ {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
+ {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */
+ {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */
+ {"poh", HB_TAG('P','O','H',' ')}, /* Pocomchi */
+ {"pon", HB_TAG('P','O','N',' ')}, /* Pohnpeian */
+ {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */
+ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */
+ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
+ {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */
+ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
+ {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */
+ {"quh", HB_TAG('Q','U','H',' ')}, /* Quechua (Bolivia) */
+ {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */
+ {"qvi", HB_TAG('Q','V','I',' ')}, /* Quechua (Ecuador) */
+ {"qwh", HB_TAG('Q','W','H',' ')}, /* Quechua (Peru) */
+ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */
+ {"rar", HB_TAG('R','A','R',' ')}, /* Rarotongan */
+ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */
+ {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */
+ {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
+ {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */
+ {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
+ {"rit", HB_TAG('R','I','T',' ')}, /* Ritarungo */
+ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */
+ {"rkw", HB_TAG('R','K','W',' ')}, /* Arakwal */
+ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */
+ {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
+ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */
+ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
+ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
+ {"rtm", HB_TAG('R','T','M',' ')}, /* Rotuman */
+ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */
+ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
+ {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */
+ {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
+ {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */
+ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
+ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
+ {"sam", HB_TAG('P','A','A',' ')}, /* Palestinian Aramaic */
+ {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */
+ {"sat", HB_TAG('S','A','T',' ')}, /* Santali */
+ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
+ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */
+ {"sco", HB_TAG('S','C','O',' ')}, /* Scots */
+ {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
+ {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
+ {"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 */
+ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */
+/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */
+ {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */
+ {"shn", HB_TAG('S','H','N',' ')}, /* Shan */
+ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
+ {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
+ {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
+ {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
+ {"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */
+ {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
+ {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
+ {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
+ {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
+ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
+ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"sn", HB_TAG('S','N','A','0')}, /* Shona */
+ {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
+ {"so", HB_TAG('S','M','L',' ')}, /* Somali */
+ {"sop", HB_TAG('S','O','P',' ')}, /* Songe */
+ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
+ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
+ {"srr", HB_TAG('S','R','R',' ')}, /* Serer */
+ {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */
+ {"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
+ {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */
+ {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */
+ {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */
+ {"suk", HB_TAG('S','U','K',' ')}, /* Sukama */
+ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */
+ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
+ {"sva", HB_TAG('S','V','A',' ')}, /* Svan */
+ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
+ {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
+ {"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 */
+ {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */
+ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
+ {"th", HB_TAG('T','H','A',' ')}, /* Thai */
+ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
+ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
+ {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */
+ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
+ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */
+ {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek */
+ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
+ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
+ {"tod", HB_TAG('T','O','D','0')}, /* Toma */
+ {"toi", HB_TAG('T','N','G',' ')}, /* Tonga */
+ {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */
+ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
+ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
+ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
+ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */
+ {"tvl", HB_TAG('T','V','L',' ')}, /* Tuvalu */
+ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */
+ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
+ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
+ {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */
+ {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */
+ {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */
+ {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
+ {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
+ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
+ {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */
+ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
+ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
+ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
+ {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */
+ {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */
+ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */
+ {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */
+ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
+ {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */
+ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */
+ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */
+ {"vro", HB_TAG('V','R','O',' ')}, /* Võro */
+ {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */
+ {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */
+ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
+ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */
+ {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
+ {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */
+ {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */
+ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
+ {"xan", HB_TAG('S','E','K',' ')}, /* Sekota */
+ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
+ {"xjb", HB_TAG('X','J','B',' ')}, /* Minjangbal */
+ {"xog", HB_TAG('X','O','G',' ')}, /* Soga */
+ {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
+ {"xpe", HB_TAG('X','P','E',' ')}, /* Kpelle (Liberia) */
+ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
+ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */
+ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */
+ {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */
+ {"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 */
+
+ /* The corresponding languages IDs for the following IDs are unclear,
+ * overlap, or are architecturally weird. Needs more research. */
+
+/*{"chp", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
+/*{"cwd", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
+/*{"emk", HB_TAG('E','M','K',' ')},*/ /* Eastern Maninkakan */
+/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
+/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
+/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */
+/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
+/*{"hy?", HB_TAG('H','Y','E','0')},*/ /* Armenian East (ISO 639-3 hye according to Microsoft, but that’s equivalent to ISO 639-1 hy) */
+/*{"ga-Latg?/" HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
+/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
+/*{"ka-Geok?", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
+/*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
+/*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
+/*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
+/*{"kqs, kss", HB_TAG('K','I','S',' ')},*/ /* Kisii */
+/*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */
+/*{"mlq", HB_TAG('M','L','N',' ')},*/ /* Malinke */
+/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Sotho, Northern */
+/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
+/*{"csw", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
+/*{"csw", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
+/*{"el-polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
+/*{"bgr, cnh, cnw, czt, sez, tcp, csy, ctd, flm, pck, tcz, zom, cmr, dao, hlt, cka, cnk, mrh, mwg, cbl, cnb, csh", HB_TAG('Q','I','N',' ')},*/ /* Chin */
+/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
+/*{"zh-Latn-pinyin", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
+};
-struct LangTag
-{
- hb_tag_t language;
+typedef struct {
+ char language[11];
hb_tag_t tag;
-
- int cmp (hb_tag_t a) const
- {
- return a < this->language ? -1 : a > this->language ? +1 : 0;
- }
- int cmp (const LangTag *that) const
- { return cmp (that->language); }
+} LangTagLong;
+static const LangTagLong ot_languages_zh[] = {
+ /* Store longest-first, if one is a prefix of another. */
+ {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
+ {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
+ {"zh-mo", HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */
+ {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
+ {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */
+ {"zh-hans", HB_TAG('Z','H','S',' ')}, /* Chinese (Simplified) */
+ {"zh-hant-hk",HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
+ {"zh-hant-mo",HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */
+ {"zh-hant", HB_TAG('Z','H','T',' ')}, /* Chinese (Traditional) */
};
-#include "hb-ot-tag-table.hh"
+static int
+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;
-/* The corresponding languages IDs for the following IDs are unclear,
- * overlap, or are architecturally weird. Needs more research. */
+ p = strchr (a, '-');
+ da = p ? (unsigned int) (p - a) : strlen (a);
-/*{"??", {HB_TAG('B','C','R',' ')}},*/ /* Bible Cree */
-/*{"zh?", {HB_TAG('C','H','N',' ')}},*/ /* Chinese (seen in Microsoft fonts) */
-/*{"ar-Syrc?", {HB_TAG('G','A','R',' ')}},*/ /* Garshuni */
-/*{"??", {HB_TAG('N','G','R',' ')}},*/ /* Nagari */
-/*{"??", {HB_TAG('Y','I','C',' ')}},*/ /* Yi Classic */
-/*{"zh?", {HB_TAG('Z','H','P',' ')}},*/ /* Chinese Phonetic */
+ p = strchr (b, '-');
+ db = p ? (unsigned int) (p - b) : strlen (b);
-#ifndef HB_DISABLE_DEPRECATED
-/**
- * hb_ot_tag_from_language:
- * @language: an #hb_language_t to convert.
- *
- * Converts an #hb_language_t to an #hb_tag_t.
- *
- * Since: 0.6.0
- * Deprecated: 2.0.0: use hb_ot_tags_from_script_and_language() instead
- **/
-hb_tag_t
-hb_ot_tag_from_language (hb_language_t language)
-{
- unsigned int count = 1;
- hb_tag_t tags[1];
- hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags);
- return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE;
+ return strncmp (a, b, MAX (da, db));
}
-#endif
-static void
-hb_ot_tags_from_language (const char *lang_str,
- const char *limit,
- unsigned int *count,
- hb_tag_t *tags)
+static hb_bool_t
+lang_matches (const char *lang_str, const char *spec)
{
+ unsigned int len = strlen (spec);
-#ifndef HB_NO_LANGUAGE_LONG
- /* Check for matches of multiple subtags. */
- if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
- return;
-#endif
+ return strncmp (lang_str, spec, len) == 0 &&
+ (lang_str[len] == '\0' || lang_str[len] == '-');
+}
- /* Find a language matching in the first component. */
-#ifndef HB_NO_LANGUAGE_LONG
- const char *s; s = strchr (lang_str, '-');
-#endif
- {
-#ifndef HB_NO_LANGUAGE_LONG
- if (s && limit - lang_str >= 6)
- {
- const char *extlang_end = strchr (s + 1, '-');
- /* If there is an extended language tag, use it. */
- if (3 == (extlang_end ? extlang_end - s - 1 : strlen (s + 1)) &&
- ISALPHA (s[1]))
- lang_str = s + 1;
- }
-#endif
- const LangTag *ot_languages = nullptr;
- unsigned ot_languages_len = 0;
- const char *dash = strchr (lang_str, '-');
- unsigned first_len = dash ? dash - lang_str : limit - lang_str;
- if (first_len == 2)
- {
- ot_languages = ot_languages2;
- ot_languages_len = ARRAY_LENGTH (ot_languages2);
- }
-#ifndef HB_NO_LANGUAGE_LONG
- else if (first_len == 3)
- {
- ot_languages = ot_languages3;
- ot_languages_len = ARRAY_LENGTH (ot_languages3);
- }
-#endif
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language)
+{
+ const char *lang_str, *s;
- hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len);
+ if (language == HB_LANGUAGE_INVALID)
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
- static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */
- unsigned tag_idx = last_tag_idx;
+ lang_str = hb_language_to_string (language);
- if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) ||
- hb_sorted_array (ot_languages, ot_languages_len).bfind (lang_tag, &tag_idx))
- {
- last_tag_idx = tag_idx;
- unsigned int i;
- while (tag_idx != 0 &&
- ot_languages[tag_idx].language == ot_languages[tag_idx - 1].language)
- tag_idx--;
- for (i = 0;
- i < *count &&
- tag_idx + i < ot_languages_len &&
- ot_languages[tag_idx + i].tag != HB_TAG_NONE &&
- ot_languages[tag_idx + i].language == ot_languages[tag_idx].language;
- i++)
- tags[i] = ot_languages[tag_idx + i].tag;
- *count = i;
- return;
+ s = strstr (lang_str, "x-hbot");
+ if (s) {
+ char tag[4];
+ int i;
+ s += 6;
+ 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 (tag[0], tag[1], tag[2], tag[3]);
}
}
-#ifndef HB_NO_LANGUAGE_LONG
- if (!s)
- s = lang_str + strlen (lang_str);
- if (s - lang_str == 3) {
- /* Assume it's ISO-639-3 and upper-case and use it. */
- tags[0] = hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
- *count = 1;
- return;
+ /*
+ * "fonipa" is a variant tag in BCP-47, meaning the International Phonetic Alphabet.
+ * It can be applied to any language.
+ */
+ if (strstr (lang_str, "-fonipa")) {
+ return HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */
}
-#endif
-
- *count = 0;
-}
-static bool
-parse_private_use_subtag (const char *private_use_subtag,
- unsigned int *count,
- hb_tag_t *tags,
- const char *prefix,
- unsigned char (*normalize) (unsigned char))
-{
-#ifdef HB_NO_LANGUAGE_PRIVATE_SUBTAG
- return false;
-#endif
-
- if (!(private_use_subtag && count && tags && *count)) return false;
-
- const char *s = strstr (private_use_subtag, prefix);
- if (!s) return false;
+ /*
+ * "fonnapa" is a variant tag in BCP-47, meaning the North American Phonetic Alphabet
+ * also known as Americanist Phonetic Notation. It can be applied to any language.
+ */
+ if (strstr (lang_str, "-fonnapa")) {
+ return HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */
+ }
- char tag[4];
- int i;
- s += strlen (prefix);
- if (s[0] == '-') {
- s += 1;
- char c;
- for (i = 0; i < 8 && ISHEX (s[i]); i++)
- {
- c = FROMHEX (s[i]);
- if (i % 2 == 0)
- tag[i / 2] = c << 4;
- else
- tag[i / 2] += c;
- }
- if (i != 8) return false;
- } else {
- for (i = 0; i < 4 && ISALNUM (s[i]); i++)
- tag[i] = normalize (s[i]);
- if (!i) return false;
+ /*
+ * "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 */
+ }
- for (; i < 4; i++)
- tag[i] = ' ';
+ /*
+ * "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 */
}
- tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
- if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
- tags[0] ^= ~0xDFDFDFDF;
- *count = 1;
- return true;
-}
-/**
- * hb_ot_tags_from_script_and_language:
- * @script: an #hb_script_t to convert.
- * @language: an #hb_language_t to convert.
- * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN)
- * and actual number of script tags retrieved (OUT)
- * @script_tags: (out) (optional): array of size at least @script_count to store the
- * script tag results
- * @language_count: (inout) (optional): maximum number of language tags to retrieve
- * (IN) and actual number of language tags retrieved (OUT)
- * @language_tags: (out) (optional): array of size at least @language_count to store
- * the language tag results
- *
- * Converts an #hb_script_t and an #hb_language_t to script and language tags.
- *
- * Since: 2.0.0
- **/
-void
-hb_ot_tags_from_script_and_language (hb_script_t script,
- hb_language_t language,
- unsigned int *script_count /* IN/OUT */,
- hb_tag_t *script_tags /* OUT */,
- unsigned int *language_count /* IN/OUT */,
- hb_tag_t *language_tags /* OUT */)
-{
- bool needs_script = true;
+ /*
+ * "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 */
+ }
- if (language == HB_LANGUAGE_INVALID)
+ /* Find a language matching in the first component */
{
- if (language_count && language_tags && *language_count)
- *language_count = 0;
+ const LangTag *lang_tag;
+ lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
+ ARRAY_LENGTH (ot_languages), sizeof (LangTag),
+ lang_compare_first_component);
+ if (lang_tag)
+ return lang_tag->tag;
}
- else
+
+ /* Otherwise, check the Chinese ones */
+ if (0 == lang_compare_first_component (lang_str, "zh"))
{
- const char *lang_str, *s, *limit, *private_use_subtag;
- bool needs_language;
+ unsigned int i;
- lang_str = hb_language_to_string (language);
- limit = nullptr;
- private_use_subtag = nullptr;
- if (lang_str[0] == 'x' && lang_str[1] == '-')
+ for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
{
- private_use_subtag = lang_str;
- } else {
- for (s = lang_str + 1; *s; s++)
- {
- if (s[-1] == '-' && s[1] == '-')
- {
- if (s[0] == 'x')
- {
- private_use_subtag = s;
- if (!limit)
- limit = s - 1;
- break;
- } else if (!limit)
- {
- limit = s - 1;
- }
- }
- }
- if (!limit)
- limit = s;
+ const LangTagLong *lang_tag;
+ lang_tag = &ot_languages_zh[i];
+ if (lang_matches (lang_str, lang_tag->language))
+ return lang_tag->tag;
}
- needs_script = !parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
- needs_language = !parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
+ /* Otherwise just return 'ZHS ' */
+ return HB_TAG('Z','H','S',' ');
+ }
- if (needs_language && language_count && language_tags && *language_count)
- hb_ot_tags_from_language (lang_str, limit, language_count, language_tags);
+ s = strchr (lang_str, '-');
+ if (!s)
+ s = lang_str + strlen (lang_str);
+ if (s - lang_str == 3) {
+ /* Assume it's ISO-639-3 and upper-case and use it. */
+ return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
}
- if (needs_script && script_count && script_tags && *script_count)
- hb_ot_all_tags_from_script (script, script_count, script_tags);
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
}
/**
* hb_ot_tag_to_language:
- * @tag: an language tag
*
- * Converts a language tag to an #hb_language_t.
+ *
*
- * Return value: (transfer none) (nullable):
- * The #hb_language_t corresponding to @tag.
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
@@ -503,156 +1024,71 @@ hb_ot_tag_to_language (hb_tag_t tag)
if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
return nullptr;
-#ifndef HB_NO_LANGUAGE_LONG
- {
- hb_language_t disambiguated_tag = hb_ot_ambiguous_tag_to_language (tag);
- if (disambiguated_tag != HB_LANGUAGE_INVALID)
- return disambiguated_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);
+ 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);
}
-#endif
-
- char buf[4];
- for (i = 0; i < ARRAY_LENGTH (ot_languages2); i++)
- if (ot_languages2[i].tag == tag)
- {
- hb_tag_to_string (ot_languages2[i].language, buf);
- return hb_language_from_string (buf, 2);
- }
-#ifndef HB_NO_LANGUAGE_LONG
- for (i = 0; i < ARRAY_LENGTH (ot_languages3); i++)
- if (ot_languages3[i].tag == tag)
- {
- hb_tag_to_string (ot_languages3[i].language, buf);
- return hb_language_from_string (buf, 3);
- }
-#endif
- /* Return a custom language in the form of "x-hbot-AABBCCDD".
- * If it's three letters long, also guess it's ISO 639-3 and lower-case and
- * prepend it (if it's not a registered tag, the private use subtags will
- * ensure that calling hb_ot_tag_from_language on the result will still return
- * the same tag as the original tag).
- */
- {
- char buf[20];
- char *str = buf;
- if (ISALPHA (tag >> 24)
- && ISALPHA ((tag >> 16) & 0xFF)
- && ISALPHA ((tag >> 8) & 0xFF)
- && (tag & 0xFF) == ' ')
- {
- buf[0] = TOLOWER (tag >> 24);
- buf[1] = TOLOWER ((tag >> 16) & 0xFF);
- buf[2] = TOLOWER ((tag >> 8) & 0xFF);
- buf[3] = '-';
- str += 4;
+ for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
+ if (ot_languages[i].tag == tag)
+ return hb_language_from_string (ot_languages[i].language, -1);
+
+ /* If tag starts with ZH, it's Chinese */
+ if ((tag & 0xFFFF0000u) == 0x5A480000u) {
+ switch (tag) {
+ case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
+ case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */
+ case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */
+ default: break; /* Fall through */
}
- snprintf (str, 16, "x-hbot-%08x", tag);
- return hb_language_from_string (&*buf, -1);
}
-}
-/**
- * hb_ot_tags_to_script_and_language:
- * @script_tag: a script tag
- * @language_tag: a language tag
- * @script: (out) (optional): the #hb_script_t corresponding to @script_tag.
- * @language: (out) (optional): the #hb_language_t corresponding to @script_tag and
- * @language_tag.
- *
- * Converts a script tag and a language tag to an #hb_script_t and an
- * #hb_language_t.
- *
- * Since: 2.0.0
- **/
-void
-hb_ot_tags_to_script_and_language (hb_tag_t script_tag,
- hb_tag_t language_tag,
- hb_script_t *script /* OUT */,
- hb_language_t *language /* OUT */)
-{
- hb_script_t script_out = hb_ot_tag_to_script (script_tag);
- if (script)
- *script = script_out;
- if (language)
+ /* Else return a custom language in the form of "x-hbotABCD" */
{
- unsigned int script_count = 1;
- hb_tag_t primary_script_tag[1];
- hb_ot_tags_from_script_and_language (script_out,
- HB_LANGUAGE_INVALID,
- &script_count,
- primary_script_tag,
- nullptr, nullptr);
- *language = hb_ot_tag_to_language (language_tag);
- if (script_count == 0 || primary_script_tag[0] != script_tag)
- {
- unsigned char *buf;
- const char *lang_str = hb_language_to_string (*language);
- size_t len = strlen (lang_str);
- buf = (unsigned char *) hb_malloc (len + 16);
- if (unlikely (!buf))
- {
- *language = nullptr;
- }
- else
- {
- int shift;
- hb_memcpy (buf, lang_str, len);
- if (lang_str[0] != 'x' || lang_str[1] != '-') {
- buf[len++] = '-';
- buf[len++] = 'x';
- }
- buf[len++] = '-';
- buf[len++] = 'h';
- buf[len++] = 'b';
- buf[len++] = 's';
- buf[len++] = 'c';
- buf[len++] = '-';
- for (shift = 28; shift >= 0; shift -= 4)
- buf[len++] = TOHEX (script_tag >> shift);
- *language = hb_language_from_string ((char *) buf, len);
- hb_free (buf);
- }
- }
+ unsigned char buf[11] = "x-hbot";
+ buf[6] = tag >> 24;
+ buf[7] = (tag >> 16) & 0xFF;
+ buf[8] = (tag >> 8) & 0xFF;
+ buf[9] = tag & 0xFF;
+ if (buf[9] == 0x20)
+ buf[9] = '\0';
+ buf[10] = '\0';
+ return hb_language_from_string ((char *) buf, -1);
}
}
#ifdef MAIN
static inline void
-test_langs_sorted ()
+test_langs_sorted (void)
{
- for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages2); i++)
+ for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++)
{
- int c = ot_languages2[i].cmp (&ot_languages2[i - 1]);
- if (c > 0)
+ int c = lang_compare_first_component (ot_languages[i-1].language, ot_languages[i].language);
+ if (c >= 0)
{
- fprintf (stderr, "ot_languages2 not sorted at index %u: %08x %d %08x\n",
- i, ot_languages2[i-1].language, c, ot_languages2[i].language);
+ fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n",
+ i, ot_languages[i-1].language, c, ot_languages[i].language);
abort();
}
}
-#ifndef HB_NO_LANGUAGE_LONG
- for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages3); i++)
- {
- int c = ot_languages3[i].cmp (&ot_languages3[i - 1]);
- if (c > 0)
- {
- fprintf (stderr, "ot_languages3 not sorted at index %u: %08x %d %08x\n",
- i, ot_languages3[i-1].language, c, ot_languages3[i].language);
- abort();
- }
- }
-#endif
}
int
-main ()
+main (void)
{
test_langs_sorted ();
return 0;
}
#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-glib.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
index 5f04183ba19..54fb747f582 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-glib.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h
@@ -1,6 +1,5 @@
/*
* Copyright © 2009 Red Hat, Inc.
- * Copyright © 2011 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -23,34 +22,38 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_GLIB_H
-#define HB_GLIB_H
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
-#include "hb.h"
+#ifndef HB_OT_TAG_H
+#define HB_OT_TAG_H
-#include <glib.h>
+#include "hb.h"
HB_BEGIN_DECLS
-HB_EXTERN hb_script_t
-hb_glib_script_to_script (GUnicodeScript script);
+#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
+#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
-HB_EXTERN GUnicodeScript
-hb_glib_script_from_script (hb_script_t script);
+HB_EXTERN void
+hb_ot_tags_from_script (hb_script_t script,
+ hb_tag_t *script_tag_1,
+ hb_tag_t *script_tag_2);
+HB_EXTERN hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag);
-HB_EXTERN hb_unicode_funcs_t *
-hb_glib_get_unicode_funcs (void);
+HB_EXTERN hb_tag_t
+hb_ot_tag_from_language (hb_language_t language);
+
+HB_EXTERN hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag);
-#if GLIB_CHECK_VERSION(2,31,10)
-HB_EXTERN hb_blob_t *
-hb_glib_blob_create (GBytes *gbytes);
-#endif
HB_END_DECLS
-#endif /* HB_GLIB_H */
+#endif /* HB_OT_TAG_H */
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
index 3449b30499d..4b88a403041 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh
@@ -27,212 +27,117 @@
#ifndef HB_OT_VAR_AVAR_TABLE_HH
#define HB_OT_VAR_AVAR_TABLE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-var-common.hh"
-
-
-/*
- * avar -- Axis Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/avar
- */
-
-#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
-
+#include "hb-open-type-private.hh"
namespace OT {
-/* "Spec": https://github.com/be-fonts/boring-expansion-spec/issues/14 */
-struct avarV2Tail
-{
- friend struct avar;
-
- bool sanitize (hb_sanitize_context_t *c,
- const void *base) const
- {
- TRACE_SANITIZE (this);
- return_trace (varIdxMap.sanitize (c, base) &&
- varStore.sanitize (c, base));
- }
-
- protected:
- Offset32To<DeltaSetIndexMap> varIdxMap; /* Offset from the beginning of 'avar' table. */
- Offset32To<VariationStore> varStore; /* Offset from the beginning of 'avar' table. */
-
- public:
- DEFINE_SIZE_STATIC (8);
-};
-
-
struct AxisValueMap
{
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
- F2DOT14 coords[2];
-// F2DOT14 fromCoord; /* A normalized coordinate value obtained using
-// * default normalization. */
-// F2DOT14 toCoord; /* The modified, normalized coordinate value. */
+ F2DOT14 fromCoord; /* A normalized coordinate value obtained using
+ * default normalization. */
+ F2DOT14 toCoord; /* The modified, normalized coordinate value. */
public:
DEFINE_SIZE_STATIC (4);
};
-struct SegmentMaps : Array16Of<AxisValueMap>
+struct SegmentMaps : ArrayOf<AxisValueMap>
{
- int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const
+ inline int map (int value) const
{
-#define fromCoord coords[from_offset].to_int ()
-#define toCoord coords[to_offset].to_int ()
/* 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 - arrayZ[0].fromCoord + arrayZ[0].toCoord;
+ return value - array[0].fromCoord + array[0].toCoord;
}
- if (value <= arrayZ[0].fromCoord)
- return value - arrayZ[0].fromCoord + arrayZ[0].toCoord;
+ if (value <= array[0].fromCoord)
+ return value - array[0].fromCoord + array[0].toCoord;
unsigned int i;
- unsigned int count = len - 1;
- for (i = 1; i < count && value > arrayZ[i].fromCoord; i++)
+ unsigned int count = len;
+ for (i = 1; i < count && value > array[i].fromCoord; i++)
;
- if (value >= arrayZ[i].fromCoord)
- return value - arrayZ[i].fromCoord + arrayZ[i].toCoord;
+ if (value >= array[i].fromCoord)
+ return value - array[i].fromCoord + array[i].toCoord;
- if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord))
- return arrayZ[i-1].toCoord;
+ if (unlikely (array[i-1].fromCoord == array[i].fromCoord))
+ return array[i-1].toCoord;
- int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord;
- return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
- (value - arrayZ[i-1].fromCoord)) / denom);
-#undef toCoord
-#undef fromCoord
+ 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;
}
- int unmap (int value) const { return map (value, 1, 0); }
-
- public:
- DEFINE_SIZE_ARRAY (2, *this);
+ DEFINE_SIZE_ARRAY (2, array);
};
-struct avar
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_avar;
-
- bool has_data () const { return version.to_int (); }
+/*
+ * avar — Axis Variations Table
+ */
- const SegmentMaps* get_segment_maps () const
- { return &firstAxisSegmentMaps; }
+#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
- unsigned get_axis_count () const
- { return axisCount; }
+struct avar
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_avar;
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- if (!(version.sanitize (c) &&
- (version.major == 1
-#ifndef HB_NO_AVAR2
- || version.major == 2
-#endif
- ) &&
- c->check_struct (this)))
+ if (unlikely (!(version.sanitize (c) &&
+ version.major == 1 &&
+ c->check_struct (this))))
return_trace (false);
- const SegmentMaps *map = &firstAxisSegmentMaps;
+ const SegmentMaps *map = &axisSegmentMapsZ;
unsigned int count = axisCount;
for (unsigned int i = 0; i < count; i++)
{
if (unlikely (!map->sanitize (c)))
- return_trace (false);
+ return_trace (false);
map = &StructAfter<SegmentMaps> (*map);
}
-#ifndef HB_NO_AVAR2
- if (version.major < 2)
- return_trace (true);
-
- const auto &v2 = * (const avarV2Tail *) map;
- if (unlikely (!v2.sanitize (c, this)))
- return_trace (false);
-#endif
-
return_trace (true);
}
- void map_coords (int *coords, unsigned int coords_length) const
+ inline void map_coords (int *coords, unsigned int coords_length) const
{
- unsigned int count = hb_min (coords_length, axisCount);
+ unsigned int count = MIN<unsigned int> (coords_length, axisCount);
- const SegmentMaps *map = &firstAxisSegmentMaps;
+ const SegmentMaps *map = &axisSegmentMapsZ;
for (unsigned int i = 0; i < count; i++)
{
coords[i] = map->map (coords[i]);
map = &StructAfter<SegmentMaps> (*map);
}
-
-#ifndef HB_NO_AVAR2
- if (version.major < 2)
- return;
-
- for (; count < axisCount; count++)
- map = &StructAfter<SegmentMaps> (*map);
-
- const auto &v2 = * (const avarV2Tail *) map;
-
- const auto &varidx_map = this+v2.varIdxMap;
- const auto &var_store = this+v2.varStore;
- auto *var_store_cache = var_store.create_cache ();
-
- hb_vector_t<int> out;
- out.alloc (coords_length);
- for (unsigned i = 0; i < coords_length; i++)
- {
- int v = coords[i];
- uint32_t varidx = varidx_map.map (i);
- float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache);
- v += roundf (delta);
- v = hb_clamp (v, -(1<<14), +(1<<14));
- out.push (v);
- }
- for (unsigned i = 0; i < coords_length; i++)
- coords[i] = out[i];
-
- OT::VariationStore::destroy_cache (var_store_cache);
-#endif
- }
-
- void unmap_coords (int *coords, unsigned int coords_length) const
- {
- unsigned int count = hb_min (coords_length, axisCount);
-
- const SegmentMaps *map = &firstAxisSegmentMaps;
- for (unsigned int i = 0; i < count; i++)
- {
- coords[i] = map->unmap (coords[i]);
- map = &StructAfter<SegmentMaps> (*map);
- }
}
protected:
FixedVersion<>version; /* Version of the avar table
* initially set to 0x00010000u */
- HBUINT16 reserved; /* This field is permanently reserved. Set to 0. */
- HBUINT16 axisCount; /* The number of variation axes in the font. This
+ 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 firstAxisSegmentMaps;
+ SegmentMaps axisSegmentMapsZ;
public:
DEFINE_SIZE_MIN (8);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh
deleted file mode 100644
index 853fe3839bd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright © 2021 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.
- *
- */
-
-#ifndef HB_OT_VAR_COMMON_HH
-#define HB_OT_VAR_COMMON_HH
-
-#include "hb-ot-layout-common.hh"
-
-
-namespace OT {
-
-template <typename MapCountT>
-struct DeltaSetIndexMapFormat01
-{
- friend struct DeltaSetIndexMap;
-
- private:
- DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- auto *out = c->start_embed (this);
- if (unlikely (!out)) return_trace (nullptr);
-
- unsigned total_size = min_size + mapCount * get_width ();
- HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
- if (unlikely (!p)) return_trace (nullptr);
-
- hb_memcpy (p, this, HBUINT8::static_size * total_size);
- return_trace (out);
- }
-
- template <typename T>
- bool serialize (hb_serialize_context_t *c, const T &plan)
- {
- unsigned int width = plan.get_width ();
- unsigned int inner_bit_count = plan.get_inner_bit_count ();
- const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
-
- TRACE_SERIALIZE (this);
- if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
- return_trace (false);
- if (unlikely (!c->extend_min (this))) return_trace (false);
-
- entryFormat = ((width-1)<<4)|(inner_bit_count-1);
- mapCount = output_map.length;
- HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
- if (unlikely (!p)) return_trace (false);
- for (unsigned int i = 0; i < output_map.length; i++)
- {
- unsigned int v = output_map[i];
- unsigned int outer = v >> 16;
- unsigned int inner = v & 0xFFFF;
- unsigned int u = (outer << inner_bit_count) | inner;
- for (unsigned int w = width; w > 0;)
- {
- p[--w] = u;
- u >>= 8;
- }
- p += width;
- }
- return_trace (true);
- }
-
- uint32_t 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 HBUINT8 *p = mapDataZ.arrayZ + w * v;
- for (; w; w--)
- u = (u << 8) + *p++;
- }
-
- { /* Repack it. */
- unsigned int n = get_inner_bit_count ();
- unsigned int outer = u >> n;
- unsigned int inner = u & ((1 << n) - 1);
- u = (outer<<16) | inner;
- }
-
- return u;
- }
-
- unsigned get_map_count () const { return mapCount; }
- unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; }
- unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
-
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- c->check_range (mapDataZ.arrayZ,
- mapCount,
- get_width ()));
- }
-
- protected:
- HBUINT8 format; /* Format identifier--format = 0 */
- HBUINT8 entryFormat; /* A packed field that describes the compressed
- * representation of delta-set indices. */
- MapCountT mapCount; /* The number of mapping entries. */
- UnsizedArrayOf<HBUINT8>
- mapDataZ; /* The delta-set index mapping data. */
-
- public:
- DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ);
-};
-
-struct DeltaSetIndexMap
-{
- template <typename T>
- bool serialize (hb_serialize_context_t *c, const T &plan)
- {
- TRACE_SERIALIZE (this);
- unsigned length = plan.get_output_map ().length;
- u.format = length <= 0xFFFF ? 0 : 1;
- switch (u.format) {
- case 0: return_trace (u.format0.serialize (c, plan));
- case 1: return_trace (u.format1.serialize (c, plan));
- default:return_trace (false);
- }
- }
-
- uint32_t map (unsigned v) const
- {
- switch (u.format) {
- case 0: return (u.format0.map (v));
- case 1: return (u.format1.map (v));
- default:return v;
- }
- }
-
- unsigned get_map_count () const
- {
- switch (u.format) {
- case 0: return u.format0.get_map_count ();
- case 1: return u.format1.get_map_count ();
- default:return 0;
- }
- }
-
- unsigned get_width () const
- {
- switch (u.format) {
- case 0: return u.format0.get_width ();
- case 1: return u.format1.get_width ();
- default:return 0;
- }
- }
-
- unsigned get_inner_bit_count () const
- {
- switch (u.format) {
- case 0: return u.format0.get_inner_bit_count ();
- case 1: return u.format1.get_inner_bit_count ();
- default:return 0;
- }
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (!u.format.sanitize (c)) return_trace (false);
- switch (u.format) {
- case 0: return_trace (u.format0.sanitize (c));
- case 1: return_trace (u.format1.sanitize (c));
- default:return_trace (true);
- }
- }
-
- DeltaSetIndexMap* copy (hb_serialize_context_t *c) const
- {
- TRACE_SERIALIZE (this);
- switch (u.format) {
- case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c)));
- case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c)));
- default:return_trace (nullptr);
- }
- }
-
- protected:
- union {
- HBUINT8 format; /* Format identifier */
- DeltaSetIndexMapFormat01<HBUINT16> format0;
- DeltaSetIndexMapFormat01<HBUINT32> format1;
- } u;
- public:
- DEFINE_SIZE_UNION (1, format);
-};
-
-
-struct VarStoreInstancer
-{
- VarStoreInstancer (const VariationStore *varStore,
- const DeltaSetIndexMap *varIdxMap,
- hb_array_t<int> coords) :
- varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
-
- operator bool () const { return varStore && bool (coords); }
-
- /* according to the spec, if colr table has varStore but does not have
- * varIdxMap, then an implicit identity mapping is used */
- float operator() (uint32_t varIdx, unsigned short offset = 0) const
- { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
-
- const VariationStore *varStore;
- const DeltaSetIndexMap *varIdxMap;
- hb_array_t<int> coords;
-};
-
-/* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
-struct TupleVariationHeader
-{
- unsigned get_size (unsigned axis_count) const
- { return min_size + get_all_tuples (axis_count).get_size (); }
-
- unsigned get_data_size () const { return varDataSize; }
-
- const TupleVariationHeader &get_next (unsigned axis_count) const
- { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); }
-
- float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count,
- const hb_array_t<const F2DOT14> shared_tuples,
- const hb_vector_t<int> *shared_tuple_active_idx = nullptr) const
- {
- const F2DOT14 *peak_tuple;
-
- unsigned start_idx = 0;
- unsigned end_idx = coord_count;
-
- if (has_peak ())
- peak_tuple = get_peak_tuple (coord_count).arrayZ;
- else
- {
- unsigned int index = get_index ();
- if (unlikely ((index + 1) * coord_count > shared_tuples.length))
- return 0.f;
- peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ;
-
- if (shared_tuple_active_idx)
- {
- assert (index < shared_tuple_active_idx->length);
- int v = (*shared_tuple_active_idx).arrayZ[index];
- if (v != -1)
- {
- start_idx = v;
- end_idx = start_idx + 1;
- }
- }
- }
-
- const F2DOT14 *start_tuple = nullptr;
- const F2DOT14 *end_tuple = nullptr;
- bool has_interm = has_intermediate ();
- if (has_interm)
- {
- start_tuple = get_start_tuple (coord_count).arrayZ;
- end_tuple = get_end_tuple (coord_count).arrayZ;
- }
-
- float scalar = 1.f;
- for (unsigned int i = start_idx; i < end_idx; i++)
- {
- int peak = peak_tuple[i].to_int ();
- if (!peak) continue;
-
- int v = coords[i];
- if (v == peak) continue;
-
- if (has_interm)
- {
- int start = start_tuple[i].to_int ();
- int end = end_tuple[i].to_int ();
- if (unlikely (start > peak || peak > end ||
- (start < 0 && end > 0 && peak))) continue;
- if (v < start || v > end) return 0.f;
- if (v < peak)
- { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
- else
- { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
- }
- else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f;
- else
- scalar *= (float) v / peak;
- }
- return scalar;
- }
-
- bool has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; }
- bool has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; }
- bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; }
- unsigned get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; }
-
- protected:
- struct TuppleIndex : HBUINT16
- {
- enum Flags {
- EmbeddedPeakTuple = 0x8000u,
- IntermediateRegion = 0x4000u,
- PrivatePointNumbers = 0x2000u,
- TupleIndexMask = 0x0FFFu
- };
-
- DEFINE_SIZE_STATIC (2);
- };
-
- hb_array_t<const F2DOT14> get_all_tuples (unsigned axis_count) const
- { return StructAfter<UnsizedArrayOf<F2DOT14>> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); }
- hb_array_t<const F2DOT14> get_peak_tuple (unsigned axis_count) const
- { return get_all_tuples (axis_count).sub_array (0, axis_count); }
- hb_array_t<const F2DOT14> get_start_tuple (unsigned axis_count) const
- { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); }
- hb_array_t<const F2DOT14> get_end_tuple (unsigned axis_count) const
- { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); }
-
- HBUINT16 varDataSize; /* The size in bytes of the serialized
- * data for this tuple variation table. */
- TuppleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below).
- The low 12 bits are an index into a shared tuple
- records array. */
- /* UnsizedArrayOf<F2DOT14> peakTuple - optional */
- /* Peak tuple record for this tuple variation table — optional,
- * determined by flags in the tupleIndex value.
- *
- * Note that this must always be included in the 'cvar' table. */
- /* UnsizedArrayOf<F2DOT14> intermediateStartTuple - optional */
- /* Intermediate start tuple record for this tuple variation table — optional,
- determined by flags in the tupleIndex value. */
- /* UnsizedArrayOf<F2DOT14> intermediateEndTuple - optional */
- /* Intermediate end tuple record for this tuple variation table — optional,
- * determined by flags in the tupleIndex value. */
- public:
- DEFINE_SIZE_MIN (4);
-};
-
-struct TupleVariationData
-{
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- // here check on min_size only, TupleVariationHeader and var data will be
- // checked while accessing through iterator.
- return_trace (c->check_struct (this));
- }
-
- unsigned get_size (unsigned axis_count) const
- {
- unsigned total_size = min_size;
- unsigned count = tupleVarCount;
- const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header());
- for (unsigned i = 0; i < count; i++)
- {
- total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size ();
- tuple_var_header = &tuple_var_header->get_next (axis_count);
- }
-
- return total_size;
- }
-
- const TupleVariationHeader &get_tuple_var_header (void) const
- { return StructAfter<TupleVariationHeader> (data); }
-
- struct tuple_iterator_t
- {
- void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_, const void *table_base_)
- {
- var_data_bytes = var_data_bytes_;
- var_data = var_data_bytes_.as<TupleVariationData> ();
- index = 0;
- axis_count = axis_count_;
- current_tuple = &var_data->get_tuple_var_header ();
- data_offset = 0;
- table_base = table_base_;
- }
-
- bool get_shared_indices (hb_vector_t<unsigned int> &shared_indices /* OUT */)
- {
- if (var_data->has_shared_point_numbers ())
- {
- const HBUINT8 *base = &(table_base+var_data->data);
- const HBUINT8 *p = base;
- if (!unpack_points (p, shared_indices, (const HBUINT8 *) (var_data_bytes.arrayZ + var_data_bytes.length))) return false;
- data_offset = p - base;
- }
- return true;
- }
-
- bool is_valid () const
- {
- return (index < var_data->tupleVarCount.get_count ()) &&
- var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
- var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (),
- current_tuple->get_size (axis_count)));
- }
-
- bool move_to_next ()
- {
- data_offset += current_tuple->get_data_size ();
- current_tuple = &current_tuple->get_next (axis_count);
- index++;
- return is_valid ();
- }
-
- const HBUINT8 *get_serialized_data () const
- { return &(table_base+var_data->data) + data_offset; }
-
- private:
- const TupleVariationData *var_data;
- unsigned int index;
- unsigned int axis_count;
- unsigned int data_offset;
- const void *table_base;
-
- public:
- hb_bytes_t var_data_bytes;
- const TupleVariationHeader *current_tuple;
- };
-
- static bool get_tuple_iterator (hb_bytes_t var_data_bytes, unsigned axis_count,
- const void *table_base,
- hb_vector_t<unsigned int> &shared_indices /* OUT */,
- tuple_iterator_t *iterator /* OUT */)
- {
- iterator->init (var_data_bytes, axis_count, table_base);
- if (!iterator->get_shared_indices (shared_indices))
- return false;
- return iterator->is_valid ();
- }
-
- bool has_shared_point_numbers () const { return tupleVarCount.has_shared_point_numbers (); }
-
- static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
- hb_vector_t<unsigned int> &points /* OUT */,
- const HBUINT8 *end)
- {
- enum packed_point_flag_t
- {
- POINTS_ARE_WORDS = 0x80,
- POINT_RUN_COUNT_MASK = 0x7F
- };
-
- if (unlikely (p + 1 > end)) return false;
-
- unsigned count = *p++;
- if (count & POINTS_ARE_WORDS)
- {
- if (unlikely (p + 1 > end)) return false;
- count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
- }
- if (unlikely (!points.resize (count, false))) return false;
-
- unsigned n = 0;
- unsigned i = 0;
- while (i < count)
- {
- if (unlikely (p + 1 > end)) return false;
- unsigned control = *p++;
- unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
- unsigned stop = i + run_count;
- if (unlikely (stop > count)) return false;
- if (control & POINTS_ARE_WORDS)
- {
- if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
- for (; i < stop; i++)
- {
- n += *(const HBUINT16 *)p;
- points.arrayZ[i] = n;
- p += HBUINT16::static_size;
- }
- }
- else
- {
- if (unlikely (p + run_count > end)) return false;
- for (; i < stop; i++)
- {
- n += *p++;
- points.arrayZ[i] = n;
- }
- }
- }
- return true;
- }
-
- static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
- hb_vector_t<int> &deltas /* IN/OUT */,
- const HBUINT8 *end)
- {
- enum packed_delta_flag_t
- {
- DELTAS_ARE_ZERO = 0x80,
- DELTAS_ARE_WORDS = 0x40,
- DELTA_RUN_COUNT_MASK = 0x3F
- };
-
- unsigned i = 0;
- unsigned count = deltas.length;
- while (i < count)
- {
- if (unlikely (p + 1 > end)) return false;
- unsigned control = *p++;
- unsigned run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
- unsigned stop = i + run_count;
- if (unlikely (stop > count)) return false;
- if (control & DELTAS_ARE_ZERO)
- {
- for (; i < stop; i++)
- deltas.arrayZ[i] = 0;
- }
- else if (control & DELTAS_ARE_WORDS)
- {
- if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
- for (; i < stop; i++)
- {
- deltas.arrayZ[i] = * (const HBINT16 *) p;
- p += HBUINT16::static_size;
- }
- }
- else
- {
- if (unlikely (p + run_count > end)) return false;
- for (; i < stop; i++)
- {
- deltas.arrayZ[i] = * (const HBINT8 *) p++;
- }
- }
- }
- return true;
- }
-
- bool has_data () const { return tupleVarCount; }
-
- protected:
- struct TupleVarCount : HBUINT16
- {
- bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
- unsigned int get_count () const { return (*this) & CountMask; }
-
- protected:
- enum Flags
- {
- SharedPointNumbers= 0x8000u,
- CountMask = 0x0FFFu
- };
- public:
- DEFINE_SIZE_STATIC (2);
- };
-
- TupleVarCount tupleVarCount; /* A packed field. The high 4 bits are flags, and the
- * low 12 bits are the number of tuple variation tables
- * for this glyph. The number of tuple variation tables
- * can be any number between 1 and 4095. */
- Offset16To<HBUINT8>
- data; /* Offset from the start of the base table
- * to the serialized data. */
- /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */
- public:
- DEFINE_SIZE_MIN (4);
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_VAR_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh
deleted file mode 100644
index bdb2b6b23bd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright © 2023 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.
- *
- */
-
-#ifndef HB_OT_VAR_CVAR_TABLE_HH
-#define HB_OT_VAR_CVAR_TABLE_HH
-
-#include "hb-ot-var-common.hh"
-
-
-namespace OT {
-/*
- * cvar -- control value table (CVT) Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cvar
- */
-#define HB_OT_TAG_cvar HB_TAG('c','v','a','r')
-
-struct cvar
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cvar;
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- version.sanitize (c) && likely (version.major == 1) &&
- tupleVariationData.sanitize (c));
- }
-
- const TupleVariationData* get_tuple_var_data (void) const
- { return &tupleVariationData; }
-
- static bool calculate_cvt_deltas (unsigned axis_count,
- hb_array_t<int> coords,
- unsigned num_cvt_item,
- const TupleVariationData *tuple_var_data,
- const void *base,
- hb_vector_t<float>& cvt_deltas /* OUT */)
- {
- if (!coords) return true;
- hb_vector_t<unsigned> shared_indices;
- TupleVariationData::tuple_iterator_t iterator;
- unsigned var_data_length = tuple_var_data->get_size (axis_count);
- hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (tuple_var_data), var_data_length);
- if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base,
- shared_indices, &iterator))
- return true; /* isn't applied at all */
-
- hb_array_t<const F2DOT14> shared_tuples = hb_array<F2DOT14> ();
- hb_vector_t<unsigned> private_indices;
- hb_vector_t<int> unpacked_deltas;
-
- do
- {
- float scalar = iterator.current_tuple->calculate_scalar (coords, axis_count, shared_tuples);
- if (scalar == 0.f) continue;
- const HBUINT8 *p = iterator.get_serialized_data ();
- unsigned int length = iterator.current_tuple->get_data_size ();
- if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
- return false;
-
- const HBUINT8 *end = p + length;
-
- bool has_private_points = iterator.current_tuple->has_private_points ();
- if (has_private_points &&
- !TupleVariationData::unpack_points (p, private_indices, end))
- return false;
- const hb_vector_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices;
-
- bool apply_to_all = (indices.length == 0);
- unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length;
- if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false;
- if (unlikely (!TupleVariationData::unpack_deltas (p, unpacked_deltas, end))) return false;
-
- for (unsigned int i = 0; i < num_deltas; i++)
- {
- unsigned int idx = apply_to_all ? i : indices[i];
- if (unlikely (idx >= num_cvt_item)) continue;
- if (scalar != 1.0f) cvt_deltas[idx] += unpacked_deltas[i] * scalar ;
- else cvt_deltas[idx] += unpacked_deltas[i];
- }
- } while (iterator.move_to_next ());
-
- return true;
- }
-
- static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan,
- const TupleVariationData *tuple_var_data,
- const void *base)
- {
- const hb_tag_t cvt = HB_TAG('c','v','t',' ');
- hb_blob_t *cvt_blob = hb_face_reference_table (plan->source, cvt);
- hb_blob_t *cvt_prime_blob = hb_blob_copy_writable_or_fail (cvt_blob);
- hb_blob_destroy (cvt_blob);
-
- if (unlikely (!cvt_prime_blob))
- return false;
-
- unsigned cvt_blob_length = hb_blob_get_length (cvt_prime_blob);
- unsigned num_cvt_item = cvt_blob_length / FWORD::static_size;
-
- hb_vector_t<float> cvt_deltas;
- if (unlikely (!cvt_deltas.resize (num_cvt_item)))
- {
- hb_blob_destroy (cvt_prime_blob);
- return false;
- }
- hb_memset (cvt_deltas.arrayZ, 0, cvt_deltas.get_size ());
-
- if (!calculate_cvt_deltas (plan->normalized_coords.length, plan->normalized_coords.as_array (),
- num_cvt_item, tuple_var_data, base, cvt_deltas))
- {
- hb_blob_destroy (cvt_prime_blob);
- return false;
- }
-
- FWORD *cvt_prime = (FWORD *) hb_blob_get_data_writable (cvt_prime_blob, nullptr);
- for (unsigned i = 0; i < num_cvt_item; i++)
- cvt_prime[i] += (int) roundf (cvt_deltas[i]);
-
- bool success = plan->add_table (cvt, cvt_prime_blob);
- hb_blob_destroy (cvt_prime_blob);
- return success;
- }
-
- protected:
- FixedVersion<>version; /* Version of the CVT variation table
- * initially set to 0x00010000u */
- TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */
- public:
- DEFINE_SIZE_MIN (8);
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_VAR_CVAR_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
index a384dfa531d..2a9357a5e2d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh
@@ -27,407 +27,177 @@
#ifndef HB_OT_VAR_FVAR_TABLE_HH
#define HB_OT_VAR_FVAR_TABLE_HH
-#include "hb-open-type.hh"
-
-/*
- * fvar -- Font Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/fvar
- */
-
-#define HB_OT_TAG_fvar HB_TAG('f','v','a','r')
-
+#include "hb-open-type-private.hh"
namespace OT {
struct InstanceRecord
{
- friend struct fvar;
-
- hb_array_t<const F16DOT16> get_coordinates (unsigned int axis_count) const
- { return coordinatesZ.as_array (axis_count); }
-
- bool subset (hb_subset_context_t *c,
- unsigned axis_count,
- bool has_postscript_nameid) const
- {
- TRACE_SUBSET (this);
- if (unlikely (!c->serializer->embed (subfamilyNameID))) return_trace (false);
- if (unlikely (!c->serializer->embed (flags))) return_trace (false);
-
- const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
- const hb_hashmap_t<hb_tag_t, float> *axes_location = &c->plan->user_axes_location;
- for (unsigned i = 0 ; i < axis_count; i++)
- {
- uint32_t *axis_tag;
- // only keep instances whose coordinates == pinned axis location
- if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue;
-
- if (axes_location->has (*axis_tag) &&
- fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f)
- return_trace (false);
-
- if (!c->plan->axes_index_map.has (i))
- continue;
-
- if (!c->serializer->embed (coords[i]))
- return_trace (false);
- }
-
- if (has_postscript_nameid)
- {
- NameID name_id;
- name_id = StructAfter<NameID> (coords);
- if (!c->serializer->embed (name_id))
- return_trace (false);
- }
-
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
+ 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 (coordinatesZ.arrayZ, axis_count));
+ c->check_array (coordinates, coordinates[0].static_size, axis_count));
}
protected:
- NameID subfamilyNameID;/* The name ID for entries in the 'name' table
+ UINT16 subfamilyNameID;/* The name ID for entries in the 'name' table
* that provide subfamily names for this instance. */
- HBUINT16 flags; /* Reserved for future use — set to 0. */
- UnsizedArrayOf<F16DOT16>
- coordinatesZ; /* The coordinates array for this instance. */
- //NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
+ 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_UNBOUNDED (4);
+ DEFINE_SIZE_ARRAY (4, coordinates);
};
struct AxisRecord
{
- int cmp (hb_tag_t key) const { return axisTag.cmp (key); }
-
- enum
- {
- AXIS_FLAG_HIDDEN = 0x0001,
- };
-
-#ifndef HB_DISABLE_DEPRECATED
- void get_axis_deprecated (hb_ot_var_axis_t *info) const
- {
- info->tag = axisTag;
- info->name_id = axisNameID;
- get_coordinates (info->min_value, info->default_value, info->max_value);
- }
-#endif
-
- void get_axis_info (unsigned axis_index, hb_ot_var_axis_info_t *info) const
- {
- info->axis_index = axis_index;
- info->tag = axisTag;
- info->name_id = axisNameID;
- info->flags = (hb_ot_var_axis_flags_t) (unsigned int) flags;
- get_coordinates (info->min_value, info->default_value, info->max_value);
- info->reserved = 0;
- }
-
- hb_tag_t get_axis_tag () const { return axisTag; }
-
- int normalize_axis_value (float v) const
- {
- float min_value, default_value, max_value;
- get_coordinates (min_value, default_value, max_value);
-
- v = hb_clamp (v, min_value, max_value);
-
- if (v == default_value)
- return 0;
- else if (v < default_value)
- v = (v - default_value) / (default_value - min_value);
- else
- v = (v - default_value) / (max_value - default_value);
- return roundf (v * 16384.f);
- }
-
- float unnormalize_axis_value (int v) const
- {
- float min_value, default_value, max_value;
- get_coordinates (min_value, default_value, max_value);
-
- if (v == 0)
- return default_value;
- else if (v < 0)
- return v * (default_value - min_value) / 16384.f + default_value;
- else
- return v * (max_value - default_value) / 16384.f + default_value;
- }
-
- hb_ot_name_id_t get_name_id () const { return axisNameID; }
-
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
- void get_coordinates (float &min, float &default_, float &max) const
- {
- default_ = defaultValue.to_float ();
- /* Ensure order, to simplify client math. */
- min = hb_min (default_, minValue.to_float ());
- max = hb_max (default_, maxValue.to_float ());
- }
-
- float get_default () const
- {
- return defaultValue.to_float ();
- }
-
public:
Tag axisTag; /* Tag identifying the design variation for the axis. */
- protected:
- F16DOT16 minValue; /* The minimum coordinate value for the axis. */
- F16DOT16 defaultValue; /* The default coordinate value for the axis. */
- F16DOT16 maxValue; /* The maximum coordinate value for the axis. */
- public:
- HBUINT16 flags; /* Axis flags. */
- NameID axisNameID; /* The name ID for entries in the 'name' table that
+ 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 constexpr hb_tag_t tableTag = HB_OT_TAG_fvar;
-
- bool has_data () const { return version.to_int (); }
+ static const hb_tag_t tableTag = HB_OT_TAG_fvar;
- bool sanitize (hb_sanitize_context_t *c) const
+ 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) &&
- axisSize == 20 && /* Assumed in our code. */
instanceSize >= axisCount * 4 + 4 &&
- get_axes ().sanitize (c) &&
- c->check_range (get_instance (0), instanceCount, instanceSize));
+ 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));
}
- unsigned int get_axis_count () const { return axisCount; }
+ inline unsigned int get_axis_count (void) const
+ { return axisCount; }
-#ifndef HB_DISABLE_DEPRECATED
- unsigned int get_axes_deprecated (unsigned int start_offset,
- unsigned int *axes_count /* IN/OUT */,
- hb_ot_var_axis_t *axes_array /* OUT */) const
+ inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const
{
- if (axes_count)
- {
- hb_array_t<const AxisRecord> arr = get_axes ().sub_array (start_offset, axes_count);
- for (unsigned i = 0; i < arr.length; ++i)
- arr[i].get_axis_deprecated (&axes_array[i]);
- }
- return axisCount;
- }
-#endif
+ if (unlikely (index >= axisCount))
+ return false;
- unsigned int get_axis_infos (unsigned int start_offset,
- unsigned int *axes_count /* IN/OUT */,
- hb_ot_var_axis_info_t *axes_array /* OUT */) const
- {
- if (axes_count)
+ if (info)
{
- hb_array_t<const AxisRecord> arr = get_axes ().sub_array (start_offset, axes_count);
- for (unsigned i = 0; i < arr.length; ++i)
- arr[i].get_axis_info (start_offset + i, &axes_array[i]);
+ 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 axisCount;
- }
-#ifndef HB_DISABLE_DEPRECATED
- bool
- find_axis_deprecated (hb_tag_t tag, unsigned *axis_index, hb_ot_var_axis_t *info) const
- {
- unsigned i;
- if (!axis_index) axis_index = &i;
- *axis_index = HB_OT_VAR_NO_AXIS_INDEX;
- auto axes = get_axes ();
- return axes.lfind (tag, axis_index) && ((void) axes[*axis_index].get_axis_deprecated (info), true);
+ return true;
}
-#endif
- bool
- find_axis_info (hb_tag_t tag, hb_ot_var_axis_info_t *info) const
- {
- unsigned i;
- auto axes = get_axes ();
- return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true);
- }
-
- int normalize_axis_value (unsigned int axis_index, float v) const
- { return get_axes ()[axis_index].normalize_axis_value (v); }
-
- float unnormalize_axis_value (unsigned int axis_index, int v) const
- { return get_axes ()[axis_index].unnormalize_axis_value (v); }
- unsigned int get_instance_count () const { return instanceCount; }
-
- hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const
+ 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
{
- const InstanceRecord *instance = get_instance (instance_index);
- if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID;
- return instance->subfamilyNameID;
- }
+ if (axes_count)
+ {
+ unsigned int count = axisCount;
+ start_offset = MIN (start_offset, count);
- hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const
- {
- const InstanceRecord *instance = get_instance (instance_index);
- if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID;
- if (instanceSize >= axisCount * 4 + 6)
- return StructAfter<NameID> (instance->get_coordinates (axisCount));
- return HB_OT_NAME_ID_INVALID;
- }
+ count -= start_offset;
+ axes_array += start_offset;
- unsigned int get_instance_coords (unsigned int instance_index,
- unsigned int *coords_length, /* IN/OUT */
- float *coords /* OUT */) const
- {
- const InstanceRecord *instance = get_instance (instance_index);
- if (unlikely (!instance))
- {
- if (coords_length)
- *coords_length = 0;
- return 0;
- }
+ count = MIN (count, *axes_count);
+ *axes_count = count;
- if (coords_length && *coords_length)
- {
- hb_array_t<const F16DOT16> instanceCoords = instance->get_coordinates (axisCount)
- .sub_array (0, coords_length);
- for (unsigned int i = 0; i < instanceCoords.length; i++)
- coords[i] = instanceCoords.arrayZ[i].to_float ();
+ for (unsigned int i = 0; i < count; i++)
+ get_axis (start_offset + i, axes_array + i);
}
return axisCount;
}
- void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
- hb_set_t *nameids /* IN/OUT */) const
+ inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const
{
- if (!has_data ()) return;
- hb_map_t pinned_axes;
-
- auto axis_records = get_axes ();
- for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
- {
- hb_tag_t axis_tag = axis_records[i].get_axis_tag ();
- if (user_axes_location->has (axis_tag))
- {
- pinned_axes.set (i, axis_tag);
- continue;
- }
-
- nameids->add (axis_records[i].get_name_id ());
- }
-
- for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
- {
- const InstanceRecord *instance = get_instance (i);
-
- if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
- | hb_filter (pinned_axes, hb_first)
- | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _)
- {
- hb_tag_t axis_tag = pinned_axes.get (_.first);
- float location = user_axes_location->get (axis_tag);
- if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
- return false;
- })
- ))
- continue;
-
- nameids->add (instance->subfamilyNameID);
-
- if (instanceSize >= axisCount * 4 + 6)
+ const AxisRecord *axes = get_axes ();
+ unsigned int count = get_axis_count ();
+ for (unsigned int i = 0; i < count; i++)
+ if (axes[i].axisTag == tag)
{
- unsigned post_script_name_id = StructAfter<NameID> (instance->get_coordinates (axisCount));
- if (post_script_name_id != HB_OT_NAME_ID_INVALID) nameids->add (post_script_name_id);
+ if (index)
+ *index = i;
+ return get_axis (i, info);
}
- }
+ if (index)
+ *index = HB_OT_VAR_NO_AXIS_INDEX;
+ return false;
}
- bool subset (hb_subset_context_t *c) const
+ inline int normalize_axis_value (unsigned int axis_index, float v) const
{
- TRACE_SUBSET (this);
- unsigned retained_axis_count = c->plan->axes_index_map.get_population ();
- if (!retained_axis_count) //all axes are pinned
- return_trace (false);
-
- fvar *out = c->serializer->embed (this);
- if (unlikely (!out)) return_trace (false);
-
- if (!c->serializer->check_assign (out->axisCount, retained_axis_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- bool has_postscript_nameid = false;
- if (instanceSize >= axisCount * 4 + 6)
- has_postscript_nameid = true;
-
- if (!c->serializer->check_assign (out->instanceSize, retained_axis_count * 4 + (has_postscript_nameid ? 6 : 4),
- HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
-
- auto axes_records = get_axes ();
- for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
- {
- if (!c->plan->axes_index_map.has (i)) continue;
- if (unlikely (!c->serializer->embed (axes_records[i])))
- return_trace (false);
- }
+ hb_ot_var_axis_t axis;
+ if (!get_axis (axis_index, &axis))
+ return 0;
- if (!c->serializer->check_assign (out->firstAxis, get_size (), HB_SERIALIZE_ERROR_INT_OVERFLOW))
- return_trace (false);
+ v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
- for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
- {
- const InstanceRecord *instance = get_instance (i);
- auto snap = c->serializer->snapshot ();
- if (!instance->subset (c, axisCount, has_postscript_nameid))
- c->serializer->revert (snap);
- }
- return_trace (true);
+ 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));
}
- public:
- hb_array_t<const AxisRecord> get_axes () const
- { return hb_array (&(this+firstAxis), axisCount); }
+ protected:
+ inline const AxisRecord * get_axes (void) const
+ { return &StructAtOffset<AxisRecord> (this, things); }
- const InstanceRecord *get_instance (unsigned int i) const
- {
- if (unlikely (i >= instanceCount)) return nullptr;
- return &StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()),
- i * instanceSize);
- }
+ 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 */
- Offset16To<AxisRecord>
- firstAxis; /* Offset in bytes from the beginning of the table
+ Offset16 things; /* Offset in bytes from the beginning of the table
* to the start of the AxisRecord array. */
- HBUINT16 reserved; /* This field is permanently reserved. Set to 2. */
- HBUINT16 axisCount; /* The number of variation axes in the font (the
+ 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). */
- HBUINT16 axisSize; /* The size in bytes of each VariationAxisRecord —
+ UINT16 axisSize; /* The size in bytes of each VariationAxisRecord —
* set to 20 (0x0014) for this version. */
- HBUINT16 instanceCount; /* The number of named instances defined in the font
+ UINT16 instanceCount; /* The number of named instances defined in the font
* (the number of records in the instances array). */
- HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
- * to either axisCount * sizeof(F16DOT16) + 4, or to
- * axisCount * sizeof(F16DOT16) + 6. */
+ 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);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh
deleted file mode 100644
index 4752a08fbe0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright © 2019 Adobe Inc.
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_OT_VAR_GVAR_TABLE_HH
-#define HB_OT_VAR_GVAR_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-var-common.hh"
-
-/*
- * gvar -- Glyph Variation Table
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar
- */
-#define HB_OT_TAG_gvar HB_TAG('g','v','a','r')
-
-namespace OT {
-
-struct contour_point_t
-{
- void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
- { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
-
- void translate (const contour_point_t &p) { x += p.x; y += p.y; }
-
- float x = 0.f;
- float y = 0.f;
- uint8_t flag = 0;
- bool is_end_point = false;
-};
-
-struct contour_point_vector_t : hb_vector_t<contour_point_t>
-{
- void extend (const hb_array_t<contour_point_t> &a)
- {
- unsigned int old_len = length;
- if (unlikely (!resize (old_len + a.length, false)))
- return;
- auto arrayZ = this->arrayZ + old_len;
- unsigned count = a.length;
- hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
- }
-
- void transform (const float (&matrix)[4])
- {
- if (matrix[0] == 1.f && matrix[1] == 0.f &&
- matrix[2] == 0.f && matrix[3] == 1.f)
- return;
- auto arrayZ = this->arrayZ;
- unsigned count = length;
- for (unsigned i = 0; i < count; i++)
- {
- contour_point_t &p = arrayZ[i];
- float x_ = p.x * matrix[0] + p.y * matrix[2];
- p.y = p.x * matrix[1] + p.y * matrix[3];
- p.x = x_;
- }
- }
-
- void translate (const contour_point_t& delta)
- {
- if (delta.x == 0.f && delta.y == 0.f)
- return;
- auto arrayZ = this->arrayZ;
- unsigned count = length;
- for (unsigned i = 0; i < count; i++)
- arrayZ[i].translate (delta);
- }
-};
-
-struct GlyphVariationData : TupleVariationData
-{};
-
-struct gvar
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar;
-
- bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && (version.major == 1) &&
- sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) &&
- (is_long_offset () ?
- c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) :
- c->check_array (get_short_offset_array (), c->get_num_glyphs () + 1)));
- }
-
- /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
- bool sanitize (hb_sanitize_context_t *c) const
- { return sanitize_shallow (c); }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
-
- unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
-
- gvar *out = c->serializer->allocate_min<gvar> ();
- if (unlikely (!out)) return_trace (false);
-
- out->version.major = 1;
- out->version.minor = 0;
- out->axisCount = axisCount;
- out->sharedTupleCount = sharedTupleCount;
-
- unsigned int num_glyphs = c->plan->num_output_glyphs ();
- out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
-
- unsigned int subset_data_size = 0;
- for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
- gid < num_glyphs;
- gid++)
- {
- hb_codepoint_t old_gid;
- if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
- subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length;
- }
-
- bool long_offset = subset_data_size & ~0xFFFFu;
- out->flags = long_offset ? 1 : 0;
-
- HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1));
- if (!subset_offsets) return_trace (false);
-
- /* shared tuples */
- if (!sharedTupleCount || !sharedTuples)
- out->sharedTuples = 0;
- else
- {
- unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount;
- F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
- if (!tuples) return_trace (false);
- out->sharedTuples = (char *) tuples - (char *) out;
- hb_memcpy (tuples, this+sharedTuples, shared_tuple_size);
- }
-
- char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
- if (!subset_data) return_trace (false);
- out->dataZ = subset_data - (char *) out;
-
- unsigned int glyph_offset = 0;
- for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
- gid < num_glyphs;
- gid++)
- {
- hb_codepoint_t old_gid;
- hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid)
- ? get_glyph_var_data_bytes (c->source_blob,
- glyph_count,
- old_gid)
- : hb_bytes_t ();
-
- if (long_offset)
- ((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
- else
- ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
-
- if (var_data_bytes.length > 0)
- hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
- subset_data += var_data_bytes.length;
- glyph_offset += var_data_bytes.length;
- }
- if (long_offset)
- ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
- else
- ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2;
-
- return_trace (true);
- }
-
- protected:
- const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob,
- unsigned glyph_count,
- hb_codepoint_t glyph) const
- {
- unsigned start_offset = get_offset (glyph_count, glyph);
- unsigned end_offset = get_offset (glyph_count, glyph+1);
- if (unlikely (end_offset < start_offset)) return hb_bytes_t ();
- unsigned length = end_offset - start_offset;
- hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length);
- return likely (var_data.length >= GlyphVariationData::min_size) ? var_data : hb_bytes_t ();
- }
-
- bool is_long_offset () const { return flags & 1; }
-
- unsigned get_offset (unsigned glyph_count, unsigned i) const
- {
- if (unlikely (i > glyph_count)) return 0;
- _hb_compiler_memory_r_barrier ();
- return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2;
- }
-
- const HBUINT32 * get_long_offset_array () const { return (const HBUINT32 *) &offsetZ; }
- const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *) &offsetZ; }
-
- public:
- struct accelerator_t
- {
- accelerator_t (hb_face_t *face)
- {
- table = hb_sanitize_context_t ().reference_table<gvar> (face);
- /* If sanitize failed, set glyphCount to 0. */
- glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0;
-
- /* For shared tuples that only have one axis active, shared the index of
- * that axis as a cache. This will speed up caclulate_scalar() a lot
- * for fonts with lots of axes and many "monovar" tuples. */
- hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
- unsigned count = table->sharedTupleCount;
- if (unlikely (!shared_tuple_active_idx.resize (count, false))) return;
- unsigned axis_count = table->axisCount;
- for (unsigned i = 0; i < count; i++)
- {
- hb_array_t<const F2DOT14> tuple = shared_tuples.sub_array (axis_count * i, axis_count);
- int idx = -1;
- for (unsigned j = 0; j < axis_count; j++)
- {
- F2DOT14 peak = tuple.arrayZ[j];
- if (peak.to_int () != 0)
- {
- if (idx != -1)
- {
- idx = -1;
- break;
- }
- idx = j;
- }
- }
- shared_tuple_active_idx[i] = idx;
- }
- }
- ~accelerator_t () { table.destroy (); }
-
- private:
-
- static float infer_delta (const hb_array_t<contour_point_t> points,
- const hb_array_t<contour_point_t> deltas,
- unsigned int target, unsigned int prev, unsigned int next,
- float contour_point_t::*m)
- {
- float target_val = points.arrayZ[target].*m;
- float prev_val = points.arrayZ[prev].*m;
- float next_val = points.arrayZ[next].*m;
- float prev_delta = deltas.arrayZ[prev].*m;
- float next_delta = deltas.arrayZ[next].*m;
-
- if (prev_val == next_val)
- return (prev_delta == next_delta) ? prev_delta : 0.f;
- else if (target_val <= hb_min (prev_val, next_val))
- return (prev_val < next_val) ? prev_delta : next_delta;
- else if (target_val >= hb_max (prev_val, next_val))
- return (prev_val > next_val) ? prev_delta : next_delta;
-
- /* linear interpolation */
- float r = (target_val - prev_val) / (next_val - prev_val);
- return prev_delta + r * (next_delta - prev_delta);
- }
-
- static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
- { return (i >= end) ? start : (i + 1); }
-
- public:
- bool apply_deltas_to_points (hb_codepoint_t glyph,
- hb_array_t<int> coords,
- const hb_array_t<contour_point_t> points) const
- {
- if (!coords) return true;
-
- if (unlikely (glyph >= glyphCount)) return true;
-
- hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph);
- if (!var_data_bytes.as<GlyphVariationData> ()->has_data ()) return true;
- hb_vector_t<unsigned int> shared_indices;
- GlyphVariationData::tuple_iterator_t iterator;
- if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount,
- var_data_bytes.arrayZ,
- shared_indices, &iterator))
- return true; /* so isn't applied at all */
-
- /* Save original points for inferred delta calculation */
- contour_point_vector_t orig_points_vec; // Populated lazily
- auto orig_points = orig_points_vec.as_array ();
-
- /* flag is used to indicate referenced point */
- contour_point_vector_t deltas_vec; // Populated lazily
- auto deltas = deltas_vec.as_array ();
-
- hb_vector_t<unsigned> end_points; // Populated lazily
-
- unsigned num_coords = table->axisCount;
- hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
-
- hb_vector_t<unsigned int> private_indices;
- hb_vector_t<int> x_deltas;
- hb_vector_t<int> y_deltas;
- bool flush = false;
- do
- {
- float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
- shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
- if (scalar == 0.f) continue;
- const HBUINT8 *p = iterator.get_serialized_data ();
- unsigned int length = iterator.current_tuple->get_data_size ();
- if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
- return false;
-
- if (!deltas)
- {
- if (unlikely (!deltas_vec.resize (points.length))) return false;
- deltas = deltas_vec.as_array ();
- }
-
- const HBUINT8 *end = p + length;
-
- bool has_private_points = iterator.current_tuple->has_private_points ();
- if (has_private_points &&
- !GlyphVariationData::unpack_points (p, private_indices, end))
- return false;
- const hb_array_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices;
-
- bool apply_to_all = (indices.length == 0);
- unsigned int num_deltas = apply_to_all ? points.length : indices.length;
- if (unlikely (!x_deltas.resize (num_deltas, false))) return false;
- if (unlikely (!GlyphVariationData::unpack_deltas (p, x_deltas, end))) return false;
- if (unlikely (!y_deltas.resize (num_deltas, false))) return false;
- if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
-
- if (!apply_to_all)
- {
- if (!orig_points)
- {
- orig_points_vec.extend (points);
- if (unlikely (orig_points_vec.in_error ())) return false;
- orig_points = orig_points_vec.as_array ();
- }
-
- if (flush)
- {
- for (unsigned int i = 0; i < points.length; i++)
- points.arrayZ[i].translate (deltas.arrayZ[i]);
- flush = false;
-
- }
- hb_memset (deltas.arrayZ, 0, deltas.get_size ());
- }
-
- if (scalar != 1.0f)
- for (unsigned int i = 0; i < num_deltas; i++)
- {
- unsigned int pt_index;
- if (apply_to_all)
- pt_index = i;
- else
- {
- pt_index = indices[i];
- if (unlikely (pt_index >= deltas.length)) continue;
- }
- auto &delta = deltas.arrayZ[pt_index];
- delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
- delta.x += x_deltas.arrayZ[i] * scalar;
- delta.y += y_deltas.arrayZ[i] * scalar;
- }
- else
- for (unsigned int i = 0; i < num_deltas; i++)
- {
- unsigned int pt_index;
- if (apply_to_all)
- pt_index = i;
- else
- {
- pt_index = indices[i];
- if (unlikely (pt_index >= deltas.length)) continue;
- }
- auto &delta = deltas.arrayZ[pt_index];
- delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
- delta.x += x_deltas.arrayZ[i];
- delta.y += y_deltas.arrayZ[i];
- }
-
- /* infer deltas for unreferenced points */
- if (!apply_to_all)
- {
- if (!end_points)
- {
- for (unsigned i = 0; i < points.length; ++i)
- if (points.arrayZ[i].is_end_point)
- end_points.push (i);
- if (unlikely (end_points.in_error ())) return false;
- }
-
- unsigned start_point = 0;
- for (unsigned end_point : end_points)
- {
- /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
- unsigned unref_count = 0;
- for (unsigned i = start_point; i < end_point + 1; i++)
- unref_count += deltas.arrayZ[i].flag;
- unref_count = (end_point - start_point + 1) - unref_count;
-
- unsigned j = start_point;
- if (unref_count == 0 || unref_count > end_point - start_point)
- goto no_more_gaps;
-
- for (;;)
- {
- /* Locate the next gap of unreferenced points between two referenced points prev and next.
- * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
- */
- unsigned int prev, next, i;
- for (;;)
- {
- i = j;
- j = next_index (i, start_point, end_point);
- if (deltas.arrayZ[i].flag && !deltas.arrayZ[j].flag) break;
- }
- prev = j = i;
- for (;;)
- {
- i = j;
- j = next_index (i, start_point, end_point);
- if (!deltas.arrayZ[i].flag && deltas.arrayZ[j].flag) break;
- }
- next = j;
- /* Infer deltas for all unref points in the gap between prev and next */
- i = prev;
- for (;;)
- {
- i = next_index (i, start_point, end_point);
- if (i == next) break;
- deltas.arrayZ[i].x = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::x);
- deltas.arrayZ[i].y = infer_delta (orig_points, deltas, i, prev, next, &contour_point_t::y);
- if (--unref_count == 0) goto no_more_gaps;
- }
- }
- no_more_gaps:
- start_point = end_point + 1;
- }
- }
-
- flush = true;
-
- } while (iterator.move_to_next ());
-
- if (flush)
- for (unsigned int i = 0; i < points.length; i++)
- points.arrayZ[i].translate (deltas.arrayZ[i]);
-
- return true;
- }
-
- unsigned int get_axis_count () const { return table->axisCount; }
-
- private:
- hb_blob_ptr_t<gvar> table;
- unsigned glyphCount;
- hb_vector_t<signed> shared_tuple_active_idx;
- };
-
- protected:
- FixedVersion<>version; /* Version number of the glyph variations table
- * Set to 0x00010000u. */
- HBUINT16 axisCount; /* The number of variation axes for this font. This must be
- * the same number as axisCount in the 'fvar' table. */
- HBUINT16 sharedTupleCount;
- /* The number of shared tuple records. Shared tuple records
- * can be referenced within glyph variation data tables for
- * multiple glyphs, as opposed to other tuple records stored
- * directly within a glyph variation data table. */
- NNOffset32To<UnsizedArrayOf<F2DOT14>>
- sharedTuples; /* Offset from the start of this table to the shared tuple records.
- * Array of tuple records shared across all glyph variation data tables. */
- HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of
- * glyphs stored elsewhere in the font. */
- HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows.
- * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the
- * offsets are uint32. */
- Offset32To<GlyphVariationData>
- dataZ; /* Offset from the start of this table to the array of
- * GlyphVariationData tables. */
- UnsizedArrayOf<HBUINT8>
- offsetZ; /* Offsets from the start of the GlyphVariationData array
- * to each GlyphVariationData table. */
- public:
- DEFINE_SIZE_ARRAY (20, offsetZ);
-};
-
-struct gvar_accelerator_t : gvar::accelerator_t {
- gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-#endif /* HB_OT_VAR_GVAR_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
index 461b2b9cdbc..fac843a7199 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh
@@ -27,232 +27,81 @@
#ifndef HB_OT_VAR_HVAR_TABLE_HH
#define HB_OT_VAR_HVAR_TABLE_HH
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-var-common.hh"
+#include "hb-ot-layout-common-private.hh"
+
namespace OT {
-struct index_map_subset_plan_t
+struct DeltaSetIndexMap
{
- enum index_map_index_t {
- ADV_INDEX,
- LSB_INDEX, /* dual as TSB */
- RSB_INDEX, /* dual as BSB */
- VORG_INDEX
- };
-
- void init (const DeltaSetIndexMap &index_map,
- hb_inc_bimap_t &outer_map,
- hb_vector_t<hb_set_t *> &inner_sets,
- const hb_subset_plan_t *plan)
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
- map_count = 0;
- outer_bit_count = 0;
- inner_bit_count = 1;
- max_inners.init ();
- output_map.init ();
-
- if (&index_map == &Null (DeltaSetIndexMap)) return;
-
- unsigned int last_val = (unsigned int)-1;
- hb_codepoint_t last_gid = (hb_codepoint_t)-1;
- hb_codepoint_t gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
-
- outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
- max_inners.resize (inner_sets.length);
- for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0;
-
- /* Search backwards for a map value different from the last map value */
- for (; gid > 0; gid--)
- {
- hb_codepoint_t old_gid;
- if (!plan->old_gid_for_new_gid (gid - 1, &old_gid))
- {
- if (last_gid == (hb_codepoint_t) -1)
- continue;
- else
- break;
- }
-
- unsigned int v = index_map.map (old_gid);
- if (last_gid == (hb_codepoint_t) -1)
- {
- last_val = v;
- last_gid = gid;
- continue;
- }
- if (v != last_val) break;
-
- last_gid = gid;
- }
-
- if (unlikely (last_gid == (hb_codepoint_t)-1)) return;
- map_count = last_gid;
- for (gid = 0; gid < map_count; gid++)
- {
- hb_codepoint_t old_gid;
- if (plan->old_gid_for_new_gid (gid, &old_gid))
- {
- unsigned int v = index_map.map (old_gid);
- unsigned int outer = v >> 16;
- unsigned int inner = v & 0xFFFF;
- outer_map.add (outer);
- if (inner > max_inners[outer]) max_inners[outer] = inner;
- if (outer >= inner_sets.length) return;
- inner_sets[outer]->add (inner);
- }
- }
- }
-
- void fini ()
- {
- max_inners.fini ();
- output_map.fini ();
- }
-
- void remap (const DeltaSetIndexMap *input_map,
- const hb_inc_bimap_t &outer_map,
- const hb_vector_t<hb_inc_bimap_t> &inner_maps,
- const hb_subset_plan_t *plan)
- {
- if (input_map == &Null (DeltaSetIndexMap)) return;
-
- for (unsigned int i = 0; i < max_inners.length; i++)
- {
- if (inner_maps[i].get_population () == 0) continue;
- unsigned int bit_count = (max_inners[i]==0)? 1: hb_bit_storage (inner_maps[i][max_inners[i]]);
- if (bit_count > inner_bit_count) inner_bit_count = bit_count;
- }
-
- output_map.resize (map_count);
- for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
- {
- hb_codepoint_t old_gid;
- if (plan->old_gid_for_new_gid (gid, &old_gid))
- {
- uint32_t v = input_map->map (old_gid);
- unsigned int outer = v >> 16;
- output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
- }
- else
- output_map[gid] = 0; /* Map unused glyph to outer/inner=0/0 */
- }
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (mapData, get_width (), mapCount));
}
- unsigned int get_inner_bit_count () const { return inner_bit_count; }
- unsigned int get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); }
- unsigned int get_map_count () const { return map_count; }
-
- unsigned int get_size () const
- { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); }
-
- bool is_identity () const { return get_output_map ().length == 0; }
- hb_array_t<const uint32_t> get_output_map () const { return output_map.as_array (); }
-
- protected:
- unsigned int map_count;
- hb_vector_t<unsigned int> max_inners;
- unsigned int outer_bit_count;
- unsigned int inner_bit_count;
- hb_vector_t<uint32_t> output_map;
-};
-
-struct hvarvvar_subset_plan_t
-{
- hvarvvar_subset_plan_t() : inner_maps (), index_map_plans () {}
- ~hvarvvar_subset_plan_t() { fini (); }
-
- void init (const hb_array_t<const DeltaSetIndexMap *> &index_maps,
- const VariationStore &_var_store,
- const hb_subset_plan_t *plan)
+ unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
{
- index_map_plans.resize (index_maps.length);
-
- var_store = &_var_store;
- inner_sets.resize (var_store->get_sub_table_count ());
- for (unsigned int i = 0; i < inner_sets.length; i++)
- inner_sets[i] = hb_set_create ();
- adv_set = hb_set_create ();
-
- inner_maps.resize (var_store->get_sub_table_count ());
-
- if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
-
- bool retain_adv_map = false;
- index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
- if (index_maps[0] == &Null (DeltaSetIndexMap))
- {
- retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
- outer_map.add (0);
- for (hb_codepoint_t old_gid : plan->glyphset()->iter())
- inner_sets[0]->add (old_gid);
- hb_set_union (adv_set, inner_sets[0]);
+ /* 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++;
}
- for (unsigned int i = 1; i < index_maps.length; i++)
- index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan);
-
- outer_map.sort ();
-
- if (retain_adv_map)
- {
- for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
- {
- if (inner_sets[0]->has (gid))
- inner_maps[0].add (gid);
- else
- inner_maps[0].skip ();
- }
+ { /* Repack it. */
+ unsigned int n = get_inner_bitcount ();
+ unsigned int outer = u >> n;
+ unsigned int inner = u & ((1 << n) - 1);
+ u = (outer<<16) | inner;
}
- else
- {
- inner_maps[0].add_set (adv_set);
- hb_set_subtract (inner_sets[0], adv_set);
- inner_maps[0].add_set (inner_sets[0]);
- }
-
- for (unsigned int i = 1; i < inner_maps.length; i++)
- inner_maps[i].add_set (inner_sets[i]);
- for (unsigned int i = 0; i < index_maps.length; i++)
- index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
+ return u;
}
- void fini ()
- {
- for (unsigned int i = 0; i < inner_sets.length; i++)
- hb_set_destroy (inner_sets[i]);
- hb_set_destroy (adv_set);
- inner_maps.fini ();
- index_map_plans.fini ();
- }
+ protected:
+ inline unsigned int get_width (void) const
+ { return ((format >> 4) & 3) + 1; }
- hb_inc_bimap_t outer_map;
- hb_vector_t<hb_inc_bimap_t> inner_maps;
- hb_vector_t<index_map_subset_plan_t> index_map_plans;
- const VariationStore *var_store;
+ inline unsigned int get_inner_bitcount (void) const
+ { return (format & 0xF) + 1; }
protected:
- hb_vector_t<hb_set_t *> inner_sets;
- hb_set_t *adv_set;
+ 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 -- Horizontal Metrics Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar
- * VVAR -- Vertical Metrics Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar
+ * 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 constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR;
- static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR;
+ static const hb_tag_t HVARTag = HB_OT_TAG_HVAR;
+ static const hb_tag_t VVARTag = HB_OT_TAG_VVAR;
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
@@ -263,93 +112,26 @@ struct HVARVVAR
rsbMap.sanitize (c, this));
}
- const VariationStore& get_var_store () const
- { return this+varStore; }
-
- void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const
- {
- index_maps.push (&(this+advMap));
- index_maps.push (&(this+lsbMap));
- index_maps.push (&(this+rsbMap));
- }
-
- bool serialize_index_maps (hb_serialize_context_t *c,
- const hb_array_t<index_map_subset_plan_t> &im_plans)
- {
- TRACE_SERIALIZE (this);
- if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ())
- advMap = 0;
- else if (unlikely (!advMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX])))
- return_trace (false);
- if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ())
- lsbMap = 0;
- else if (unlikely (!lsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX])))
- return_trace (false);
- if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ())
- rsbMap = 0;
- else if (unlikely (!rsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX])))
- return_trace (false);
-
- return_trace (true);
- }
-
- template <typename T>
- bool _subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- hvarvvar_subset_plan_t hvar_plan;
- hb_vector_t<const DeltaSetIndexMap *>
- index_maps;
-
- ((T*)this)->listup_index_maps (index_maps);
- hvar_plan.init (index_maps.as_array (), this+varStore, c->plan);
-
- T *out = c->serializer->allocate_min<T> ();
- if (unlikely (!out)) return_trace (false);
-
- out->version.major = 1;
- out->version.minor = 0;
-
- if (unlikely (!out->varStore
- .serialize_serialize (c->serializer,
- hvar_plan.var_store,
- hvar_plan.inner_maps.as_array ())))
- return_trace (false);
-
- return_trace (out->T::serialize_index_maps (c->serializer,
- hvar_plan.index_map_plans.as_array ()));
- }
-
- float get_advance_delta_unscaled (hb_codepoint_t glyph,
- const int *coords, unsigned int coord_count,
- VariationStore::cache_t *store_cache = nullptr) const
+ inline float get_advance_var (hb_codepoint_t glyph,
+ int *coords, unsigned int coord_count) const
{
- uint32_t varidx = (this+advMap).map (glyph);
- return (this+varStore).get_delta (varidx,
- coords, coord_count,
- store_cache);
+ unsigned int varidx = (this+advMap).map (glyph);
+ return (this+varStore).get_delta (varidx, coords, coord_count);
}
- bool get_lsb_delta_unscaled (hb_codepoint_t glyph,
- const int *coords, unsigned int coord_count,
- float *lsb) const
- {
- if (!lsbMap) return false;
- uint32_t varidx = (this+lsbMap).map (glyph);
- *lsb = (this+varStore).get_delta (varidx, coords, coord_count);
- return true;
- }
+ inline bool has_sidebearing_deltas (void) const
+ { return lsbMap && rsbMap; }
- public:
+ protected:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */
- Offset32To<VariationStore>
+ LOffsetTo<VariationStore>
varStore; /* Offset to item variation store table. */
- Offset32To<DeltaSetIndexMap>
+ LOffsetTo<DeltaSetIndexMap>
advMap; /* Offset to advance var-idx mapping. */
- Offset32To<DeltaSetIndexMap>
+ LOffsetTo<DeltaSetIndexMap>
lsbMap; /* Offset to lsb/tsb var-idx mapping. */
- Offset32To<DeltaSetIndexMap>
+ LOffsetTo<DeltaSetIndexMap>
rsbMap; /* Offset to rsb/bsb var-idx mapping. */
public:
@@ -357,53 +139,20 @@ struct HVARVVAR
};
struct HVAR : HVARVVAR {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR;
- bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<HVAR> (c); }
+ static const hb_tag_t tableTag = HB_OT_TAG_HVAR;
};
struct VVAR : HVARVVAR {
- static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR;
+ static const hb_tag_t tableTag = HB_OT_TAG_VVAR;
- bool sanitize (hb_sanitize_context_t *c) const
+ 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));
}
- void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const
- {
- HVARVVAR::listup_index_maps (index_maps);
- index_maps.push (&(this+vorgMap));
- }
-
- bool serialize_index_maps (hb_serialize_context_t *c,
- const hb_array_t<index_map_subset_plan_t> &im_plans)
- {
- TRACE_SERIALIZE (this);
- if (unlikely (!HVARVVAR::serialize_index_maps (c, im_plans)))
- return_trace (false);
- if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ())
- vorgMap = 0;
- else if (unlikely (!vorgMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX])))
- return_trace (false);
-
- return_trace (true);
- }
-
- bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); }
-
- bool get_vorg_delta_unscaled (hb_codepoint_t glyph,
- const int *coords, unsigned int coord_count,
- float *delta) const
- {
- if (!vorgMap) return false;
- uint32_t varidx = (this+vorgMap).map (glyph);
- *delta = (this+varStore).get_delta (varidx, coords, coord_count);
- return true;
- }
-
protected:
- Offset32To<DeltaSetIndexMap>
+ LOffsetTo<DeltaSetIndexMap>
vorgMap; /* Offset to vertical-origin var-idx mapping. */
public:
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
index d27ebb39c0a..e17ff5160a6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh
@@ -27,7 +27,7 @@
#ifndef HB_OT_VAR_MVAR_TABLE_HH
#define HB_OT_VAR_MVAR_TABLE_HH
-#include "hb-ot-layout-common.hh"
+#include "hb-ot-layout-common-private.hh"
namespace OT {
@@ -35,7 +35,7 @@ namespace OT {
struct VariationValueRecord
{
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
@@ -43,7 +43,7 @@ struct VariationValueRecord
public:
Tag valueTag; /* Four-byte tag identifying a font-wide measure. */
- VarIdx varIdx; /* Outer/inner index into VariationStore item. */
+ UINT32 varIdx; /* Outer/inner index into VariationStore item. */
public:
DEFINE_SIZE_STATIC (8);
@@ -51,16 +51,16 @@ struct VariationValueRecord
/*
- * MVAR -- Metrics Variations
- * https://docs.microsoft.com/en-us/typography/opentype/spec/mvar
+ * MVAR -- Metrics Variations Table
*/
+
#define HB_OT_TAG_MVAR HB_TAG('M','V','A','R')
struct MVAR
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_MVAR;
+ static const hb_tag_t tableTag = HB_OT_TAG_MVAR;
- bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
@@ -68,20 +68,16 @@ struct MVAR
c->check_struct (this) &&
valueRecordSize >= VariationValueRecord::static_size &&
varStore.sanitize (c, this) &&
- c->check_range (valuesZ.arrayZ,
- valueRecordCount,
- valueRecordSize));
+ c->check_array (values, valueRecordSize, valueRecordCount));
}
- float get_var (hb_tag_t tag,
- const int *coords, unsigned int coord_count) const
+ inline float get_var (hb_tag_t tag,
+ int *coords, unsigned int coord_count) const
{
const VariationValueRecord *record;
- record = (VariationValueRecord *) hb_bsearch (tag,
- (const VariationValueRecord *)
- (const HBUINT8 *) valuesZ,
- valueRecordCount, valueRecordSize,
- tag_compare);
+ record = (VariationValueRecord *) bsearch (&tag, values,
+ valueRecordCount, valueRecordSize,
+ tag_compare);
if (!record)
return 0.;
@@ -89,7 +85,7 @@ struct MVAR
}
protected:
- static int tag_compare (const void *pa, const void *pb)
+ 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;
@@ -99,30 +95,20 @@ protected:
protected:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */
- HBUINT16 reserved; /* Not used; set to 0. */
- HBUINT16 valueRecordSize;/* The size in bytes of each value record —
+ UINT16 reserved; /* Not used; set to 0. */
+ UINT16 valueRecordSize;/* The size in bytes of each value record —
* must be greater than zero. */
- HBUINT16 valueRecordCount;/* The number of value records — may be zero. */
- Offset16To<VariationStore>
+ UINT16 valueRecordCount;/* The number of value records — may be zero. */
+ OffsetTo<VariationStore>
varStore; /* Offset to item variation store table. */
- UnsizedArrayOf<HBUINT8>
- valuesZ; /* Array of value records. The records must be
+ UINT8 values[VAR]; /* Array of value records. The records must be
* in binary order of their valueTag field. */
public:
- DEFINE_SIZE_ARRAY (12, valuesZ);
+ DEFINE_SIZE_ARRAY (12, values);
};
} /* namespace OT */
-#define HB_ADD_MVAR_VAR(tag, field) \
- c->serializer->check_assign (table->field, \
- roundf (table->field + \
- MVAR.get_var (tag, \
- c->plan->normalized_coords.arrayZ, \
- c->plan->normalized_coords.length)), \
- HB_SERIALIZE_ERROR_INT_OVERFLOW)
-
-
#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
index f000f272636..90ba0bd02c6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc
@@ -24,78 +24,66 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-
-#ifndef HB_NO_VAR
-
-#include "hb-ot-var.h"
+#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"
-
-
-/**
- * SECTION:hb-ot-var
- * @title: hb-ot-var
- * @short_description: OpenType Font Variations
- * @include: hb-ot.h
- *
- * Functions for fetching information about OpenType Variable Fonts.
- **/
-
+#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: The #hb_face_t to work on
+ * @face: #hb_face_t to test
*
- * Tests whether a face includes any OpenType variation data in the `fvar` table.
+ * 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 data found, `false` otherwise
+ * 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 face->table.fvar->has_data ();
+ return &_get_fvar (face) != &OT::Null(OT::fvar);
}
/**
* hb_ot_var_get_axis_count:
- * @face: The #hb_face_t to work on
- *
- * Fetches the number of OpenType variation axes included in the face.
- *
- * Return value: the number of variation axes defined
*
* Since: 1.4.2
**/
unsigned int
hb_ot_var_get_axis_count (hb_face_t *face)
{
- return face->table.fvar->get_axis_count ();
+ const OT::fvar &fvar = _get_fvar (face);
+ return fvar.get_axis_count ();
}
-#ifndef HB_DISABLE_DEPRECATED
/**
* hb_ot_var_get_axes:
- * @face: #hb_face_t to work upon
- * @start_offset: offset of the first lookup to retrieve
- * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return;
- * Output = the actual number of variation axes returned (may be zero)
- * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found
- *
- * Fetches a list of all variation axes in the specified face. The list returned will begin
- * at the offset provided.
*
* Since: 1.4.2
- * Deprecated: 2.2.0: use hb_ot_var_get_axis_infos() instead
**/
unsigned int
hb_ot_var_get_axes (hb_face_t *face,
@@ -103,21 +91,14 @@ hb_ot_var_get_axes (hb_face_t *face,
unsigned int *axes_count /* IN/OUT */,
hb_ot_var_axis_t *axes_array /* OUT */)
{
- return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array);
+ const OT::fvar &fvar = _get_fvar (face);
+ return fvar.get_axis_infos (start_offset, axes_count, axes_array);
}
/**
* hb_ot_var_find_axis:
- * @face: #hb_face_t to work upon
- * @axis_tag: The #hb_tag_t of the variation axis to query
- * @axis_index: The index of the variation axis
- * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried
- *
- * Fetches the variation-axis information corresponding to the specified axis tag
- * in the specified face.
*
* Since: 1.4.2
- * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead
**/
hb_bool_t
hb_ot_var_find_axis (hb_face_t *face,
@@ -125,148 +106,13 @@ hb_ot_var_find_axis (hb_face_t *face,
unsigned int *axis_index,
hb_ot_var_axis_t *axis_info)
{
- return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
-}
-#endif
-
-/**
- * hb_ot_var_get_axis_infos:
- * @face: #hb_face_t to work upon
- * @start_offset: offset of the first lookup to retrieve
- * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return;
- * Output = the actual number of variation axes returned (may be zero)
- * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found
- *
- * Fetches a list of all variation axes in the specified face. The list returned will begin
- * at the offset provided.
- *
- * Return value: the number of variation axes in the face
- *
- * Since: 2.2.0
- **/
-HB_EXTERN unsigned int
-hb_ot_var_get_axis_infos (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *axes_count /* IN/OUT */,
- hb_ot_var_axis_info_t *axes_array /* OUT */)
-{
- return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array);
-}
-
-/**
- * hb_ot_var_find_axis_info:
- * @face: #hb_face_t to work upon
- * @axis_tag: The #hb_tag_t of the variation axis to query
- * @axis_info: (out): The #hb_ot_var_axis_info_t of the axis tag queried
- *
- * Fetches the variation-axis information corresponding to the specified axis tag
- * in the specified face.
- *
- * Return value: `true` if data found, `false` otherwise
- *
- * Since: 2.2.0
- **/
-HB_EXTERN hb_bool_t
-hb_ot_var_find_axis_info (hb_face_t *face,
- hb_tag_t axis_tag,
- hb_ot_var_axis_info_t *axis_info)
-{
- return face->table.fvar->find_axis_info (axis_tag, axis_info);
-}
-
-
-/*
- * Named instances.
- */
-
-/**
- * hb_ot_var_get_named_instance_count:
- * @face: The #hb_face_t to work on
- *
- * Fetches the number of named instances included in the face.
- *
- * Return value: the number of named instances defined
- *
- * Since: 2.2.0
- **/
-unsigned int
-hb_ot_var_get_named_instance_count (hb_face_t *face)
-{
- return face->table.fvar->get_instance_count ();
-}
-
-/**
- * hb_ot_var_named_instance_get_subfamily_name_id:
- * @face: The #hb_face_t to work on
- * @instance_index: The index of the named instance to query
- *
- * Fetches the `name` table Name ID that provides display names for
- * the "Subfamily name" defined for the given named instance in the face.
- *
- * Return value: the Name ID found for the Subfamily name
- *
- * Since: 2.2.0
- **/
-hb_ot_name_id_t
-hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
- unsigned int instance_index)
-{
- return face->table.fvar->get_instance_subfamily_name_id (instance_index);
-}
-
-/**
- * hb_ot_var_named_instance_get_postscript_name_id:
- * @face: The #hb_face_t to work on
- * @instance_index: The index of the named instance to query
- *
- * Fetches the `name` table Name ID that provides display names for
- * the "PostScript name" defined for the given named instance in the face.
- *
- * Return value: the Name ID found for the PostScript name
- *
- * Since: 2.2.0
- **/
-hb_ot_name_id_t
-hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
- unsigned int instance_index)
-{
- return face->table.fvar->get_instance_postscript_name_id (instance_index);
-}
-
-/**
- * hb_ot_var_named_instance_get_design_coords:
- * @face: The #hb_face_t to work on
- * @instance_index: The index of the named instance to query
- * @coords_length: (inout) (optional): Input = the maximum number of coordinates to return;
- * Output = the actual number of coordinates returned (may be zero)
- * @coords: (out) (array length=coords_length): The array of coordinates found for the query
- *
- * Fetches the design-space coordinates corresponding to the given
- * named instance in the face.
- *
- * Return value: the number of variation axes in the face
- *
- * Since: 2.2.0
- **/
-unsigned int
-hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
- unsigned int instance_index,
- unsigned int *coords_length, /* IN/OUT */
- float *coords /* OUT */)
-{
- return face->table.fvar->get_instance_coords (instance_index, coords_length, coords);
+ const OT::fvar &fvar = _get_fvar (face);
+ return fvar.find_axis (axis_tag, axis_index, axis_info);
}
/**
* hb_ot_var_normalize_variations:
- * @face: The #hb_face_t to work on
- * @variations: The array of variations to normalize
- * @variations_length: The number of variations to normalize
- * @coords: (out) (array length=coords_length): The array of normalized coordinates
- * @coords_length: The length of the coordinate array
- *
- * Normalizes all of the coordinates in the given list of variation axes.
*
* Since: 1.4.2
**/
@@ -280,34 +126,21 @@ hb_ot_var_normalize_variations (hb_face_t *face,
for (unsigned int i = 0; i < coords_length; i++)
coords[i] = 0;
- const OT::fvar &fvar = *face->table.fvar;
+ const OT::fvar &fvar = _get_fvar (face);
for (unsigned int i = 0; i < variations_length; i++)
{
- hb_ot_var_axis_info_t info;
- if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) &&
- info.axis_index < coords_length)
- coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value);
+ 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);
}
- face->table.avar->map_coords (coords, coords_length);
+ const OT::avar &avar = _get_avar (face);
+ avar.map_coords (coords, coords_length);
}
/**
* hb_ot_var_normalize_coords:
- * @face: The #hb_face_t to work on
- * @coords_length: The length of the coordinate array
- * @design_coords: The design-space coordinates to normalize
- * @normalized_coords: (out): The normalized coordinates
- *
- * Normalizes the given design-space coordinates. The minimum and maximum
- * values for the axis are mapped to the interval [-1,1], with the default
- * axis value mapped to 0.
- *
- * The normalized values have 14 bits of fixed-point sub-integer precision as per
- * OpenType specification.
- *
- * Any additional scaling defined in the face's `avar` table is also
- * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
*
* Since: 1.4.2
**/
@@ -317,12 +150,10 @@ hb_ot_var_normalize_coords (hb_face_t *face,
const float *design_coords, /* IN */
int *normalized_coords /* OUT */)
{
- const OT::fvar &fvar = *face->table.fvar;
+ 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]);
- face->table.avar->map_coords (normalized_coords, coords_length);
+ const OT::avar &avar = _get_avar (face);
+ avar.map_coords (normalized_coords, coords_length);
}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h
index 05147cc25e3..a2c0c5f2b02 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_OT_H_IN
#error "Include <hb-ot.h> instead."
#endif
@@ -35,40 +35,11 @@
HB_BEGIN_DECLS
-/**
- * HB_OT_TAG_VAR_AXIS_ITALIC:
- *
- * Registered tag for the roman/italic axis.
- */
-#define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l')
-/**
- * HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE:
- *
- * Registered tag for the optical-size axis.
- * <note>Note: The optical-size axis supersedes the OpenType `size` feature.</note>
- */
+#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')
-
-/**
- * HB_OT_TAG_VAR_AXIS_SLANT:
- *
- * Registered tag for the slant axis
- */
#define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t')
-
-/**
- * HB_OT_TAG_VAR_AXIS_WIDTH:
- *
- * Registered tag for the width axis.
- */
#define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h')
-
-/**
- * HB_OT_TAG_VAR_AXIS_WEIGHT:
- *
- * Registered tag for the weight axis.
- */
#define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t')
@@ -76,101 +47,44 @@ HB_BEGIN_DECLS
* fvar / avar
*/
-HB_EXTERN hb_bool_t
-hb_ot_var_has_data (hb_face_t *face);
-
-
-/*
- * Variation axes.
- */
-
-
-HB_EXTERN unsigned int
-hb_ot_var_get_axis_count (hb_face_t *face);
-
/**
- * hb_ot_var_axis_flags_t:
- * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces.
- *
- * Flags for #hb_ot_var_axis_info_t.
+ * hb_ot_var_axis_t:
*
- * Since: 2.2.0
+ * Since: 1.4.2
*/
-typedef enum { /*< flags >*/
- HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u,
+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;
- /*< private >*/
- _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_ot_var_axis_flags_t;
+HB_EXTERN hb_bool_t
+hb_ot_var_has_data (hb_face_t *face);
/**
- * hb_ot_var_axis_info_t:
- * @axis_index: Index of the axis in the variation-axis array
- * @tag: The #hb_tag_t tag identifying the design variation of the axis
- * @name_id: The `name` table Name ID that provides display names for the axis
- * @flags: The #hb_ot_var_axis_flags_t flags for the axis
- * @min_value: The minimum value on the variation axis that the font covers
- * @default_value: The position on the variation axis corresponding to the font's defaults
- * @max_value: The maximum value on the variation axis that the font covers
- *
- * Data type for holding variation-axis values.
- *
- * The minimum, default, and maximum values are in un-normalized, user scales.
+ * HB_OT_VAR_NO_AXIS_INDEX:
*
- * <note>Note: at present, the only flag defined for @flags is
- * #HB_OT_VAR_AXIS_FLAG_HIDDEN.</note>
- *
- * Since: 2.2.0
+ * Since: 1.4.2
*/
-typedef struct hb_ot_var_axis_info_t {
- unsigned int axis_index;
- hb_tag_t tag;
- hb_ot_name_id_t name_id;
- hb_ot_var_axis_flags_t flags;
- float min_value;
- float default_value;
- float max_value;
- /*< private >*/
- unsigned int reserved;
-} hb_ot_var_axis_info_t;
+#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu
HB_EXTERN unsigned int
-hb_ot_var_get_axis_infos (hb_face_t *face,
- unsigned int start_offset,
- unsigned int *axes_count /* IN/OUT */,
- hb_ot_var_axis_info_t *axes_array /* OUT */);
-
-HB_EXTERN hb_bool_t
-hb_ot_var_find_axis_info (hb_face_t *face,
- hb_tag_t axis_tag,
- hb_ot_var_axis_info_t *axis_info);
-
-
-/*
- * Named instances.
- */
-
-HB_EXTERN unsigned int
-hb_ot_var_get_named_instance_count (hb_face_t *face);
-
-HB_EXTERN hb_ot_name_id_t
-hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
- unsigned int instance_index);
-
-HB_EXTERN hb_ot_name_id_t
-hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
- unsigned int instance_index);
+hb_ot_var_get_axis_count (hb_face_t *face);
HB_EXTERN unsigned int
-hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
- unsigned int instance_index,
- unsigned int *coords_length, /* IN/OUT */
- float *coords /* OUT */);
+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);
-/*
- * Conversions.
- */
HB_EXTERN void
hb_ot_var_normalize_variations (hb_face_t *face,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh
deleted file mode 100644
index 811e13919e9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-vorg-table.hh
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_OT_VORG_TABLE_HH
-#define HB_OT_VORG_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * VORG -- Vertical Origin Table
- * https://docs.microsoft.com/en-us/typography/opentype/spec/vorg
- */
-#define HB_OT_TAG_VORG HB_TAG('V','O','R','G')
-
-namespace OT {
-
-struct VertOriginMetric
-{
- int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
-
- public:
- HBGlyphID16 glyph;
- FWORD vertOriginY;
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-struct VORG
-{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_VORG;
-
- bool has_data () const { return version.to_int (); }
-
- int get_y_origin (hb_codepoint_t glyph) const
- {
- unsigned int i;
- if (!vertYOrigins.bfind (glyph, &i))
- return defaultVertOriginY;
- return vertYOrigins[i].vertOriginY;
- }
-
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it,
- FWORD defaultVertOriginY)
- {
-
- if (unlikely (!c->extend_min ((*this)))) return;
-
- this->version.major = 1;
- this->version.minor = 0;
-
- this->defaultVertOriginY = defaultVertOriginY;
- this->vertYOrigins.len = it.len ();
-
- c->copy_all (it);
- }
-
- bool subset (hb_subset_context_t *c) const
- {
- TRACE_SUBSET (this);
- VORG *vorg_prime = c->serializer->start_embed<VORG> ();
- if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false);
-
- auto it =
- + vertYOrigins.as_array ()
- | hb_filter (c->plan->glyphset (), &VertOriginMetric::glyph)
- | hb_map ([&] (const VertOriginMetric& _)
- {
- hb_codepoint_t new_glyph = HB_SET_VALUE_INVALID;
- c->plan->new_gid_for_old_gid (_.glyph, &new_glyph);
-
- VertOriginMetric metric;
- metric.glyph = new_glyph;
- metric.vertOriginY = _.vertOriginY;
- return metric;
- })
- ;
-
- /* serialize the new table */
- vorg_prime->serialize (c->serializer, it, defaultVertOriginY);
- return_trace (true);
- }
-
- bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- version.major == 1 &&
- vertYOrigins.sanitize (c));
- }
-
- protected:
- FixedVersion<>version; /* Version of VORG table. Set to 0x00010000u. */
- FWORD defaultVertOriginY;
- /* The default vertical origin. */
- SortedArray16Of<VertOriginMetric>
- vertYOrigins; /* The array of vertical origins. */
-
- public:
- DEFINE_SIZE_ARRAY(8, vertYOrigins);
-};
-} /* namespace OT */
-
-#endif /* HB_OT_VORG_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot.h b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
index f2dbaa1b317..2120a3efa34 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
@@ -30,14 +30,10 @@
#include "hb.h"
-#include "hb-ot-color.h"
-#include "hb-ot-deprecated.h"
#include "hb-ot-font.h"
#include "hb-ot-layout.h"
#include "hb-ot-math.h"
-#include "hb-ot-meta.h"
-#include "hb-ot-metrics.h"
-#include "hb-ot-name.h"
+#include "hb-ot-tag.h"
#include "hb-ot-shape.h"
#include "hb-ot-var.h"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-outline.cc b/src/3rdparty/harfbuzz-ng/src/hb-outline.cc
deleted file mode 100644
index 29b1f530d5a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-outline.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright © 2023 Behdad Esfahbod
- * Copyright © 1999 David Turner
- * Copyright © 2005 Werner Lemberg
- * Copyright © 2013-2015 Alexei Podtelezhnikov
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_OUTLINE
-
-#include "hb-outline.hh"
-
-#include "hb-machinery.hh"
-
-
-void hb_outline_t::replay (hb_draw_funcs_t *pen, void *pen_data) const
-{
- hb_draw_state_t st = HB_DRAW_STATE_DEFAULT;
-
- unsigned first = 0;
- for (unsigned contour : contours)
- {
- auto it = points.as_array ().sub_array (first, contour - first);
- while (it)
- {
- hb_outline_point_t p1 = *it++;
- switch (p1.type)
- {
- case hb_outline_point_t::type_t::MOVE_TO:
- {
- pen->move_to (pen_data, st,
- p1.x, p1.y);
- }
- break;
- case hb_outline_point_t::type_t::LINE_TO:
- {
- pen->line_to (pen_data, st,
- p1.x, p1.y);
- }
- break;
- case hb_outline_point_t::type_t::QUADRATIC_TO:
- {
- hb_outline_point_t p2 = *it++;
- pen->quadratic_to (pen_data, st,
- p1.x, p1.y,
- p2.x, p2.y);
- }
- break;
- case hb_outline_point_t::type_t::CUBIC_TO:
- {
- hb_outline_point_t p2 = *it++;
- hb_outline_point_t p3 = *it++;
- pen->cubic_to (pen_data, st,
- p1.x, p1.y,
- p2.x, p2.y,
- p3.x, p3.y);
- }
- break;
- }
- }
- pen->close_path (pen_data, st);
- first = contour;
- }
-}
-
-float hb_outline_t::control_area () const
-{
- float a = 0;
- unsigned first = 0;
- for (unsigned contour : contours)
- {
- for (unsigned i = first; i < contour; i++)
- {
- unsigned j = i + 1 < contour ? i + 1 : first;
-
- auto &pi = points[i];
- auto &pj = points[j];
- a += pi.x * pj.y - pi.y * pj.x;
- }
-
- first = contour;
- }
- return a * .5f;
-}
-
-void hb_outline_t::embolden (float x_strength, float y_strength,
- float x_shift, float y_shift)
-{
- /* This function is a straight port of FreeType's FT_Outline_EmboldenXY.
- * Permission has been obtained from the FreeType authors of the code
- * to relicense it under the HarfBuzz license. */
-
- if (!x_strength && !y_strength) return;
- if (!points) return;
-
- x_strength /= 2.f;
- y_strength /= 2.f;
-
- bool orientation_negative = control_area () < 0;
-
- signed first = 0;
- for (unsigned c = 0; c < contours.length; c++)
- {
- hb_outline_vector_t in, out, anchor, shift;
- float l_in, l_out, l_anchor = 0, l, q, d;
-
- l_in = 0;
- signed last = (int) contours[c] - 1;
-
- /* pacify compiler */
- in.x = in.y = anchor.x = anchor.y = 0;
-
- /* Counter j cycles though the points; counter i advances only */
- /* when points are moved; anchor k marks the first moved point. */
- for ( signed i = last, j = first, k = -1;
- j != i && i != k;
- j = j < last ? j + 1 : first )
- {
- if ( j != k )
- {
- out.x = points[j].x - points[i].x;
- out.y = points[j].y - points[i].y;
- l_out = out.normalize_len ();
-
- if ( l_out == 0 )
- continue;
- }
- else
- {
- out = anchor;
- l_out = l_anchor;
- }
-
- if ( l_in != 0 )
- {
- if ( k < 0 )
- {
- k = i;
- anchor = in;
- l_anchor = l_in;
- }
-
- d = in.x * out.x + in.y * out.y;
-
- /* shift only if turn is less than ~160 degrees */
- if ( d > -15.f/16.f )
- {
- d = d + 1.f;
-
- /* shift components along lateral bisector in proper orientation */
- shift.x = in.y + out.y;
- shift.y = in.x + out.x;
-
- if ( orientation_negative )
- shift.x = -shift.x;
- else
- shift.y = -shift.y;
-
- /* restrict shift magnitude to better handle collapsing segments */
- q = out.x * in.y - out.y * in.x;
- if ( orientation_negative )
- q = -q;
-
- l = hb_min (l_in, l_out);
-
- /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
- if (x_strength * q <= l * d)
- shift.x = shift.x * x_strength / d;
- else
- shift.x = shift.x * l / q;
-
-
- if (y_strength * q <= l * d)
- shift.y = shift.y * y_strength / d;
- else
- shift.y = shift.y * l / q;
- }
- else
- shift.x = shift.y = 0;
-
- for ( ;
- i != j;
- i = i < last ? i + 1 : first )
- {
- points[i].x += x_shift + shift.x;
- points[i].y += y_shift + shift.y;
- }
- }
- else
- i = j;
-
- in = out;
- l_in = l_out;
- }
-
- first = last + 1;
- }
-}
-
-static void
-hb_outline_recording_pen_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_outline_t *c = (hb_outline_t *) data;
-
- c->points.push (hb_outline_point_t {to_x, to_y, hb_outline_point_t::type_t::MOVE_TO});
-}
-
-static void
-hb_outline_recording_pen_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_outline_t *c = (hb_outline_t *) data;
-
- c->points.push (hb_outline_point_t {to_x, to_y, hb_outline_point_t::type_t::LINE_TO});
-}
-
-static void
-hb_outline_recording_pen_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_outline_t *c = (hb_outline_t *) data;
-
- c->points.push (hb_outline_point_t {control_x, control_y, hb_outline_point_t::type_t::QUADRATIC_TO});
- c->points.push (hb_outline_point_t {to_x, to_y, hb_outline_point_t::type_t::QUADRATIC_TO});
-}
-
-static void
-hb_outline_recording_pen_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_outline_t *c = (hb_outline_t *) data;
-
- c->points.push (hb_outline_point_t {control1_x, control1_y, hb_outline_point_t::type_t::CUBIC_TO});
- c->points.push (hb_outline_point_t {control2_x, control2_y, hb_outline_point_t::type_t::CUBIC_TO});
- c->points.push (hb_outline_point_t {to_x, to_y, hb_outline_point_t::type_t::CUBIC_TO});
-}
-
-static void
-hb_outline_recording_pen_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- void *user_data HB_UNUSED)
-{
- hb_outline_t *c = (hb_outline_t *) data;
-
- c->contours.push (c->points.length);
-}
-
-static inline void free_static_outline_recording_pen_funcs ();
-
-static struct hb_outline_recording_pen_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_outline_recording_pen_funcs_lazy_loader_t>
-{
- static hb_draw_funcs_t *create ()
- {
- hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
-
- hb_draw_funcs_set_move_to_func (funcs, hb_outline_recording_pen_move_to, nullptr, nullptr);
- hb_draw_funcs_set_line_to_func (funcs, hb_outline_recording_pen_line_to, nullptr, nullptr);
- hb_draw_funcs_set_quadratic_to_func (funcs, hb_outline_recording_pen_quadratic_to, nullptr, nullptr);
- hb_draw_funcs_set_cubic_to_func (funcs, hb_outline_recording_pen_cubic_to, nullptr, nullptr);
- hb_draw_funcs_set_close_path_func (funcs, hb_outline_recording_pen_close_path, nullptr, nullptr);
-
- hb_draw_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_outline_recording_pen_funcs);
-
- return funcs;
- }
-} static_outline_recording_pen_funcs;
-
-static inline
-void free_static_outline_recording_pen_funcs ()
-{
- static_outline_recording_pen_funcs.free_instance ();
-}
-
-hb_draw_funcs_t *
-hb_outline_recording_pen_get_funcs ()
-{
- return static_outline_recording_pen_funcs.get_unconst ();
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-outline.hh b/src/3rdparty/harfbuzz-ng/src/hb-outline.hh
deleted file mode 100644
index c43c06596bb..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-outline.hh
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright © 2023 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_OUTLINE_HH
-#define HB_OUTLINE_HH
-
-#include "hb.hh"
-
-#include "hb-draw.hh"
-
-
-struct hb_outline_point_t
-{
- enum class type_t
- {
- MOVE_TO,
- LINE_TO,
- QUADRATIC_TO,
- CUBIC_TO,
- };
-
- hb_outline_point_t (float x, float y, type_t type) :
- x (x), y (y), type (type) {}
-
- float x, y;
- type_t type;
-};
-
-struct hb_outline_vector_t
-{
- float normalize_len ()
- {
- float len = hypotf (x, y);
- if (len)
- {
- x /= len;
- y /= len;
- }
- return len;
- }
-
- float x, y;
-};
-
-struct hb_outline_t
-{
- void reset () { points.shrink (0, false); contours.resize (0); }
-
- HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const;
- HB_INTERNAL float control_area () const;
- HB_INTERNAL void embolden (float x_strength, float y_strength,
- float x_shift, float y_shift);
-
- hb_vector_t<hb_outline_point_t> points;
- hb_vector_t<unsigned> contours;
-};
-
-HB_INTERNAL hb_draw_funcs_t *
-hb_outline_recording_pen_get_funcs ();
-
-
-#endif /* HB_OUTLINE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc b/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc
deleted file mode 100644
index 2393322b715..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.cc
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_PAINT
-
-#include "hb-paint-extents.hh"
-
-#include "hb-draw.h"
-
-#include "hb-machinery.hh"
-
-
-/*
- * This file implements bounds-extraction as well as boundedness
- * computation of COLRv1 fonts as described in:
- *
- * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness
- */
-
-static void
-hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy});
-}
-
-static void
-hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->pop_transform ();
-}
-
-static void
-hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_extents_t *extents = (hb_extents_t *) data;
-
- extents->add_point (to_x, to_y);
-}
-
-static void
-hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_extents_t *extents = (hb_extents_t *) data;
-
- extents->add_point (to_x, to_y);
-}
-
-static void
-hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float control_x, float control_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_extents_t *extents = (hb_extents_t *) data;
-
- extents->add_point (control_x, control_y);
- extents->add_point (to_x, to_y);
-}
-
-static void
-hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
- void *data,
- hb_draw_state_t *st,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *user_data HB_UNUSED)
-{
- hb_extents_t *extents = (hb_extents_t *) data;
-
- extents->add_point (control1_x, control1_y);
- extents->add_point (control2_x, control2_y);
- extents->add_point (to_x, to_y);
-}
-
-static inline void free_static_draw_extents_funcs ();
-
-static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_draw_extents_funcs_lazy_loader_t>
-{
- static hb_draw_funcs_t *create ()
- {
- hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
-
- hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr);
- hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr);
- hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr);
- hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr);
-
- hb_draw_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_draw_extents_funcs);
-
- return funcs;
- }
-} static_draw_extents_funcs;
-
-static inline
-void free_static_draw_extents_funcs ()
-{
- static_draw_extents_funcs.free_instance ();
-}
-
-static hb_draw_funcs_t *
-hb_draw_extents_get_funcs ()
-{
- return static_draw_extents_funcs.get_unconst ();
-}
-
-static void
-hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- hb_extents_t extents;
- hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs ();
- hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents);
- c->push_clip (extents);
-}
-
-static void
-hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- float xmin, float ymin, float xmax, float ymax,
- void *user_data)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- hb_extents_t extents = {xmin, ymin, xmax, ymax};
- c->push_clip (extents);
-}
-
-static void
-hb_paint_extents_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->pop_clip ();
-}
-
-static void
-hb_paint_extents_push_group (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->push_group ();
-}
-
-static void
-hb_paint_extents_pop_group (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_paint_composite_mode_t mode,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->pop_group (mode);
-}
-
-static hb_bool_t
-hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_blob_t *blob HB_UNUSED,
- unsigned int width HB_UNUSED,
- unsigned int height HB_UNUSED,
- hb_tag_t format HB_UNUSED,
- float slant HB_UNUSED,
- hb_glyph_extents_t *glyph_extents,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- hb_extents_t extents = {(float) glyph_extents->x_bearing,
- (float) glyph_extents->y_bearing + glyph_extents->height,
- (float) glyph_extents->x_bearing + glyph_extents->width,
- (float) glyph_extents->y_bearing};
- c->push_clip (extents);
- c->paint ();
- c->pop_clip ();
-
- return true;
-}
-
-static void
-hb_paint_extents_paint_color (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_bool_t use_foreground HB_UNUSED,
- hb_color_t color HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->paint ();
-}
-
-static void
-hb_paint_extents_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line HB_UNUSED,
- float x0 HB_UNUSED, float y0 HB_UNUSED,
- float x1 HB_UNUSED, float y1 HB_UNUSED,
- float x2 HB_UNUSED, float y2 HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->paint ();
-}
-
-static void
-hb_paint_extents_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line HB_UNUSED,
- float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED,
- float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->paint ();
-}
-
-static void
-hb_paint_extents_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED,
- void *paint_data,
- hb_color_line_t *color_line HB_UNUSED,
- float cx HB_UNUSED, float cy HB_UNUSED,
- float start_angle HB_UNUSED,
- float end_angle HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data;
-
- c->paint ();
-}
-
-static inline void free_static_paint_extents_funcs ();
-
-static struct hb_paint_extents_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_paint_extents_funcs_lazy_loader_t>
-{
- static hb_paint_funcs_t *create ()
- {
- hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
-
- hb_paint_funcs_set_push_transform_func (funcs, hb_paint_extents_push_transform, nullptr, nullptr);
- hb_paint_funcs_set_pop_transform_func (funcs, hb_paint_extents_pop_transform, nullptr, nullptr);
- hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_extents_push_clip_glyph, nullptr, nullptr);
- hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_extents_push_clip_rectangle, nullptr, nullptr);
- hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_extents_pop_clip, nullptr, nullptr);
- hb_paint_funcs_set_push_group_func (funcs, hb_paint_extents_push_group, nullptr, nullptr);
- hb_paint_funcs_set_pop_group_func (funcs, hb_paint_extents_pop_group, nullptr, nullptr);
- hb_paint_funcs_set_color_func (funcs, hb_paint_extents_paint_color, nullptr, nullptr);
- hb_paint_funcs_set_image_func (funcs, hb_paint_extents_paint_image, nullptr, nullptr);
- hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_extents_paint_linear_gradient, nullptr, nullptr);
- hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_extents_paint_radial_gradient, nullptr, nullptr);
- hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_extents_paint_sweep_gradient, nullptr, nullptr);
-
- hb_paint_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_paint_extents_funcs);
-
- return funcs;
- }
-} static_paint_extents_funcs;
-
-static inline
-void free_static_paint_extents_funcs ()
-{
- static_paint_extents_funcs.free_instance ();
-}
-
-hb_paint_funcs_t *
-hb_paint_extents_get_funcs ()
-{
- return static_paint_extents_funcs.get_unconst ();
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.hh b/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.hh
deleted file mode 100644
index f172bd42f93..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-paint-extents.hh
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright © 2022 Behdad Esfahbod
- *
- * 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.
- */
-
-#ifndef HB_PAINT_EXTENTS_HH
-#define HB_PAINT_EXTENTS_HH
-
-#include "hb.hh"
-#include "hb-paint.h"
-
-
-typedef struct hb_extents_t
-{
- hb_extents_t () {}
- hb_extents_t (float xmin, float ymin, float xmax, float ymax) :
- xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {}
-
- bool is_empty () const { return xmin >= xmax || ymin >= ymax; }
- bool is_void () const { return xmin > xmax; }
-
- void union_ (const hb_extents_t &o)
- {
- xmin = hb_min (xmin, o.xmin);
- ymin = hb_min (ymin, o.ymin);
- xmax = hb_max (xmax, o.xmax);
- ymax = hb_max (ymax, o.ymax);
- }
-
- void intersect (const hb_extents_t &o)
- {
- xmin = hb_max (xmin, o.xmin);
- ymin = hb_max (ymin, o.ymin);
- xmax = hb_min (xmax, o.xmax);
- ymax = hb_min (ymax, o.ymax);
- }
-
- void
- add_point (float x, float y)
- {
- if (unlikely (is_void ()))
- {
- xmin = xmax = x;
- ymin = ymax = y;
- }
- else
- {
- xmin = hb_min (xmin, x);
- ymin = hb_min (ymin, y);
- xmax = hb_max (xmax, x);
- ymax = hb_max (ymax, y);
- }
- }
-
- float xmin = 0.f;
- float ymin = 0.f;
- float xmax = -1.f;
- float ymax = -1.f;
-} hb_extents_t;
-
-typedef struct hb_transform_t
-{
- hb_transform_t () {}
- hb_transform_t (float xx, float yx,
- float xy, float yy,
- float x0, float y0) :
- xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {}
-
- void multiply (const hb_transform_t &o)
- {
- /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */
- hb_transform_t r;
-
- r.xx = o.xx * xx + o.yx * xy;
- r.yx = o.xx * yx + o.yx * yy;
-
- r.xy = o.xy * xx + o.yy * xy;
- r.yy = o.xy * yx + o.yy * yy;
-
- r.x0 = o.x0 * xx + o.y0 * xy + x0;
- r.y0 = o.x0 * yx + o.y0 * yy + y0;
-
- *this = r;
- }
-
- void transform_distance (float &dx, float &dy) const
- {
- float new_x = xx * dx + xy * dy;
- float new_y = yx * dx + yy * dy;
- dx = new_x;
- dy = new_y;
- }
-
- void transform_point (float &x, float &y) const
- {
- transform_distance (x, y);
- x += x0;
- y += y0;
- }
-
- void transform_extents (hb_extents_t &extents) const
- {
- float quad_x[4], quad_y[4];
-
- quad_x[0] = extents.xmin;
- quad_y[0] = extents.ymin;
- quad_x[1] = extents.xmin;
- quad_y[1] = extents.ymax;
- quad_x[2] = extents.xmax;
- quad_y[2] = extents.ymin;
- quad_x[3] = extents.xmax;
- quad_y[3] = extents.ymax;
-
- extents = hb_extents_t {};
- for (unsigned i = 0; i < 4; i++)
- {
- transform_point (quad_x[i], quad_y[i]);
- extents.add_point (quad_x[i], quad_y[i]);
- }
- }
-
- float xx = 1.f;
- float yx = 0.f;
- float xy = 0.f;
- float yy = 1.f;
- float x0 = 0.f;
- float y0 = 0.f;
-} hb_transform_t;
-
-typedef struct hb_bounds_t
-{
- enum status_t {
- UNBOUNDED,
- BOUNDED,
- EMPTY,
- };
-
- hb_bounds_t (status_t status) : status (status) {}
- hb_bounds_t (const hb_extents_t &extents) :
- status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {}
-
- void union_ (const hb_bounds_t &o)
- {
- if (o.status == UNBOUNDED)
- status = UNBOUNDED;
- else if (o.status == BOUNDED)
- {
- if (status == EMPTY)
- *this = o;
- else if (status == BOUNDED)
- extents.union_ (o.extents);
- }
- }
-
- void intersect (const hb_bounds_t &o)
- {
- if (o.status == EMPTY)
- status = EMPTY;
- else if (o.status == BOUNDED)
- {
- if (status == UNBOUNDED)
- *this = o;
- else if (status == BOUNDED)
- {
- extents.intersect (o.extents);
- if (extents.is_empty ())
- status = EMPTY;
- }
- }
- }
-
- status_t status;
- hb_extents_t extents;
-} hb_bounds_t;
-
-typedef struct hb_paint_extents_context_t hb_paint_extents_context_t;
-
-struct hb_paint_extents_context_t
-{
- hb_paint_extents_context_t ()
- {
- transforms.push (hb_transform_t{});
- clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED});
- groups.push (hb_bounds_t{hb_bounds_t::EMPTY});
- }
-
- hb_extents_t get_extents ()
- {
- return groups.tail().extents;
- }
-
- bool is_bounded ()
- {
- return groups.tail().status != hb_bounds_t::UNBOUNDED;
- }
-
- void push_transform (const hb_transform_t &trans)
- {
- hb_transform_t t = transforms.tail ();
- t.multiply (trans);
- transforms.push (t);
- }
-
- void pop_transform ()
- {
- transforms.pop ();
- }
-
- void push_clip (hb_extents_t extents)
- {
- /* Transform extents and push a new clip. */
- const hb_transform_t &t = transforms.tail ();
- t.transform_extents (extents);
-
- clips.push (hb_bounds_t {extents});
- }
-
- void pop_clip ()
- {
- clips.pop ();
- }
-
- void push_group ()
- {
- groups.push (hb_bounds_t {hb_bounds_t::EMPTY});
- }
-
- void pop_group (hb_paint_composite_mode_t mode)
- {
- const hb_bounds_t src_bounds = groups.pop ();
- hb_bounds_t &backdrop_bounds = groups.tail ();
-
- // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite
- switch ((int) mode)
- {
- case HB_PAINT_COMPOSITE_MODE_CLEAR:
- backdrop_bounds.status = hb_bounds_t::EMPTY;
- break;
- case HB_PAINT_COMPOSITE_MODE_SRC:
- case HB_PAINT_COMPOSITE_MODE_SRC_OUT:
- backdrop_bounds = src_bounds;
- break;
- case HB_PAINT_COMPOSITE_MODE_DEST:
- case HB_PAINT_COMPOSITE_MODE_DEST_OUT:
- break;
- case HB_PAINT_COMPOSITE_MODE_SRC_IN:
- case HB_PAINT_COMPOSITE_MODE_DEST_IN:
- backdrop_bounds.intersect (src_bounds);
- break;
- default:
- backdrop_bounds.union_ (src_bounds);
- break;
- }
- }
-
- void paint ()
- {
- const hb_bounds_t &clip = clips.tail ();
- hb_bounds_t &group = groups.tail ();
-
- group.union_ (clip);
- }
-
- protected:
- hb_vector_t<hb_transform_t> transforms;
- hb_vector_t<hb_bounds_t> clips;
- hb_vector_t<hb_bounds_t> groups;
-};
-
-HB_INTERNAL hb_paint_funcs_t *
-hb_paint_extents_get_funcs ();
-
-
-#endif /* HB_PAINT_EXTENTS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.cc b/src/3rdparty/harfbuzz-ng/src/hb-paint.cc
deleted file mode 100644
index 28150f1638d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-paint.cc
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright © 2022 Matthias Clasen
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_PAINT
-
-#include "hb-paint.hh"
-
-/**
- * SECTION: hb-paint
- * @title: hb-paint
- * @short_description: Glyph painting
- * @include: hb.h
- *
- * Functions for painting glyphs.
- *
- * The main purpose of these functions is to paint (extract) color glyph layers
- * from the COLRv1 table, but the API works for drawing ordinary outlines and
- * images as well.
- *
- * The #hb_paint_funcs_t struct can be used with hb_font_paint_glyph().
- **/
-
-static void
-hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy,
- void *user_data) {}
-
-static void
-hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
- void *user_data) {}
-
-static void
-hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font,
- void *user_data) {}
-
-static void
-hb_paint_push_clip_rectangle_nil (hb_paint_funcs_t *funcs, void *paint_data,
- float xmin, float ymin, float xmax, float ymax,
- void *user_data) {}
-
-static void
-hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data,
- void *user_data) {}
-
-static void
-hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_bool_t is_foreground,
- hb_color_t color,
- void *user_data) {}
-
-static hb_bool_t
-hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_blob_t *image,
- unsigned int width,
- unsigned int height,
- hb_tag_t format,
- float slant_xy,
- hb_glyph_extents_t *extents,
- void *user_data) { return false; }
-
-static void
-hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2,
- void *user_data) {}
-
-static void
-hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1,
- void *user_data) {}
-
-static void
-hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle,
- float end_angle,
- void *user_data) {}
-
-static void
-hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
- void *user_data) {}
-
-static void
-hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
- hb_paint_composite_mode_t mode,
- void *user_data) {}
-
-static hb_bool_t
-hb_paint_custom_palette_color_nil (hb_paint_funcs_t *funcs, void *paint_data,
- unsigned int color_index,
- hb_color_t *color,
- void *user_data) { return false; }
-
-static bool
-_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
- bool func_is_null,
- void **user_data,
- hb_destroy_func_t *destroy)
-{
- if (hb_object_is_immutable (funcs))
- {
- if (*destroy)
- (*destroy) (*user_data);
- return false;
- }
-
- if (func_is_null)
- {
- if (*destroy)
- (*destroy) (*user_data);
- *destroy = nullptr;
- *user_data = nullptr;
- }
-
- return true;
-}
-
-static bool
-_hb_paint_funcs_set_middle (hb_paint_funcs_t *funcs,
- void *user_data,
- hb_destroy_func_t destroy)
-{
- if (user_data && !funcs->user_data)
- {
- funcs->user_data = (decltype (funcs->user_data)) hb_calloc (1, sizeof (*funcs->user_data));
- if (unlikely (!funcs->user_data))
- goto fail;
- }
- if (destroy && !funcs->destroy)
- {
- funcs->destroy = (decltype (funcs->destroy)) hb_calloc (1, sizeof (*funcs->destroy));
- if (unlikely (!funcs->destroy))
- goto fail;
- }
-
- return true;
-
-fail:
- if (destroy)
- (destroy) (user_data);
- return false;
-}
-
-#define HB_PAINT_FUNC_IMPLEMENT(name) \
- \
-void \
-hb_paint_funcs_set_##name##_func (hb_paint_funcs_t *funcs, \
- hb_paint_##name##_func_t func, \
- void *user_data, \
- hb_destroy_func_t destroy) \
-{ \
- if (!_hb_paint_funcs_set_preamble (funcs, !func, &user_data, &destroy)) \
- return; \
- \
- if (funcs->destroy && funcs->destroy->name) \
- funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name);\
- \
- if (!_hb_paint_funcs_set_middle (funcs, user_data, destroy)) \
- return; \
- \
- if (func) \
- funcs->func.name = func; \
- else \
- funcs->func.name = hb_paint_##name##_nil; \
- \
- if (funcs->user_data) \
- funcs->user_data->name = user_data; \
- if (funcs->destroy) \
- funcs->destroy->name = destroy; \
-}
-
-HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
-
-/**
- * hb_paint_funcs_create:
- *
- * Creates a new #hb_paint_funcs_t structure of paint functions.
- *
- * The initial reference count of 1 should be released with hb_paint_funcs_destroy()
- * when you are done using the #hb_paint_funcs_t. This function never returns
- * `NULL`. If memory cannot be allocated, a special singleton #hb_paint_funcs_t
- * object will be returned.
- *
- * Returns value: (transfer full): the paint-functions structure
- *
- * Since: 7.0.0
- */
-hb_paint_funcs_t *
-hb_paint_funcs_create ()
-{
- hb_paint_funcs_t *funcs;
- if (unlikely (!(funcs = hb_object_create<hb_paint_funcs_t> ())))
- return const_cast<hb_paint_funcs_t *> (&Null (hb_paint_funcs_t));
-
- funcs->func = Null (hb_paint_funcs_t).func;
-
- return funcs;
-}
-
-DEFINE_NULL_INSTANCE (hb_paint_funcs_t) =
-{
- HB_OBJECT_HEADER_STATIC,
-
- {
-#define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_nil,
- HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
- }
-};
-
-/**
- * hb_paint_funcs_get_empty:
- *
- * Fetches the singleton empty paint-functions structure.
- *
- * Return value: (transfer full): The empty paint-functions structure
- *
- * Since: 7.0.0
- **/
-hb_paint_funcs_t *
-hb_paint_funcs_get_empty ()
-{
- return const_cast<hb_paint_funcs_t *> (&Null (hb_paint_funcs_t));
-}
-
-/**
- * hb_paint_funcs_reference: (skip)
- * @funcs: The paint-functions structure
- *
- * Increases the reference count on a paint-functions structure.
- *
- * This prevents @funcs from being destroyed until a matching
- * call to hb_paint_funcs_destroy() is made.
- *
- * Return value: The paint-functions structure
- *
- * Since: 7.0.0
- */
-hb_paint_funcs_t *
-hb_paint_funcs_reference (hb_paint_funcs_t *funcs)
-{
- return hb_object_reference (funcs);
-}
-
-/**
- * hb_paint_funcs_destroy: (skip)
- * @funcs: The paint-functions structure
- *
- * Decreases the reference count on a paint-functions structure.
- *
- * When the reference count reaches zero, the structure
- * is destroyed, freeing all memory.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_funcs_destroy (hb_paint_funcs_t *funcs)
-{
- if (!hb_object_destroy (funcs)) return;
-
- if (funcs->destroy)
- {
-#define HB_PAINT_FUNC_IMPLEMENT(name) \
- if (funcs->destroy->name) funcs->destroy->name (!funcs->user_data ? nullptr : funcs->user_data->name);
- HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
- }
-
- hb_free (funcs->destroy);
- hb_free (funcs->user_data);
- hb_free (funcs);
-}
-
-/**
- * hb_paint_funcs_set_user_data: (skip)
- * @funcs: The paint-functions structure
- * @key: The user-data key
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the specified paint-functions structure.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 7.0.0
- **/
-hb_bool_t
-hb_paint_funcs_set_user_data (hb_paint_funcs_t *funcs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- return hb_object_set_user_data (funcs, key, data, destroy, replace);
-}
-
-/**
- * hb_paint_funcs_get_user_data: (skip)
- * @funcs: The paint-functions structure
- * @key: The user-data key to query
- *
- * Fetches the user-data associated with the specified key,
- * attached to the specified paint-functions structure.
- *
- * Return value: (transfer none): A pointer to the user data
- *
- * Since: 7.0.0
- **/
-void *
-hb_paint_funcs_get_user_data (const hb_paint_funcs_t *funcs,
- hb_user_data_key_t *key)
-{
- return hb_object_get_user_data (funcs, key);
-}
-
-/**
- * hb_paint_funcs_make_immutable:
- * @funcs: The paint-functions structure
- *
- * Makes a paint-functions structure immutable.
- *
- * After this call, all attempts to set one of the callbacks
- * on @funcs will fail.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs)
-{
- if (hb_object_is_immutable (funcs))
- return;
-
- hb_object_make_immutable (funcs);
-}
-
-/**
- * hb_paint_funcs_is_immutable:
- * @funcs: The paint-functions structure
- *
- * Tests whether a paint-functions structure is immutable.
- *
- * Return value: `true` if @funcs is immutable, `false` otherwise
- *
- * Since: 7.0.0
- */
-hb_bool_t
-hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs)
-{
- return hb_object_is_immutable (funcs);
-}
-
-
-/**
- * hb_color_line_get_color_stops:
- * @color_line: a #hb_color_line_t object
- * @start: the index of the first color stop to return
- * @count: (inout) (optional): Input = the maximum number of feature tags to return;
- * Output = the actual number of feature tags returned (may be zero)
- * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate
- *
- * Fetches a list of color stops from the given color line object.
- *
- * Note that due to variations being applied, the returned color stops
- * may be out of order. It is the callers responsibility to ensure that
- * color stops are sorted by their offset before they are used.
- *
- * Return value: the total number of color stops in @color_line
- *
- * Since: 7.0.0
- */
-unsigned int
-hb_color_line_get_color_stops (hb_color_line_t *color_line,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops)
-{
- return color_line->get_color_stops (color_line,
- color_line->data,
- start, count,
- color_stops,
- color_line->get_color_stops_user_data);
-}
-
-/**
- * hb_color_line_get_extend:
- * @color_line: a #hb_color_line_t object
- *
- * Fetches the extend mode of the color line object.
- *
- * Return value: the extend mode of @color_line
- *
- * Since: 7.0.0
- */
-hb_paint_extend_t
-hb_color_line_get_extend (hb_color_line_t *color_line)
-{
- return color_line->get_extend (color_line,
- color_line->data,
- color_line->get_extend_user_data);
-}
-
-
-/**
- * hb_paint_push_transform:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @xx: xx component of the transform matrix
- * @yx: yx component of the transform matrix
- * @xy: xy component of the transform matrix
- * @yy: yy component of the transform matrix
- * @dx: dx component of the transform matrix
- * @dy: dy component of the transform matrix
- *
- * Perform a "push-transform" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy)
-{
- funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy);
-}
-
-/**
- * hb_paint_pop_transform:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- *
- * Perform a "pop-transform" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data)
-{
- funcs->pop_transform (paint_data);
-}
-
-/**
- * hb_paint_push_clip_glyph:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @glyph: the glyph ID
- * @font: the font
- *
- * Perform a "push-clip-glyph" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font)
-{
- funcs->push_clip_glyph (paint_data, glyph, font);
-}
-
-/**
- * hb_paint_push_clip_rectangle:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @xmin: min X for the rectangle
- * @ymin: min Y for the rectangle
- * @xmax: max X for the rectangle
- * @ymax: max Y for the rectangle
- *
- * Perform a "push-clip-rect" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data,
- float xmin, float ymin, float xmax, float ymax)
-{
- funcs->push_clip_rectangle (paint_data, xmin, ymin, xmax, ymax);
-}
-
-/**
- * hb_paint_pop_clip:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- *
- * Perform a "pop-clip" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data)
-{
- funcs->pop_clip (paint_data);
-}
-
-/**
- * hb_paint_color:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @is_foreground: whether the color is the foreground
- * @color: The color to use
- *
- * Perform a "color" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data,
- hb_bool_t is_foreground,
- hb_color_t color)
-{
- funcs->color (paint_data, is_foreground, color);
-}
-
-/**
- * hb_paint_image:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @image: image data
- * @width: width of the raster image in pixels, or 0
- * @height: height of the raster image in pixels, or 0
- * @format: the image format as a tag
- * @slant: the synthetic slant ratio to be applied to the image during rendering
- * @extents: (nullable): the extents of the glyph
- *
- * Perform a "image" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data,
- hb_blob_t *image,
- unsigned int width,
- unsigned int height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents)
-{
- funcs->image (paint_data, image, width, height, format, slant, extents);
-}
-
-/**
- * hb_paint_linear_gradient:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the first point
- * @y0: Y coordinate of the first point
- * @x1: X coordinate of the second point
- * @y1: Y coordinate of the second point
- * @x2: X coordinate of the third point
- * @y2: Y coordinate of the third point
- *
- * Perform a "linear-gradient" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2)
-{
- funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2);
-}
-
-/**
- * hb_paint_radial_gradient:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the first circle's center
- * @y0: Y coordinate of the first circle's center
- * @r0: radius of the first circle
- * @x1: X coordinate of the second circle's center
- * @y1: Y coordinate of the second circle's center
- * @r1: radius of the second circle
- *
- * Perform a "radial-gradient" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1)
-{
- funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1);
-}
-
-/**
- * hb_paint_sweep_gradient:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the circle's center
- * @y0: Y coordinate of the circle's center
- * @start_angle: the start angle
- * @end_angle: the end angle
- *
- * Perform a "sweep-gradient" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle, float end_angle)
-{
- funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle);
-}
-
-/**
- * hb_paint_push_group:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- *
- * Perform a "push-group" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data)
-{
- funcs->push_group (paint_data);
-}
-
-/**
- * hb_paint_pop_group:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @mode: the compositing mode to use
- *
- * Perform a "pop-group" paint operation.
- *
- * Since: 7.0.0
- */
-void
-hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
- hb_paint_composite_mode_t mode)
-{
- funcs->pop_group (paint_data, mode);
-}
-
-/**
- * hb_paint_custom_palette_color:
- * @funcs: paint functions
- * @paint_data: associated data passed by the caller
- * @color_index: color index
- * @color: (out): fetched color
- *
- * Gets the custom palette color for @color_index.
- *
- * Return value: `true` if found, `false` otherwise
- *
- * Since: 7.0.0
- */
-hb_bool_t
-hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
- unsigned int color_index,
- hb_color_t *color)
-{
- return funcs->custom_palette_color (paint_data, color_index, color);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.h b/src/3rdparty/harfbuzz-ng/src/hb-paint.h
deleted file mode 100644
index 543382780d1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-paint.h
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * Copyright © 2022 Matthias Clasen
- *
- * 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.
- */
-
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb.h> instead."
-#endif
-
-#ifndef HB_PAINT_H
-#define HB_PAINT_H
-
-#include "hb-common.h"
-
-HB_BEGIN_DECLS
-
-
-/**
- * hb_paint_funcs_t:
- *
- * Glyph paint callbacks.
- *
- * The callbacks assume that the caller maintains a stack
- * of current transforms, clips and intermediate surfaces,
- * as evidenced by the pairs of push/pop callbacks. The
- * push/pop calls will be properly nested, so it is fine
- * to store the different kinds of object on a single stack.
- *
- * Not all callbacks are required for all kinds of glyphs.
- * For rendering COLRv0 or non-color outline glyphs, the
- * gradient callbacks are not needed, and the composite
- * callback only needs to handle simple alpha compositing
- * (#HB_PAINT_COMPOSITE_MODE_SRC_OVER).
- *
- * The paint-image callback is only needed for glyphs
- * with image blobs in the CBDT, sbix or SVG tables.
- *
- * The custom-palette-color callback is only necessary if
- * you want to override colors from the font palette with
- * custom colors.
- *
- * Since: 7.0.0
- **/
-typedef struct hb_paint_funcs_t hb_paint_funcs_t;
-
-HB_EXTERN hb_paint_funcs_t *
-hb_paint_funcs_create (void);
-
-HB_EXTERN hb_paint_funcs_t *
-hb_paint_funcs_get_empty (void);
-
-HB_EXTERN hb_paint_funcs_t *
-hb_paint_funcs_reference (hb_paint_funcs_t *funcs);
-
-HB_EXTERN void
-hb_paint_funcs_destroy (hb_paint_funcs_t *funcs);
-
-HB_EXTERN hb_bool_t
-hb_paint_funcs_set_user_data (hb_paint_funcs_t *funcs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace);
-
-
-HB_EXTERN void *
-hb_paint_funcs_get_user_data (const hb_paint_funcs_t *funcs,
- hb_user_data_key_t *key);
-
-HB_EXTERN void
-hb_paint_funcs_make_immutable (hb_paint_funcs_t *funcs);
-
-HB_EXTERN hb_bool_t
-hb_paint_funcs_is_immutable (hb_paint_funcs_t *funcs);
-
-/**
- * hb_paint_push_transform_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @xx: xx component of the transform matrix
- * @yx: yx component of the transform matrix
- * @xy: xy component of the transform matrix
- * @yy: yy component of the transform matrix
- * @dx: dx component of the transform matrix
- * @dy: dy component of the transform matrix
- * @user_data: User data pointer passed to hb_paint_funcs_set_push_transform_func()
- *
- * A virtual method for the #hb_paint_funcs_t to apply
- * a transform to subsequent paint calls.
- *
- * This transform is applied after the current transform,
- * and remains in effect until a matching call to
- * the #hb_paint_funcs_pop_transform_func_t vfunc.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_push_transform_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy,
- void *user_data);
-
-/**
- * hb_paint_pop_transform_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @user_data: User data pointer passed to hb_paint_funcs_set_pop_transform_func()
- *
- * A virtual method for the #hb_paint_funcs_t to undo
- * the effect of a prior call to the #hb_paint_funcs_push_transform_func_t
- * vfunc.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- void *user_data);
-
-/**
- * hb_paint_push_clip_glyph_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @glyph: the glyph ID
- * @font: the font
- * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_glyph_func()
- *
- * A virtual method for the #hb_paint_funcs_t to clip
- * subsequent paint calls to the outline of a glyph.
- *
- * The coordinates of the glyph outline are interpreted according
- * to the current transform.
- *
- * This clip is applied in addition to the current clip,
- * and remains in effect until a matching call to
- * the #hb_paint_funcs_pop_clip_func_t vfunc.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font,
- void *user_data);
-
-/**
- * hb_paint_push_clip_rectangle_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @xmin: min X for the rectangle
- * @ymin: min Y for the rectangle
- * @xmax: max X for the rectangle
- * @ymax: max Y for the rectangle
- * @user_data: User data pointer passed to hb_paint_funcs_set_push_clip_rectangle_func()
- *
- * A virtual method for the #hb_paint_funcs_t to clip
- * subsequent paint calls to a rectangle.
- *
- * The coordinates of the rectangle are interpreted according
- * to the current transform.
- *
- * This clip is applied in addition to the current clip,
- * and remains in effect until a matching call to
- * the #hb_paint_funcs_pop_clip_func_t vfunc.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_push_clip_rectangle_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- float xmin, float ymin,
- float xmax, float ymax,
- void *user_data);
-
-/**
- * hb_paint_pop_clip_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @user_data: User data pointer passed to hb_paint_funcs_set_pop_clip_func()
- *
- * A virtual method for the #hb_paint_funcs_t to undo
- * the effect of a prior call to the #hb_paint_funcs_push_clip_glyph_func_t
- * or #hb_paint_funcs_push_clip_rectangle_func_t vfuncs.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- void *user_data);
-
-/**
- * hb_paint_color_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @is_foreground: whether the color is the foreground
- * @color: The color to use, unpremultiplied
- * @user_data: User data pointer passed to hb_paint_funcs_set_color_func()
- *
- * A virtual method for the #hb_paint_funcs_t to paint a
- * color everywhere within the current clip.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_bool_t is_foreground,
- hb_color_t color,
- void *user_data);
-
-/**
- * HB_PAINT_IMAGE_FORMAT_PNG:
- *
- * Tag identifying PNG images in #hb_paint_image_func_t callbacks.
- *
- * Since: 7.0.0
- */
-#define HB_PAINT_IMAGE_FORMAT_PNG HB_TAG('p','n','g',' ')
-
-/**
- * HB_PAINT_IMAGE_FORMAT_SVG:
- *
- * Tag identifying SVG images in #hb_paint_image_func_t callbacks.
- *
- * Since: 7.0.0
- */
-#define HB_PAINT_IMAGE_FORMAT_SVG HB_TAG('s','v','g',' ')
-
-/**
- * HB_PAINT_IMAGE_FORMAT_BGRA:
- *
- * Tag identifying raw pixel-data images in #hb_paint_image_func_t callbacks.
- * The data is in BGRA pre-multiplied sRGBA color-space format.
- *
- * Since: 7.0.0
- */
-#define HB_PAINT_IMAGE_FORMAT_BGRA HB_TAG('B','G','R','A')
-
-/**
- * hb_paint_image_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @image: the image data
- * @width: width of the raster image in pixels, or 0
- * @height: height of the raster image in pixels, or 0
- * @format: the image format as a tag
- * @slant: the synthetic slant ratio to be applied to the image during rendering
- * @extents: (nullable): glyph extents for desired rendering
- * @user_data: User data pointer passed to hb_paint_funcs_set_image_func()
- *
- * A virtual method for the #hb_paint_funcs_t to paint a glyph image.
- *
- * This method is called for glyphs with image blobs in the CBDT,
- * sbix or SVG tables. The @format identifies the kind of data that
- * is contained in @image. Possible values include #HB_PAINT_IMAGE_FORMAT_PNG,
- * #HB_PAINT_IMAGE_FORMAT_SVG and #HB_PAINT_IMAGE_FORMAT_BGRA.
- *
- * The image dimensions and glyph extents are provided if available,
- * and should be used to size and position the image.
- *
- * Return value: Whether the operation was successful.
- *
- * Since: 7.0.0
- */
-typedef hb_bool_t (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_blob_t *image,
- unsigned int width,
- unsigned int height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents,
- void *user_data);
-
-/**
- * hb_color_stop_t:
- * @offset: the offset of the color stop
- * @is_foreground: whether the color is the foreground
- * @color: the color, unpremultiplied
- *
- * Information about a color stop on a color line.
- *
- * Color lines typically have offsets ranging between 0 and 1,
- * but that is not required.
- *
- * Note: despite @color being unpremultiplied here, interpolation in
- * gradients shall happen in premultiplied space. See the OpenType spec
- * [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details.
- *
- * Since: 7.0.0
- */
-typedef struct {
- float offset;
- hb_bool_t is_foreground;
- hb_color_t color;
-} hb_color_stop_t;
-
-/**
- * hb_paint_extend_t:
- * @HB_PAINT_EXTEND_PAD: Outside the defined interval,
- * the color of the closest color stop is used.
- * @HB_PAINT_EXTEND_REPEAT: The color line is repeated over
- * repeated multiples of the defined interval
- * @HB_PAINT_EXTEND_REFLECT: The color line is repeated over
- * repeated intervals, as for the repeat mode.
- * However, in each repeated interval, the ordering of
- * color stops is the reverse of the adjacent interval.
- *
- * The values of this enumeration determine how color values
- * outside the minimum and maximum defined offset on a #hb_color_line_t
- * are determined.
- *
- * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details.
- *
- * Since: 7.0.0
- */
-typedef enum {
- HB_PAINT_EXTEND_PAD,
- HB_PAINT_EXTEND_REPEAT,
- HB_PAINT_EXTEND_REFLECT
-} hb_paint_extend_t;
-
-typedef struct hb_color_line_t hb_color_line_t;
-
-/**
- * hb_color_line_get_color_stops_func_t:
- * @color_line: a #hb_color_line_t object
- * @color_line_data: the data accompanying @color_line
- * @start: the index of the first color stop to return
- * @count: (inout) (optional): Input = the maximum number of feature tags to return;
- * Output = the actual number of feature tags returned (may be zero)
- * @color_stops: (out) (array length=count) (optional): Array of #hb_color_stop_t to populate
- * @user_data: the data accompanying this method
- *
- * A virtual method for the #hb_color_line_t to fetch color stops.
- *
- * Return value: the total number of color stops in @color_line
- *
- * Since: 7.0.0
- */
-typedef unsigned int (*hb_color_line_get_color_stops_func_t) (hb_color_line_t *color_line,
- void *color_line_data,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops,
- void *user_data);
-
-/**
- * hb_color_line_get_extend_func_t:
- * @color_line: a #hb_color_line_t object
- * @color_line_data: the data accompanying @color_line
- * @user_data: the data accompanying this method
- *
- * A virtual method for the @hb_color_line_t to fetches the extend mode.
- *
- * Return value: the extend mode of @color_line
- *
- * Since: 7.0.0
- */
-typedef hb_paint_extend_t (*hb_color_line_get_extend_func_t) (hb_color_line_t *color_line,
- void *color_line_data,
- void *user_data);
-
-/**
- * hb_color_line_t:
- *
- * A struct containing color information for a gradient.
- *
- * Since: 7.0.0
- */
-struct hb_color_line_t {
- void *data;
-
- hb_color_line_get_color_stops_func_t get_color_stops;
- void *get_color_stops_user_data;
-
- hb_color_line_get_extend_func_t get_extend;
- void *get_extend_user_data;
-
- void *reserved0;
- void *reserved1;
- void *reserved2;
- void *reserved3;
- void *reserved5;
- void *reserved6;
- void *reserved7;
- void *reserved8;
-};
-
-HB_EXTERN unsigned int
-hb_color_line_get_color_stops (hb_color_line_t *color_line,
- unsigned int start,
- unsigned int *count,
- hb_color_stop_t *color_stops);
-
-HB_EXTERN hb_paint_extend_t
-hb_color_line_get_extend (hb_color_line_t *color_line);
-
-/**
- * hb_paint_linear_gradient_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the first point
- * @y0: Y coordinate of the first point
- * @x1: X coordinate of the second point
- * @y1: Y coordinate of the second point
- * @x2: X coordinate of the third point
- * @y2: Y coordinate of the third point
- * @user_data: User data pointer passed to hb_paint_funcs_set_linear_gradient_func()
- *
- * A virtual method for the #hb_paint_funcs_t to paint a linear
- * gradient everywhere within the current clip.
- *
- * The @color_line object contains information about the colors of the gradients.
- * It is only valid for the duration of the callback, you cannot keep it around.
- *
- * The coordinates of the points are interpreted according
- * to the current transform.
- *
- * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details on how the points define the direction
- * of the gradient, and how to interpret the @color_line.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2,
- void *user_data);
-
-/**
- * hb_paint_radial_gradient_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the first circle's center
- * @y0: Y coordinate of the first circle's center
- * @r0: radius of the first circle
- * @x1: X coordinate of the second circle's center
- * @y1: Y coordinate of the second circle's center
- * @r1: radius of the second circle
- * @user_data: User data pointer passed to hb_paint_funcs_set_radial_gradient_func()
- *
- * A virtual method for the #hb_paint_funcs_t to paint a radial
- * gradient everywhere within the current clip.
- *
- * The @color_line object contains information about the colors of the gradients.
- * It is only valid for the duration of the callback, you cannot keep it around.
- *
- * The coordinates of the points are interpreted according
- * to the current transform.
- *
- * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details on how the points define the direction
- * of the gradient, and how to interpret the @color_line.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1,
- void *user_data);
-
-/**
- * hb_paint_sweep_gradient_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @color_line: Color information for the gradient
- * @x0: X coordinate of the circle's center
- * @y0: Y coordinate of the circle's center
- * @start_angle: the start angle, in radians
- * @end_angle: the end angle, in radians
- * @user_data: User data pointer passed to hb_paint_funcs_set_sweep_gradient_func()
- *
- * A virtual method for the #hb_paint_funcs_t to paint a sweep
- * gradient everywhere within the current clip.
- *
- * The @color_line object contains information about the colors of the gradients.
- * It is only valid for the duration of the callback, you cannot keep it around.
- *
- * The coordinates of the points are interpreted according
- * to the current transform.
- *
- * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details on how the points define the direction
- * of the gradient, and how to interpret the @color_line.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle,
- float end_angle,
- void *user_data);
-
-/**
- * hb_paint_composite_mode_t:
- * @HB_PAINT_COMPOSITE_MODE_CLEAR: clear destination layer (bounded)
- * @HB_PAINT_COMPOSITE_MODE_SRC: replace destination layer (bounded)
- * @HB_PAINT_COMPOSITE_MODE_SRC_OVER: draw source layer on top of destination layer
- * (bounded)
- * @HB_PAINT_COMPOSITE_MODE_SRC_IN: draw source where there was destination content
- * (unbounded)
- * @HB_PAINT_COMPOSITE_MODE_SRC_OUT: draw source where there was no destination
- * content (unbounded)
- * @HB_PAINT_COMPOSITE_MODE_SRC_ATOP: draw source on top of destination content and
- * only there
- * @HB_PAINT_COMPOSITE_MODE_DEST: ignore the source
- * @HB_PAINT_COMPOSITE_MODE_DEST_OVER: draw destination on top of source
- * @HB_PAINT_COMPOSITE_MODE_DEST_IN: leave destination only where there was
- * source content (unbounded)
- * @HB_PAINT_COMPOSITE_MODE_DEST_OUT: leave destination only where there was no
- * source content
- * @HB_PAINT_COMPOSITE_MODE_DEST_ATOP: leave destination on top of source content
- * and only there (unbounded)
- * @HB_PAINT_COMPOSITE_MODE_XOR: source and destination are shown where there is only
- * one of them
- * @HB_PAINT_COMPOSITE_MODE_PLUS: source and destination layers are accumulated
- * @HB_PAINT_COMPOSITE_MODE_MULTIPLY: source and destination layers are multiplied.
- * This causes the result to be at least as dark as the darker inputs.
- * @HB_PAINT_COMPOSITE_MODE_SCREEN: source and destination are complemented and
- * multiplied. This causes the result to be at least as light as the lighter
- * inputs.
- * @HB_PAINT_COMPOSITE_MODE_OVERLAY: multiplies or screens, depending on the
- * lightness of the destination color.
- * @HB_PAINT_COMPOSITE_MODE_DARKEN: replaces the destination with the source if it
- * is darker, otherwise keeps the source.
- * @HB_PAINT_COMPOSITE_MODE_LIGHTEN: replaces the destination with the source if it
- * is lighter, otherwise keeps the source.
- * @HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: brightens the destination color to reflect
- * the source color.
- * @HB_PAINT_COMPOSITE_MODE_COLOR_BURN: darkens the destination color to reflect
- * the source color.
- * @HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: Multiplies or screens, dependent on source
- * color.
- * @HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: Darkens or lightens, dependent on source
- * color.
- * @HB_PAINT_COMPOSITE_MODE_DIFFERENCE: Takes the difference of the source and
- * destination color.
- * @HB_PAINT_COMPOSITE_MODE_EXCLUSION: Produces an effect similar to difference, but
- * with lower contrast.
- * @HB_PAINT_COMPOSITE_MODE_HSL_HUE: Creates a color with the hue of the source
- * and the saturation and luminosity of the target.
- * @HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: Creates a color with the saturation
- * of the source and the hue and luminosity of the target. Painting with
- * this mode onto a gray area produces no change.
- * @HB_PAINT_COMPOSITE_MODE_HSL_COLOR: Creates a color with the hue and saturation
- * of the source and the luminosity of the target. This preserves the gray
- * levels of the target and is useful for coloring monochrome images or
- * tinting color images.
- * @HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: Creates a color with the luminosity of
- * the source and the hue and saturation of the target. This produces an
- * inverse effect to @HB_PAINT_COMPOSITE_MODE_HSL_COLOR.
- *
- * The values of this enumeration describe the compositing modes
- * that can be used when combining temporary redirected drawing
- * with the backdrop.
- *
- * See the OpenType spec [COLR](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)
- * section for details.
- *
- * Since: 7.0.0
- */
-typedef enum {
- HB_PAINT_COMPOSITE_MODE_CLEAR,
- HB_PAINT_COMPOSITE_MODE_SRC,
- HB_PAINT_COMPOSITE_MODE_DEST,
- HB_PAINT_COMPOSITE_MODE_SRC_OVER,
- HB_PAINT_COMPOSITE_MODE_DEST_OVER,
- HB_PAINT_COMPOSITE_MODE_SRC_IN,
- HB_PAINT_COMPOSITE_MODE_DEST_IN,
- HB_PAINT_COMPOSITE_MODE_SRC_OUT,
- HB_PAINT_COMPOSITE_MODE_DEST_OUT,
- HB_PAINT_COMPOSITE_MODE_SRC_ATOP,
- HB_PAINT_COMPOSITE_MODE_DEST_ATOP,
- HB_PAINT_COMPOSITE_MODE_XOR,
- HB_PAINT_COMPOSITE_MODE_PLUS,
- HB_PAINT_COMPOSITE_MODE_SCREEN,
- HB_PAINT_COMPOSITE_MODE_OVERLAY,
- HB_PAINT_COMPOSITE_MODE_DARKEN,
- HB_PAINT_COMPOSITE_MODE_LIGHTEN,
- HB_PAINT_COMPOSITE_MODE_COLOR_DODGE,
- HB_PAINT_COMPOSITE_MODE_COLOR_BURN,
- HB_PAINT_COMPOSITE_MODE_HARD_LIGHT,
- HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT,
- HB_PAINT_COMPOSITE_MODE_DIFFERENCE,
- HB_PAINT_COMPOSITE_MODE_EXCLUSION,
- HB_PAINT_COMPOSITE_MODE_MULTIPLY,
- HB_PAINT_COMPOSITE_MODE_HSL_HUE,
- HB_PAINT_COMPOSITE_MODE_HSL_SATURATION,
- HB_PAINT_COMPOSITE_MODE_HSL_COLOR,
- HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY
-} hb_paint_composite_mode_t;
-
-/**
- * hb_paint_push_group_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @user_data: User data pointer passed to hb_paint_funcs_set_push_group_func()
- *
- * A virtual method for the #hb_paint_funcs_t to use
- * an intermediate surface for subsequent paint calls.
- *
- * The drawing will be redirected to an intermediate surface
- * until a matching call to the #hb_paint_funcs_pop_group_func_t
- * vfunc.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_push_group_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- void *user_data);
-
-/**
- * hb_paint_pop_group_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @mode: the compositing mode to use
- * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func()
- *
- * A virtual method for the #hb_paint_funcs_t to undo
- * the effect of a prior call to the #hb_paint_funcs_push_group_func_t
- * vfunc.
- *
- * This call stops the redirection to the intermediate surface,
- * and then composites it on the previous surface, using the
- * compositing mode passed to this call.
- *
- * Since: 7.0.0
- */
-typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- hb_paint_composite_mode_t mode,
- void *user_data);
-
-/**
- * hb_paint_custom_palette_color_func_t:
- * @funcs: paint functions object
- * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
- * @color_index: the color index
- * @color: (out): fetched color
- * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func()
- *
- * A virtual method for the #hb_paint_funcs_t to fetch a color from the custom
- * color palette.
- *
- * Custom palette colors override the colors from the fonts selected color
- * palette. It is not necessary to override all palette entries; for entries
- * that should be taken from the font palette, return `false`.
- *
- * This function might get called multiple times, but the custom palette is
- * expected to remain unchanged for duration of a hb_font_paint_glyph() call.
- *
- * Return value: `true` if found, `false` otherwise
- *
- * Since: 7.0.0
- */
-typedef hb_bool_t (*hb_paint_custom_palette_color_func_t) (hb_paint_funcs_t *funcs,
- void *paint_data,
- unsigned int color_index,
- hb_color_t *color,
- void *user_data);
-
-
-/**
- * hb_paint_funcs_set_push_transform_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The push-transform callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the push-transform callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_push_transform_func (hb_paint_funcs_t *funcs,
- hb_paint_push_transform_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_pop_transform_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The pop-transform callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the pop-transform callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs,
- hb_paint_pop_transform_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_push_clip_glyph_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the push-clip-glyph callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs,
- hb_paint_push_clip_glyph_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_push_clip_rectangle_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-rectangle callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the push-clip-rect callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_push_clip_rectangle_func (hb_paint_funcs_t *funcs,
- hb_paint_push_clip_rectangle_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_pop_clip_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The pop-clip callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the pop-clip callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_pop_clip_func (hb_paint_funcs_t *funcs,
- hb_paint_pop_clip_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_color_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The paint-color callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the paint-color callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_color_func (hb_paint_funcs_t *funcs,
- hb_paint_color_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_image_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The paint-image callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the paint-image callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_image_func (hb_paint_funcs_t *funcs,
- hb_paint_image_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_linear_gradient_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The linear-gradient callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the linear-gradient callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_linear_gradient_func (hb_paint_funcs_t *funcs,
- hb_paint_linear_gradient_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_radial_gradient_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The radial-gradient callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the radial-gradient callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_radial_gradient_func (hb_paint_funcs_t *funcs,
- hb_paint_radial_gradient_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_sweep_gradient_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The sweep-gradient callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the sweep-gradient callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_sweep_gradient_func (hb_paint_funcs_t *funcs,
- hb_paint_sweep_gradient_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_push_group_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The push-group callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the push-group callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_push_group_func (hb_paint_funcs_t *funcs,
- hb_paint_push_group_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_pop_group_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The pop-group callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the pop-group callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs,
- hb_paint_pop_group_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-
-/**
- * hb_paint_funcs_set_custom_palette_color_func:
- * @funcs: A paint functions struct
- * @func: (closure user_data) (destroy destroy) (scope notified): The custom-palette-color callback
- * @user_data: Data to pass to @func
- * @destroy: (nullable): Function to call when @user_data is no longer needed
- *
- * Sets the custom-palette-color callback on the paint functions struct.
- *
- * Since: 7.0.0
- */
-HB_EXTERN void
-hb_paint_funcs_set_custom_palette_color_func (hb_paint_funcs_t *funcs,
- hb_paint_custom_palette_color_func_t func,
- void *user_data,
- hb_destroy_func_t destroy);
-/*
- * Manual API
- */
-
-HB_EXTERN void
-hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy);
-
-HB_EXTERN void
-hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);
-
-HB_EXTERN void
-hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font);
-
-HB_EXTERN void
-hb_paint_push_clip_rectangle (hb_paint_funcs_t *funcs, void *paint_data,
- float xmin, float ymin,
- float xmax, float ymax);
-
-HB_EXTERN void
-hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data);
-
-HB_EXTERN void
-hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data,
- hb_bool_t is_foreground,
- hb_color_t color);
-
-HB_EXTERN void
-hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data,
- hb_blob_t *image,
- unsigned int width,
- unsigned int height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents);
-
-HB_EXTERN void
-hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2);
-
-HB_EXTERN void
-hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float r0,
- float x1, float y1,
- float r1);
-
-HB_EXTERN void
-hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle, float end_angle);
-
-HB_EXTERN void
-hb_paint_push_group (hb_paint_funcs_t *funcs, void *paint_data);
-
-HB_EXTERN void
-hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
- hb_paint_composite_mode_t mode);
-
-HB_EXTERN hb_bool_t
-hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
- unsigned int color_index,
- hb_color_t *color);
-
-HB_END_DECLS
-
-#endif /* HB_PAINT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-paint.hh b/src/3rdparty/harfbuzz-ng/src/hb-paint.hh
deleted file mode 100644
index d291a4b9731..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-paint.hh
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright © 2022 Matthias Clasen
- *
- * 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.
- */
-
-#ifndef HB_PAINT_HH
-#define HB_PAINT_HH
-
-#include "hb.hh"
-#include "hb-face.hh"
-#include "hb-font.hh"
-
-#define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
- HB_PAINT_FUNC_IMPLEMENT (push_transform) \
- HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
- HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
- HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
- HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
- HB_PAINT_FUNC_IMPLEMENT (color) \
- HB_PAINT_FUNC_IMPLEMENT (image) \
- HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \
- HB_PAINT_FUNC_IMPLEMENT (radial_gradient) \
- HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \
- HB_PAINT_FUNC_IMPLEMENT (push_group) \
- HB_PAINT_FUNC_IMPLEMENT (pop_group) \
- HB_PAINT_FUNC_IMPLEMENT (custom_palette_color) \
- /* ^--- Add new callbacks here */
-
-struct hb_paint_funcs_t
-{
- hb_object_header_t header;
-
- struct {
-#define HB_PAINT_FUNC_IMPLEMENT(name) hb_paint_##name##_func_t name;
- HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
- } func;
-
- struct {
-#define HB_PAINT_FUNC_IMPLEMENT(name) void *name;
- HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
- } *user_data;
-
- struct {
-#define HB_PAINT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
- HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS
-#undef HB_PAINT_FUNC_IMPLEMENT
- } *destroy;
-
- void push_transform (void *paint_data,
- float xx, float yx,
- float xy, float yy,
- float dx, float dy)
- { func.push_transform (this, paint_data,
- xx, yx, xy, yy, dx, dy,
- !user_data ? nullptr : user_data->push_transform); }
- void pop_transform (void *paint_data)
- { func.pop_transform (this, paint_data,
- !user_data ? nullptr : user_data->pop_transform); }
- void push_clip_glyph (void *paint_data,
- hb_codepoint_t glyph,
- hb_font_t *font)
- { func.push_clip_glyph (this, paint_data,
- glyph,
- font,
- !user_data ? nullptr : user_data->push_clip_glyph); }
- void push_clip_rectangle (void *paint_data,
- float xmin, float ymin, float xmax, float ymax)
- { func.push_clip_rectangle (this, paint_data,
- xmin, ymin, xmax, ymax,
- !user_data ? nullptr : user_data->push_clip_rectangle); }
- void pop_clip (void *paint_data)
- { func.pop_clip (this, paint_data,
- !user_data ? nullptr : user_data->pop_clip); }
- void color (void *paint_data,
- hb_bool_t is_foreground,
- hb_color_t color)
- { func.color (this, paint_data,
- is_foreground, color,
- !user_data ? nullptr : user_data->color); }
- bool image (void *paint_data,
- hb_blob_t *image,
- unsigned width, unsigned height,
- hb_tag_t format,
- float slant,
- hb_glyph_extents_t *extents)
- { return func.image (this, paint_data,
- image, width, height, format, slant, extents,
- !user_data ? nullptr : user_data->image); }
- void linear_gradient (void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float x1, float y1,
- float x2, float y2)
- { func.linear_gradient (this, paint_data,
- color_line, x0, y0, x1, y1, x2, y2,
- !user_data ? nullptr : user_data->linear_gradient); }
- void radial_gradient (void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0, float r0,
- float x1, float y1, float r1)
- { func.radial_gradient (this, paint_data,
- color_line, x0, y0, r0, x1, y1, r1,
- !user_data ? nullptr : user_data->radial_gradient); }
- void sweep_gradient (void *paint_data,
- hb_color_line_t *color_line,
- float x0, float y0,
- float start_angle,
- float end_angle)
- { func.sweep_gradient (this, paint_data,
- color_line, x0, y0, start_angle, end_angle,
- !user_data ? nullptr : user_data->sweep_gradient); }
- void push_group (void *paint_data)
- { func.push_group (this, paint_data,
- !user_data ? nullptr : user_data->push_group); }
- void pop_group (void *paint_data,
- hb_paint_composite_mode_t mode)
- { func.pop_group (this, paint_data,
- mode,
- !user_data ? nullptr : user_data->pop_group); }
- bool custom_palette_color (void *paint_data,
- unsigned int color_index,
- hb_color_t *color)
- { return func.custom_palette_color (this, paint_data,
- color_index,
- color,
- !user_data ? nullptr : user_data->custom_palette_color); }
-
-
- /* Internal specializations. */
-
- void push_root_transform (void *paint_data,
- const hb_font_t *font)
- {
- float upem = font->face->get_upem ();
- int xscale = font->x_scale, yscale = font->y_scale;
- float slant = font->slant_xy;
-
- push_transform (paint_data,
- xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0);
- }
-
- void push_inverse_root_transform (void *paint_data,
- hb_font_t *font)
- {
- float upem = font->face->get_upem ();
- int xscale = font->x_scale ? font->x_scale : upem;
- int yscale = font->y_scale ? font->y_scale : upem;
- float slant = font->slant_xy;
-
- push_transform (paint_data,
- upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0);
- }
-
- HB_NODISCARD
- bool push_translate (void *paint_data,
- float dx, float dy)
- {
- if (!dx && !dy)
- return false;
-
- push_transform (paint_data,
- 1.f, 0.f, 0.f, 1.f, dx, dy);
- return true;
- }
-
- HB_NODISCARD
- bool push_scale (void *paint_data,
- float sx, float sy)
- {
- if (sx == 1.f && sy == 1.f)
- return false;
-
- push_transform (paint_data,
- sx, 0.f, 0.f, sy, 0.f, 0.f);
- return true;
- }
-
- HB_NODISCARD
- bool push_rotate (void *paint_data,
- float a)
- {
- if (!a)
- return false;
-
- float cc = cosf (a * HB_PI);
- float ss = sinf (a * HB_PI);
- push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f);
- return true;
- }
-
- HB_NODISCARD
- bool push_skew (void *paint_data,
- float sx, float sy)
- {
- if (!sx && !sy)
- return false;
-
- float x = tanf (-sx * HB_PI);
- float y = tanf (+sy * HB_PI);
- push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f);
- return true;
- }
-};
-DECLARE_NULL_INSTANCE (hb_paint_funcs_t);
-
-
-#endif /* HB_PAINT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-pool.hh b/src/3rdparty/harfbuzz-ng/src/hb-pool.hh
deleted file mode 100644
index d6eb778f5dd..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-pool.hh
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright © 2019 Facebook, 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.
- *
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_POOL_HH
-#define HB_POOL_HH
-
-#include "hb.hh"
-
-/* Memory pool for persistent allocation of small objects.
- *
- * Some AI musings on this, not necessarily true:
- *
- * This is a very simple implementation, but it's good enough for our
- * purposes. It's not thread-safe. It's not very fast. It's not
- * very memory efficient. It's not very cache efficient. It's not
- * very anything efficient. But it's simple and it works. And it's
- * good enough for our purposes. If you need something more
- * sophisticated, use a real allocator. Or use a real language. */
-
-template <typename T, unsigned ChunkLen = 32>
-struct hb_pool_t
-{
- hb_pool_t () : next (nullptr) {}
- ~hb_pool_t ()
- {
- next = nullptr;
-
- + hb_iter (chunks)
- | hb_apply (hb_free)
- ;
- }
-
- T* alloc ()
- {
- if (unlikely (!next))
- {
- if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
- chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t));
- if (unlikely (!chunk)) return nullptr;
- chunks.push (chunk);
- next = chunk->thread ();
- }
-
- T* obj = next;
- next = * ((T**) next);
-
- hb_memset (obj, 0, sizeof (T));
-
- return obj;
- }
-
- void release (T* obj)
- {
- * (T**) obj = next;
- next = obj;
- }
-
- private:
-
- static_assert (ChunkLen > 1, "");
- static_assert (sizeof (T) >= sizeof (void *), "");
- static_assert (alignof (T) % alignof (void *) == 0, "");
-
- struct chunk_t
- {
- T* thread ()
- {
- for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++)
- * (T**) &arrayZ[i] = &arrayZ[i + 1];
-
- * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr;
-
- return arrayZ;
- }
-
- T arrayZ[ChunkLen];
- };
-
- T* next;
- hb_vector_t<chunk_t *> chunks;
-};
-
-
-#endif /* HB_POOL_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh b/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh
deleted file mode 100644
index bf1b282d3d8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-priority-queue.hh
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright © 2020 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): Garret Rieger
- */
-
-#ifndef HB_PRIORITY_QUEUE_HH
-#define HB_PRIORITY_QUEUE_HH
-
-#include "hb.hh"
-#include "hb-vector.hh"
-
-/*
- * hb_priority_queue_t
- *
- * Priority queue implemented as a binary heap. Supports extract minimum
- * and insert operations.
- *
- * The priority queue is implemented as a binary heap, which is a complete
- * binary tree. The root of the tree is the minimum element. The heap
- * property is that the priority of a node is less than or equal to the
- * priority of its children. The heap is stored in an array, with the
- * children of node i stored at indices 2i + 1 and 2i + 2.
- */
-struct hb_priority_queue_t
-{
- private:
- typedef hb_pair_t<int64_t, unsigned> item_t;
- hb_vector_t<item_t> heap;
-
- public:
-
- void reset () { heap.resize (0); }
-
- bool in_error () const { return heap.in_error (); }
-
- void insert (int64_t priority, unsigned value)
- {
- heap.push (item_t (priority, value));
- if (unlikely (heap.in_error ())) return;
- bubble_up (heap.length - 1);
- }
-
- item_t pop_minimum ()
- {
- assert (!is_empty ());
-
- item_t result = heap.arrayZ[0];
-
- heap.arrayZ[0] = heap.arrayZ[heap.length - 1];
- heap.resize (heap.length - 1);
-
- if (!is_empty ())
- bubble_down (0);
-
- return result;
- }
-
- const item_t& minimum ()
- {
- return heap[0];
- }
-
- bool is_empty () const { return heap.length == 0; }
- explicit operator bool () const { return !is_empty (); }
- unsigned int get_population () const { return heap.length; }
-
- /* Sink interface. */
- hb_priority_queue_t& operator << (item_t item)
- { insert (item.first, item.second); return *this; }
-
- private:
-
- static constexpr unsigned parent (unsigned index)
- {
- return (index - 1) / 2;
- }
-
- static constexpr unsigned left_child (unsigned index)
- {
- return 2 * index + 1;
- }
-
- static constexpr unsigned right_child (unsigned index)
- {
- return 2 * index + 2;
- }
-
- void bubble_down (unsigned index)
- {
- assert (index < heap.length);
-
- unsigned left = left_child (index);
- unsigned right = right_child (index);
-
- bool has_left = left < heap.length;
- if (!has_left)
- // If there's no left, then there's also no right.
- return;
-
- bool has_right = right < heap.length;
- if (heap.arrayZ[index].first <= heap.arrayZ[left].first
- && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
- return;
-
- if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
- {
- swap (index, left);
- bubble_down (left);
- return;
- }
-
- swap (index, right);
- bubble_down (right);
- }
-
- void bubble_up (unsigned index)
- {
- assert (index < heap.length);
-
- if (index == 0) return;
-
- unsigned parent_index = parent (index);
- if (heap.arrayZ[parent_index].first <= heap.arrayZ[index].first)
- return;
-
- swap (index, parent_index);
- bubble_up (parent_index);
- }
-
- void swap (unsigned a, unsigned b)
- {
- assert (a < heap.length);
- assert (b < heap.length);
- hb_swap (heap.arrayZ[a], heap.arrayZ[b]);
- }
-};
-
-#endif /* HB_PRIORITY_QUEUE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
new file mode 100644
index 00000000000..acddd893810
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -0,0 +1,899 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2011,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_PRIVATE_HH
+#define HB_PRIVATE_HH
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb.h"
+#define HB_H_IN
+#ifdef HAVE_OT
+#include "hb-ot.h"
+#define HB_OT_H_IN
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.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) \
+ && defined(hb_calloc_impl) \
+ && defined(hb_realloc_impl) \
+ && defined(hb_free_impl)
+extern "C" void* hb_malloc_impl(size_t size);
+extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
+extern "C" void* hb_realloc_impl(void *ptr, size_t size);
+extern "C" void hb_free_impl(void *ptr);
+#define malloc hb_malloc_impl
+#define calloc hb_calloc_impl
+#define realloc hb_realloc_impl
+#define free hb_free_impl
+#endif
+
+
+/* Compiler attributes */
+
+
+#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)
+#endif
+
+#if !defined(__GNUC__) && !defined(__clang__)
+#undef __attribute__
+#define __attribute__(x)
+#endif
+
+#if __GNUC__ >= 3
+#define HB_PURE_FUNC __attribute__((pure))
+#define HB_CONST_FUNC __attribute__((const))
+#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#else
+#define HB_PURE_FUNC
+#define HB_CONST_FUNC
+#define HB_PRINTF_FUNC(format_idx, arg_idx)
+#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
+
+#ifndef HB_INTERNAL
+# if !defined(__MINGW32__) && !defined(__CYGWIN__)
+# define HB_INTERNAL __attribute__((__visibility__("hidden")))
+# else
+# define HB_INTERNAL
+# endif
+#endif
+
+#if __GNUC__ >= 3
+#define HB_FUNC __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define HB_FUNC __FUNCSIG__
+#else
+#define HB_FUNC __func__
+#endif
+
+/*
+ * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
+ * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
+ * cases that fall through without a break or return statement. HB_FALLTHROUGH
+ * is only needed on cases that have code:
+ *
+ * switch (foo) {
+ * case 1: // These cases have no code. No fallthrough annotations are needed.
+ * case 2:
+ * case 3:
+ * foo = 4; // This case has code, so a fallthrough annotation is needed:
+ * HB_FALLTHROUGH;
+ * default:
+ * return foo;
+ * }
+ */
+#if defined(__clang__) && __cplusplus >= 201103L
+ /* clang's fallthrough annotations are only available starting in C++11. */
+# define HB_FALLTHROUGH [[clang::fallthrough]]
+#elif defined(_MSC_VER)
+ /*
+ * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
+ * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
+ */
+# include <sal.h>
+# define HB_FALLTHROUGH __fallthrough
+#else
+# define HB_FALLTHROUGH /* FALLTHROUGH */
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ /* We need Windows Vista for both Uniscribe backend and for
+ * MemoryBarrier. We don't support compiling on Windows XP,
+ * though we run on it fine. */
+# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
+# undef _WIN32_WINNT
+# endif
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0600
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+# ifndef STRICT
+# define STRICT 1
+# endif
+
+# if defined(_WIN32_WCE)
+ /* Some things not defined on Windows CE. */
+# define vsnprintf _vsnprintf
+# 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) nullptr
+# endif
+# if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+# endif
+#endif
+
+#if HAVE_ATEXIT
+/* atexit() is only safe to be called from shared libraries on certain
+ * platforms. Whitelist.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
+# if defined(__linux) && defined(__GLIBC_PREREQ)
+# if __GLIBC_PREREQ(2,3)
+/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
+# define HB_USE_ATEXIT 1
+# endif
+# elif defined(_MSC_VER) || defined(__MINGW32__)
+/* For MSVC:
+ * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx
+ * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx
+ * mingw32 headers say atexit is safe to use in shared libraries.
+ */
+# define HB_USE_ATEXIT 1
+# elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+/* This was fixed in Android NKD r8 or r8b:
+ * https://code.google.com/p/android/issues/detail?id=6455
+ * which introduced GCC 4.6:
+ * https://developer.android.com/tools/sdk/ndk/index.html
+ */
+# define HB_USE_ATEXIT 1
+# endif
+#endif
+
+/* Basics */
+
+#undef MIN
+template <typename Type>
+static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
+
+#undef MAX
+template <typename Type>
+static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
+
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
+
+#undef ARRAY_LENGTH
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+#define HB_STMT_START do
+#define HB_STMT_END while (0)
+
+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>))
+
+/* Lets assert int types. Saves trouble down the road. */
+
+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), "");
+
+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 */
+
+#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
+#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
+#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type)
+
+#ifdef __GNUC__
+# define _ASSERT_INSTANCE_POD1(_line, _instance) \
+ HB_STMT_START { \
+ typedef __typeof__(_instance) _type_##_line; \
+ _ASSERT_TYPE_POD1 (_line, _type_##_line); \
+ } HB_STMT_END
+#else
+# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested
+#endif
+# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance)
+# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
+
+/* Check _assertion in a method environment */
+#define _ASSERT_POD1(_line) \
+ HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
+ { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
+# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
+# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
+
+
+
+/* Misc */
+
+/* Void! */
+struct _hb_void_t {};
+typedef const _hb_void_t *hb_void_t;
+#define HB_VOID ((const _hb_void_t *) nullptr)
+
+/* Return the number of 1 bits in mask. */
+static inline HB_CONST_FUNC unsigned int
+_hb_popcount32 (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+ return __builtin_popcount (mask);
+#else
+ /* "HACKMEM 169" */
+ uint32_t y;
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ 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
+_hb_bit_storage (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
+#else
+ unsigned int n_bits = 0;
+ while (number) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+/* Returns the number of zero bits in the least significant side of number */
+static inline HB_CONST_FUNC unsigned int
+_hb_ctz (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? __builtin_ctz (number) : 0;
+#else
+ unsigned int n_bits = 0;
+ if (unlikely (!number)) return 0;
+ while (!(number & 1)) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+static inline bool
+_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
+{
+ return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+
+
+/* arrays and maps */
+
+
+#define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
+template <typename Type, unsigned int StaticSize=16>
+struct hb_prealloced_array_t
+{
+ unsigned int len;
+ unsigned int allocated;
+ Type *array;
+ Type static_array[StaticSize];
+
+ 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 (unlikely (!resize (len + 1)))
+ return nullptr;
+
+ return &array[len - 1];
+ }
+
+ 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 false;
+
+ array = new_array;
+ allocated = new_allocated;
+ }
+
+ len = size;
+ return true;
+ }
+
+ inline void pop (void)
+ {
+ len--;
+ }
+
+ inline void remove (unsigned int i)
+ {
+ if (unlikely (i >= len))
+ return;
+ memmove (static_cast<void *> (&array[i]),
+ static_cast<void *> (&array[i + 1]),
+ (len - i - 1) * sizeof (Type));
+ len--;
+ }
+
+ inline void shrink (unsigned int l)
+ {
+ if (l < len)
+ len = l;
+ }
+
+ template <typename T>
+ inline Type *find (T v) {
+ for (unsigned int i = 0; i < len; i++)
+ if (array[i] == v)
+ return &array[i];
+ 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 nullptr;
+ }
+
+ inline void qsort (void)
+ {
+ ::qsort (array, len, sizeof (Type), Type::cmp);
+ }
+
+ inline void qsort (unsigned int start, unsigned int end)
+ {
+ ::qsort (array + start, end - start, sizeof (Type), Type::cmp);
+ }
+
+ template <typename T>
+ inline Type *bsearch (T *x)
+ {
+ unsigned int i;
+ return bfind (x, &i) ? &array[i] : nullptr;
+ }
+ template <typename T>
+ inline const Type *bsearch (T *x) const
+ {
+ 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 = nullptr;
+ allocated = len = 0;
+ }
+};
+
+template <typename Type>
+struct hb_auto_array_t : hb_prealloced_array_t <Type>
+{
+ hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
+ ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
+};
+
+
+#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
+template <typename item_t, typename lock_t>
+struct hb_lockable_set_t
+{
+ hb_prealloced_array_t <item_t, 1> items;
+
+ inline void init (void) { items.init (); }
+
+ template <typename T>
+ inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item) {
+ if (replace) {
+ item_t old = *item;
+ *item = v;
+ l.unlock ();
+ old.finish ();
+ }
+ else {
+ item = nullptr;
+ l.unlock ();
+ }
+ } else {
+ item = items.push ();
+ if (likely (item))
+ *item = v;
+ l.unlock ();
+ }
+ return item;
+ }
+
+ template <typename T>
+ inline void remove (T v, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item) {
+ item_t old = *item;
+ *item = items[items.len - 1];
+ items.pop ();
+ l.unlock ();
+ old.finish ();
+ } else {
+ l.unlock ();
+ }
+ }
+
+ template <typename T>
+ inline bool find (T v, item_t *i, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (item)
+ *i = *item;
+ l.unlock ();
+ return !!item;
+ }
+
+ template <typename T>
+ inline item_t *find_or_insert (T v, lock_t &l)
+ {
+ l.lock ();
+ item_t *item = items.find (v);
+ if (!item) {
+ item = items.push ();
+ if (likely (item))
+ *item = v;
+ }
+ l.unlock ();
+ return item;
+ }
+
+ inline void finish (lock_t &l)
+ {
+ if (!items.len) {
+ /* No need for locking. */
+ items.finish ();
+ return;
+ }
+ l.lock ();
+ while (items.len) {
+ item_t old = items[items.len - 1];
+ items.pop ();
+ l.unlock ();
+ old.finish ();
+ l.lock ();
+ }
+ items.finish ();
+ l.unlock ();
+ }
+
+};
+
+
+/* ASCII tag/character handling */
+
+static inline bool ISALPHA (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
+static inline bool ISALNUM (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
+static inline unsigned char TOUPPER (unsigned char c)
+{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
+static inline unsigned char TOLOWER (unsigned char c)
+{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
+
+
+/* HB_NDEBUG disables some sanity checks that are very safe to disable and
+ * should be disabled in production systems. If NDEBUG is defined, enable
+ * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
+ * light-weight) to be enabled, then HB_DEBUG can be defined to disable
+ * the costlier checks. */
+#ifdef NDEBUG
+#define HB_NDEBUG
+#endif
+
+
+/* Misc */
+
+template <typename T> class hb_assert_unsigned_t;
+template <> class hb_assert_unsigned_t<unsigned char> {};
+template <> class hb_assert_unsigned_t<unsigned short> {};
+template <> class hb_assert_unsigned_t<unsigned int> {};
+template <> class hb_assert_unsigned_t<unsigned long> {};
+
+template <typename T> static inline bool
+hb_in_range (T u, T lo, T hi)
+{
+ /* The sizeof() is here to force template instantiation.
+ * I'm sure there are better ways to do this but can't think of
+ * 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. */
+ 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! */
+ return (T)(u - lo) <= (T)(hi - lo);
+}
+
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+{
+ return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+}
+
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+{
+ return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+}
+
+
+/* Enable bitwise ops on enums marked as flags_t */
+/* To my surprise, looks like the function resolver is happy to silently cast
+ * 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/harfbuzz/harfbuzz/pull/163
+ */
+#ifdef _MSC_VER
+# pragma warning(disable:4200)
+# pragma warning(disable:4800)
+#endif
+#define HB_MARK_AS_FLAG_T(T) \
+ extern "C++" { \
+ static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
+ static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
+ static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
+ static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
+ static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
+ static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
+ static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
+ }
+
+
+/* Useful for set-operations on small enums.
+ * For example, for testing "x ∈ {x1, x2, x3}" use:
+ * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
+ */
+#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))
+
+
+template <typename T, typename T2> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
+{
+ for (unsigned int i = 1; i < len; i++)
+ {
+ unsigned int j = i;
+ while (j && compar (&array[j - 1], &array[i]) > 0)
+ j--;
+ if (i == j)
+ continue;
+ /* Move item i to occupy place for item j, shift what's in between. */
+ {
+ T t = array[i];
+ memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
+ array[j] = t;
+ }
+ if (array2)
+ {
+ T2 t = array2[i];
+ memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
+ array2[j] = 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 *) nullptr);
+}
+
+static inline hb_bool_t
+hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
+{
+ /* Pain because we don't know whether s is nul-terminated. */
+ char buf[64];
+ len = MIN (ARRAY_LENGTH (buf) - 1, len);
+ strncpy (buf, s, len);
+ buf[len] = '\0';
+
+ char *end;
+ errno = 0;
+ unsigned long v = strtoul (buf, &end, base);
+ if (errno) return false;
+ if (*end) return false;
+ *out = v;
+ return true;
+}
+
+
+/* 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
+{
+ unsigned int initialized : 1;
+ unsigned int uniscribe_bug_compatible : 1;
+};
+
+union hb_options_union_t {
+ unsigned int i;
+ hb_options_t opts;
+};
+static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
+
+HB_INTERNAL void
+_hb_options_init (void);
+
+extern HB_INTERNAL hb_options_union_t _hb_options;
+
+static inline hb_options_t
+hb_options (void)
+{
+ if (unlikely (!_hb_options.i))
+ _hb_options_init ();
+
+ return _hb_options.opts;
+}
+
+/* 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-repacker.hh b/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh
deleted file mode 100644
index cd57ade0722..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-repacker.hh
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright © 2020 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): Garret Rieger
- */
-
-#ifndef HB_REPACKER_HH
-#define HB_REPACKER_HH
-
-#include "hb-open-type.hh"
-#include "hb-map.hh"
-#include "hb-vector.hh"
-#include "graph/graph.hh"
-#include "graph/gsubgpos-graph.hh"
-#include "graph/serialize.hh"
-
-using graph::graph_t;
-
-/*
- * For a detailed writeup on the overflow resolution algorithm see:
- * docs/repacker.md
- */
-
-struct lookup_size_t
-{
- unsigned lookup_index;
- size_t size;
- unsigned num_subtables;
-
- static int cmp (const void* a, const void* b)
- {
- return cmp ((const lookup_size_t*) a,
- (const lookup_size_t*) b);
- }
-
- static int cmp (const lookup_size_t* a, const lookup_size_t* b)
- {
- double subtables_per_byte_a = (double) a->num_subtables / (double) a->size;
- double subtables_per_byte_b = (double) b->num_subtables / (double) b->size;
- if (subtables_per_byte_a == subtables_per_byte_b) {
- return b->lookup_index - a->lookup_index;
- }
-
- double cmp = subtables_per_byte_b - subtables_per_byte_a;
- if (cmp < 0) return -1;
- if (cmp > 0) return 1;
- return 0;
- }
-};
-
-static inline
-bool _presplit_subtables_if_needed (graph::gsubgpos_graph_context_t& ext_context)
-{
- // For each lookup this will check the size of subtables and split them as needed
- // so that no subtable is at risk of overflowing. (where we support splitting for
- // that subtable type).
- //
- // TODO(grieger): de-dup newly added nodes as necessary. Probably just want a full de-dup
- // pass after this processing is done. Not super necessary as splits are
- // only done where overflow is likely, so de-dup probably will get undone
- // later anyways.
- for (unsigned lookup_index : ext_context.lookups.keys ())
- {
- graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
- if (!lookup->split_subtables_if_needed (ext_context, lookup_index))
- return false;
- }
-
- return true;
-}
-
-/*
- * Analyze the lookups in a GSUB/GPOS table and decide if any should be promoted
- * to extension lookups.
- */
-static inline
-bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context)
-{
- // Simple Algorithm (v1, current):
- // 1. Calculate how many bytes each non-extension lookup consumes.
- // 2. Select up to 64k of those to remain as non-extension (greedy, highest subtables per byte first)
- // 3. Promote the rest.
- //
- // Advanced Algorithm (v2, not implemented):
- // 1. Perform connected component analysis using lookups as roots.
- // 2. Compute size of each connected component.
- // 3. Select up to 64k worth of connected components to remain as non-extensions.
- // (greedy, highest subtables per byte first)
- // 4. Promote the rest.
-
- // TODO(garretrieger): support extension demotion, then consider all lookups. Requires advanced algo.
- // TODO(garretrieger): also support extension promotion during iterative resolution phase, then
- // we can use a less conservative threshold here.
- // TODO(grieger): skip this for the 24 bit case.
- if (!ext_context.lookups) return true;
-
- hb_vector_t<lookup_size_t> lookup_sizes;
- lookup_sizes.alloc (ext_context.lookups.get_population (), true);
-
- for (unsigned lookup_index : ext_context.lookups.keys ())
- {
- const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
- hb_set_t visited;
- lookup_sizes.push (lookup_size_t {
- lookup_index,
- ext_context.graph.find_subgraph_size (lookup_index, visited),
- lookup->number_of_subtables (),
- });
- }
-
- lookup_sizes.qsort ();
-
- size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size ();
- size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups
- size_t l3_l4_size = 0; // Lookups + SubTables
- size_t l4_plus_size = 0; // SubTables + their descendants
-
- // Start by assuming all lookups are using extension subtables, this size will be removed later
- // if it's decided to not make a lookup extension.
- for (auto p : lookup_sizes)
- {
- unsigned subtables_size = p.num_subtables * 8;
- l3_l4_size += subtables_size;
- l4_plus_size += subtables_size;
- }
-
- bool layers_full = false;
- for (auto p : lookup_sizes)
- {
- const graph::Lookup* lookup = ext_context.lookups.get(p.lookup_index);
- if (lookup->is_extension (ext_context.table_tag))
- // already an extension so size is counted by the loop above.
- continue;
-
- if (!layers_full)
- {
- size_t lookup_size = ext_context.graph.vertices_[p.lookup_index].table_size ();
- hb_set_t visited;
- size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size;
- size_t remaining_size = p.size - subtables_size - lookup_size;
-
- l2_l3_size += lookup_size;
- l3_l4_size += lookup_size + subtables_size;
- l3_l4_size -= p.num_subtables * 8;
- l4_plus_size += subtables_size + remaining_size;
-
- if (l2_l3_size < (1 << 16)
- && l3_l4_size < (1 << 16)
- && l4_plus_size < (1 << 16)) continue; // this lookup fits within all layers groups
-
- layers_full = true;
- }
-
- if (!ext_context.lookups.get(p.lookup_index)->make_extension (ext_context, p.lookup_index))
- return false;
- }
-
- return true;
-}
-
-static inline
-bool _try_isolating_subgraphs (const hb_vector_t<graph::overflow_record_t>& overflows,
- graph_t& sorted_graph)
-{
- unsigned space = 0;
- hb_set_t roots_to_isolate;
-
- for (int i = overflows.length - 1; i >= 0; i--)
- {
- const graph::overflow_record_t& r = overflows[i];
-
- unsigned root;
- unsigned overflow_space = sorted_graph.space_for (r.parent, &root);
- if (!overflow_space) continue;
- if (sorted_graph.num_roots_for_space (overflow_space) <= 1) continue;
-
- if (!space) {
- space = overflow_space;
- }
-
- if (space == overflow_space)
- roots_to_isolate.add(root);
- }
-
- if (!roots_to_isolate) return false;
-
- unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u);
- if (roots_to_isolate.get_population () > maximum_to_move) {
- // Only move at most half of the roots in a space at a time.
- unsigned extra = roots_to_isolate.get_population () - maximum_to_move;
- while (extra--) {
- uint32_t root = HB_SET_VALUE_INVALID;
- roots_to_isolate.previous (&root);
- roots_to_isolate.del (root);
- }
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Overflow in space %u (%u roots). Moving %u roots to space %u.",
- space,
- sorted_graph.num_roots_for_space (space),
- roots_to_isolate.get_population (),
- sorted_graph.next_space ());
-
- sorted_graph.isolate_subgraph (roots_to_isolate);
- sorted_graph.move_to_new_space (roots_to_isolate);
-
- return true;
-}
-
-static inline
-bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows,
- hb_set_t& priority_bumped_parents,
- graph_t& sorted_graph)
-{
- bool resolution_attempted = false;
-
- // Try resolving the furthest overflows first.
- for (int i = overflows.length - 1; i >= 0; i--)
- {
- const graph::overflow_record_t& r = overflows[i];
- const auto& child = sorted_graph.vertices_[r.child];
- if (child.is_shared ())
- {
- // The child object is shared, we may be able to eliminate the overflow
- // by duplicating it.
- if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue;
- return true;
- }
-
- if (child.is_leaf () && !priority_bumped_parents.has (r.parent))
- {
- // This object is too far from it's parent, attempt to move it closer.
- //
- // TODO(garretrieger): initially limiting this to leaf's since they can be
- // moved closer with fewer consequences. However, this can
- // likely can be used for non-leafs as well.
- // TODO(garretrieger): also try lowering priority of the parent. Make it
- // get placed further up in the ordering, closer to it's children.
- // this is probably preferable if the total size of the parent object
- // is < then the total size of the children (and the parent can be moved).
- // Since in that case moving the parent will cause a smaller increase in
- // the length of other offsets.
- if (sorted_graph.raise_childrens_priority (r.parent)) {
- priority_bumped_parents.add (r.parent);
- resolution_attempted = true;
- }
- continue;
- }
-
- // TODO(garretrieger): add additional offset resolution strategies
- // - Promotion to extension lookups.
- // - Table splitting.
- }
-
- return resolution_attempted;
-}
-
-inline bool
-hb_resolve_graph_overflows (hb_tag_t table_tag,
- unsigned max_rounds ,
- bool recalculate_extensions,
- graph_t& sorted_graph /* IN/OUT */)
-{
- sorted_graph.sort_shortest_distance ();
- if (sorted_graph.in_error ())
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state after initial sort.");
- return false;
- }
-
- bool will_overflow = graph::will_overflow (sorted_graph);
- if (!will_overflow)
- return true;
-
- graph::gsubgpos_graph_context_t ext_context (table_tag, sorted_graph);
- if ((table_tag == HB_OT_TAG_GPOS
- || table_tag == HB_OT_TAG_GSUB)
- && will_overflow)
- {
- if (recalculate_extensions)
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Splitting subtables if needed.");
- if (!_presplit_subtables_if_needed (ext_context)) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Subtable splitting failed.");
- return false;
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Promoting lookups to extensions if needed.");
- if (!_promote_extensions_if_needed (ext_context)) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Extensions promotion failed.");
- return false;
- }
- }
-
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs.");
- if (sorted_graph.assign_spaces ())
- sorted_graph.sort_shortest_distance ();
- else
- sorted_graph.sort_shortest_distance_if_needed ();
- }
-
- unsigned round = 0;
- hb_vector_t<graph::overflow_record_t> overflows;
- // TODO(garretrieger): select a good limit for max rounds.
- while (!sorted_graph.in_error ()
- && graph::will_overflow (sorted_graph, &overflows)
- && round < max_rounds) {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %u ===", round);
- print_overflows (sorted_graph, overflows);
-
- hb_set_t priority_bumped_parents;
-
- if (!_try_isolating_subgraphs (overflows, sorted_graph))
- {
- // Don't count space isolation towards round limit. Only increment
- // round counter if space isolation made no changes.
- round++;
- if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :(");
- break;
- }
- }
-
- sorted_graph.sort_shortest_distance ();
- }
-
- if (sorted_graph.in_error ())
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state.");
- return false;
- }
-
- if (graph::will_overflow (sorted_graph))
- {
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
- return false;
- }
-
- return true;
-}
-
-/*
- * Attempts to modify the topological sorting of the provided object graph to
- * eliminate offset overflows in the links between objects of the graph. If a
- * non-overflowing ordering is found the updated graph is serialized it into the
- * provided serialization context.
- *
- * If necessary the structure of the graph may be modified in ways that do not
- * affect the functionality of the graph. For example shared objects may be
- * duplicated.
- *
- * For a detailed writeup describing how the algorithm operates see:
- * docs/repacker.md
- */
-template<typename T>
-inline hb_blob_t*
-hb_resolve_overflows (const T& packed,
- hb_tag_t table_tag,
- unsigned max_rounds = 20,
- bool recalculate_extensions = false) {
- graph_t sorted_graph (packed);
- if (sorted_graph.in_error ())
- {
- // Invalid graph definition.
- return nullptr;
- }
-
- if (!sorted_graph.is_fully_connected ())
- {
- sorted_graph.print_orphaned_nodes ();
- return nullptr;
- }
-
- if (sorted_graph.in_error ())
- {
- // Allocations failed somewhere
- DEBUG_MSG (SUBSET_REPACK, nullptr,
- "Graph is in error, likely due to a memory allocation error.");
- return nullptr;
- }
-
- if (!hb_resolve_graph_overflows (table_tag, max_rounds, recalculate_extensions, sorted_graph))
- return nullptr;
-
- return graph::serialize (sorted_graph);
-}
-
-#endif /* HB_REPACKER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh b/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh
deleted file mode 100644
index 5259891b7e0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-sanitize.hh
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2012,2018 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
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_SANITIZE_HH
-#define HB_SANITIZE_HH
-
-#include "hb.hh"
-#include "hb-blob.hh"
-#include "hb-dispatch.hh"
-
-
-/*
- * Sanitize
- *
- *
- * === Introduction ===
- *
- * The sanitize machinery is at the core of our zero-cost font loading. We
- * mmap() font file into memory and create a blob out of it. Font subtables
- * are returned as a readonly sub-blob of the main font blob. These table
- * blobs are then sanitized before use, to ensure invalid memory access does
- * not happen. The toplevel sanitize API use is like, eg. to load the 'head'
- * table:
- *
- * hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (face);
- *
- * The blob then can be converted to a head table struct with:
- *
- * const head *head_table = head_blob->as<head> ();
- *
- * What the reference_table does is, to call hb_face_reference_table() to load
- * the table blob, sanitize it and return either the sanitized blob, or empty
- * blob if sanitization failed. The blob->as() function returns the null
- * object of its template type argument if the blob is empty. Otherwise, it
- * just casts the blob contents to the desired type.
- *
- * Sanitizing a blob of data with a type T works as follows (with minor
- * simplification):
- *
- * - Cast blob content to T*, call sanitize() method of it,
- * - If sanitize succeeded, return blob.
- * - Otherwise, if blob is not writable, try making it writable,
- * or copy if cannot be made writable in-place,
- * - Call sanitize() again. Return blob if sanitize succeeded.
- * - Return empty blob otherwise.
- *
- *
- * === The sanitize() contract ===
- *
- * The sanitize() method of each object type shall return true if it's safe to
- * call other methods of the object, and %false otherwise.
- *
- * Note that what sanitize() checks for might align with what the specification
- * describes as valid table data, but does not have to be. In particular, we
- * do NOT want to be pedantic and concern ourselves with validity checks that
- * are irrelevant to our use of the table. On the contrary, we want to be
- * lenient with error handling and accept invalid data to the extent that it
- * does not impose extra burden on us.
- *
- * Based on the sanitize contract, one can see that what we check for depends
- * on how we use the data in other table methods. Ie. if other table methods
- * assume that offsets do NOT point out of the table data block, then that's
- * something sanitize() must check for (GSUB/GPOS/GDEF/etc work this way). On
- * the other hand, if other methods do such checks themselves, then sanitize()
- * does not have to bother with them (glyf/local work this way). The choice
- * depends on the table structure and sanitize() performance. For example, to
- * check glyf/loca offsets in sanitize() would cost O(num-glyphs). We try hard
- * to avoid such costs during font loading. By postponing such checks to the
- * actual glyph loading, we reduce the sanitize cost to O(1) and total runtime
- * cost to O(used-glyphs). As such, this is preferred.
- *
- * The same argument can be made re GSUB/GPOS/GDEF, but there, the table
- * structure is so complicated that by checking all offsets at sanitize() time,
- * we make the code much simpler in other methods, as offsets and referenced
- * objects do not need to be validated at each use site.
- */
-
-/* This limits sanitizing time on really broken fonts. */
-#ifndef HB_SANITIZE_MAX_EDITS
-#define HB_SANITIZE_MAX_EDITS 32
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_FACTOR
-#define HB_SANITIZE_MAX_OPS_FACTOR 64
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MIN
-#define HB_SANITIZE_MAX_OPS_MIN 16384
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MAX
-#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
-#endif
-#ifndef HB_SANITIZE_MAX_SUBTABLES
-#define HB_SANITIZE_MAX_SUBTABLES 0x4000
-#endif
-
-struct hb_sanitize_context_t :
- hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
-{
- hb_sanitize_context_t () :
- start (nullptr), end (nullptr),
- max_ops (0), max_subtables (0),
- recursion_depth (0),
- writable (false), edit_count (0),
- blob (nullptr),
- num_glyphs (65536),
- num_glyphs_set (false) {}
-
- const char *get_name () { return "SANITIZE"; }
- template <typename T, typename F>
- bool may_dispatch (const T *obj HB_UNUSED, const F *format)
- { return format->sanitize (this); }
- static return_t default_return_value () { return true; }
- static return_t no_dispatch_return_value () { return false; }
- bool stop_sublookup_iteration (const return_t r) const { return !r; }
-
- bool visit_subtables (unsigned count)
- {
- max_subtables += count;
- return max_subtables < HB_SANITIZE_MAX_SUBTABLES;
- }
-
- private:
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.sanitize (this, std::forward<Ts> (ds)...) )
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.dispatch (this, std::forward<Ts> (ds)...) )
- public:
- template <typename T, typename ...Ts> auto
- dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
- ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
-
-
- void init (hb_blob_t *b)
- {
- this->blob = hb_blob_reference (b);
- this->writable = false;
- }
-
- void set_num_glyphs (unsigned int num_glyphs_)
- {
- num_glyphs = num_glyphs_;
- num_glyphs_set = true;
- }
- unsigned int get_num_glyphs () { return num_glyphs; }
-
- void set_max_ops (int max_ops_) { max_ops = max_ops_; }
-
- template <typename T>
- void set_object (const T *obj)
- {
- reset_object ();
-
- if (!obj) return;
-
- const char *obj_start = (const char *) obj;
- if (unlikely (obj_start < this->start || this->end <= obj_start))
- this->start = this->end = nullptr;
- else
- {
- this->start = obj_start;
- this->end = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ());
- }
- }
-
- void reset_object ()
- {
- this->start = this->blob->data;
- this->end = this->start + this->blob->length;
- assert (this->start <= this->end); /* Must not overflow. */
- }
-
- void start_processing ()
- {
- reset_object ();
- unsigned m;
- if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m)))
- this->max_ops = HB_SANITIZE_MAX_OPS_MAX;
- else
- this->max_ops = hb_clamp (m,
- (unsigned) HB_SANITIZE_MAX_OPS_MIN,
- (unsigned) HB_SANITIZE_MAX_OPS_MAX);
- this->edit_count = 0;
- this->debug_depth = 0;
- this->recursion_depth = 0;
-
- DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
- "start [%p..%p] (%lu bytes)",
- this->start, this->end,
- (unsigned long) (this->end - this->start));
- }
-
- void end_processing ()
- {
- DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
- "end [%p..%p] %u edit requests",
- this->start, this->end, this->edit_count);
-
- hb_blob_destroy (this->blob);
- this->blob = nullptr;
- this->start = this->end = nullptr;
- }
-
- unsigned get_edit_count () { return edit_count; }
-
-
- bool check_ops(unsigned count)
- {
- /* Avoid underflow */
- if (unlikely (this->max_ops < 0 || count >= (unsigned) this->max_ops))
- {
- this->max_ops = -1;
- return false;
- }
- return (this->max_ops -= (int) count) > 0;
- }
-
- bool check_range (const void *base,
- unsigned int len) const
- {
- const char *p = (const char *) base;
- bool ok = !len ||
- (this->start <= p &&
- p <= this->end &&
- (unsigned int) (this->end - p) >= len &&
- (this->max_ops -= len) > 0);
-
- DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
- "check_range [%p..%p]"
- " (%u bytes) in [%p..%p] -> %s",
- p, p + len, len,
- this->start, this->end,
- ok ? "OK" : "OUT-OF-RANGE");
-
- return likely (ok);
- }
-
- template <typename T>
- bool check_range (const T *base,
- unsigned int a,
- unsigned int b) const
- {
- unsigned m;
- return !hb_unsigned_mul_overflows (a, b, &m) &&
- this->check_range (base, m);
- }
-
- template <typename T>
- bool check_range (const T *base,
- unsigned int a,
- unsigned int b,
- unsigned int c) const
- {
- unsigned m;
- return !hb_unsigned_mul_overflows (a, b, &m) &&
- this->check_range (base, m, c);
- }
-
- template <typename T>
- bool check_array (const T *base, unsigned int len) const
- {
- return this->check_range (base, len, hb_static_size (T));
- }
-
- template <typename T>
- bool check_array (const T *base,
- unsigned int a,
- unsigned int b) const
- {
- return this->check_range (base, a, b, hb_static_size (T));
- }
-
- bool check_start_recursion (int max_depth)
- {
- if (unlikely (recursion_depth >= max_depth)) return false;
- return ++recursion_depth;
- }
-
- bool end_recursion (bool result)
- {
- recursion_depth--;
- return result;
- }
-
- template <typename Type>
- bool check_struct (const Type *obj) const
- { return likely (this->check_range (obj, obj->min_size)); }
-
- bool may_edit (const void *base, unsigned int len)
- {
- if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
- return false;
-
- const char *p = (const char *) base;
- this->edit_count++;
-
- DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
- "may_edit(%u) [%p..%p] (%u bytes) in [%p..%p] -> %s",
- this->edit_count,
- p, p + len, len,
- this->start, this->end,
- this->writable ? "GRANTED" : "DENIED");
-
- return this->writable;
- }
-
- template <typename Type, typename ValueType>
- bool try_set (const Type *obj, const ValueType &v)
- {
- if (this->may_edit (obj, hb_static_size (Type)))
- {
- * const_cast<Type *> (obj) = v;
- return true;
- }
- return false;
- }
-
- template <typename Type>
- hb_blob_t *sanitize_blob (hb_blob_t *blob)
- {
- bool sane;
-
- init (blob);
-
- retry:
- DEBUG_MSG_FUNC (SANITIZE, start, "start");
-
- start_processing ();
-
- if (unlikely (!start))
- {
- end_processing ();
- return blob;
- }
-
- Type *t = reinterpret_cast<Type *> (const_cast<char *> (start));
-
- sane = t->sanitize (this);
- if (sane)
- {
- if (edit_count)
- {
- DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %u edits; going for second round", edit_count);
-
- /* sanitize again to ensure no toe-stepping */
- edit_count = 0;
- sane = t->sanitize (this);
- if (edit_count) {
- DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILLING", edit_count);
- sane = false;
- }
- }
- }
- else
- {
- if (edit_count && !writable) {
- start = hb_blob_get_data_writable (blob, nullptr);
- end = start + blob->length;
-
- if (start)
- {
- writable = true;
- /* ok, we made it writable by relocating. try again */
- DEBUG_MSG_FUNC (SANITIZE, start, "retry");
- goto retry;
- }
- }
- }
-
- end_processing ();
-
- DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
- if (sane)
- {
- hb_blob_make_immutable (blob);
- return blob;
- }
- else
- {
- hb_blob_destroy (blob);
- return hb_blob_get_empty ();
- }
- }
-
- template <typename Type>
- hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
- {
- if (!num_glyphs_set)
- set_num_glyphs (hb_face_get_glyph_count (face));
- return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
- }
-
- const char *start, *end;
- mutable int max_ops, max_subtables;
- private:
- int recursion_depth;
- bool writable;
- unsigned int edit_count;
- hb_blob_t *blob;
- unsigned int num_glyphs;
- bool num_glyphs_set;
-};
-
-struct hb_sanitize_with_object_t
-{
- template <typename T>
- hb_sanitize_with_object_t (hb_sanitize_context_t *c, const T& obj) : c (c)
- { c->set_object (obj); }
- ~hb_sanitize_with_object_t ()
- { c->reset_object (); }
-
- private:
- hb_sanitize_context_t *c;
-};
-
-
-#endif /* HB_SANITIZE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh
deleted file mode 100644
index 61ec0253a0e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2012,2018 Google, Inc.
- * Copyright © 2019 Facebook, 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
- * Google Author(s): Behdad Esfahbod
- * Facebook Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_SERIALIZE_HH
-#define HB_SERIALIZE_HH
-
-#include "hb.hh"
-#include "hb-blob.hh"
-#include "hb-map.hh"
-#include "hb-pool.hh"
-
-#ifdef HB_EXPERIMENTAL_API
-#include "hb-subset-repacker.h"
-#endif
-
-/*
- * Serialize
- */
-
-enum hb_serialize_error_t {
- HB_SERIALIZE_ERROR_NONE = 0x00000000u,
- HB_SERIALIZE_ERROR_OTHER = 0x00000001u,
- HB_SERIALIZE_ERROR_OFFSET_OVERFLOW = 0x00000002u,
- HB_SERIALIZE_ERROR_OUT_OF_ROOM = 0x00000004u,
- HB_SERIALIZE_ERROR_INT_OVERFLOW = 0x00000008u,
- HB_SERIALIZE_ERROR_ARRAY_OVERFLOW = 0x00000010u
-};
-HB_MARK_AS_FLAG_T (hb_serialize_error_t);
-
-struct hb_serialize_context_t
-{
- typedef unsigned objidx_t;
-
- enum whence_t {
- Head, /* Relative to the current object head (default). */
- Tail, /* Relative to the current object tail after packed. */
- Absolute /* Absolute: from the start of the serialize buffer. */
- };
-
-
-
- struct object_t
- {
- void fini () {
- real_links.fini ();
- virtual_links.fini ();
- }
-
- object_t () = default;
-
-#ifdef HB_EXPERIMENTAL_API
- object_t (const hb_object_t &o)
- {
- head = o.head;
- tail = o.tail;
- next = nullptr;
- real_links.alloc (o.num_real_links, true);
- for (unsigned i = 0 ; i < o.num_real_links; i++)
- real_links.push (o.real_links[i]);
-
- virtual_links.alloc (o.num_virtual_links, true);
- for (unsigned i = 0; i < o.num_virtual_links; i++)
- virtual_links.push (o.virtual_links[i]);
- }
-#endif
-
- friend void swap (object_t& a, object_t& b)
- {
- hb_swap (a.head, b.head);
- hb_swap (a.tail, b.tail);
- hb_swap (a.next, b.next);
- hb_swap (a.real_links, b.real_links);
- hb_swap (a.virtual_links, b.virtual_links);
- }
-
- bool operator == (const object_t &o) const
- {
- // Virtual links aren't considered for equality since they don't affect the functionality
- // of the object.
- return (tail - head == o.tail - o.head)
- && (real_links.length == o.real_links.length)
- && 0 == hb_memcmp (head, o.head, tail - head)
- && real_links.as_bytes () == o.real_links.as_bytes ();
- }
- uint32_t hash () const
- {
- // Virtual links aren't considered for equality since they don't affect the functionality
- // of the object.
- return hb_bytes_t (head, tail - head).hash () ^
- real_links.as_bytes ().hash ();
- }
-
- struct link_t
- {
- unsigned width: 3;
- unsigned is_signed: 1;
- unsigned whence: 2;
- unsigned bias : 26;
- unsigned position;
- objidx_t objidx;
-
- link_t () = default;
-
-#ifdef HB_EXPERIMENTAL_API
- link_t (const hb_link_t &o)
- {
- width = o.width;
- is_signed = 0;
- whence = 0;
- position = o.position;
- bias = 0;
- objidx = o.objidx;
- }
-#endif
-
- HB_INTERNAL static int cmp (const void* a, const void* b)
- {
- int cmp = ((const link_t*)a)->position - ((const link_t*)b)->position;
- if (cmp) return cmp;
-
- return ((const link_t*)a)->objidx - ((const link_t*)b)->objidx;
- }
- };
-
- char *head;
- char *tail;
- hb_vector_t<link_t> real_links;
- hb_vector_t<link_t> virtual_links;
- object_t *next;
-
- auto all_links () const HB_AUTO_RETURN
- (( hb_concat (this->real_links, this->virtual_links) ));
- auto all_links_writer () HB_AUTO_RETURN
- (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) ));
- };
-
- struct snapshot_t
- {
- char *head;
- char *tail;
- object_t *current; // Just for sanity check
- unsigned num_real_links;
- unsigned num_virtual_links;
- hb_serialize_error_t errors;
- };
-
- snapshot_t snapshot ()
- { return snapshot_t {
- head, tail, current, current->real_links.length, current->virtual_links.length, errors }; }
-
- hb_serialize_context_t (void *start_, unsigned int size) :
- start ((char *) start_),
- end (start + size),
- current (nullptr)
- { reset (); }
- ~hb_serialize_context_t () { fini (); }
-
- void fini ()
- {
- for (object_t *_ : ++hb_iter (packed)) _->fini ();
- packed.fini ();
- this->packed_map.fini ();
-
- while (current)
- {
- auto *_ = current;
- current = current->next;
- _->fini ();
- }
- }
-
- bool in_error () const { return bool (errors); }
-
- bool successful () const { return !bool (errors); }
-
- HB_NODISCARD bool ran_out_of_room () const { return errors & HB_SERIALIZE_ERROR_OUT_OF_ROOM; }
- HB_NODISCARD bool offset_overflow () const { return errors & HB_SERIALIZE_ERROR_OFFSET_OVERFLOW; }
- HB_NODISCARD bool only_offset_overflow () const { return errors == HB_SERIALIZE_ERROR_OFFSET_OVERFLOW; }
- HB_NODISCARD bool only_overflow () const
- {
- return errors == HB_SERIALIZE_ERROR_OFFSET_OVERFLOW
- || errors == HB_SERIALIZE_ERROR_INT_OVERFLOW
- || errors == HB_SERIALIZE_ERROR_ARRAY_OVERFLOW;
- }
-
- void reset (void *start_, unsigned int size)
- {
- start = (char*) start_;
- end = start + size;
- reset ();
- current = nullptr;
- }
-
- void reset ()
- {
- this->errors = HB_SERIALIZE_ERROR_NONE;
- this->head = this->start;
- this->tail = this->end;
- this->zerocopy = nullptr;
- this->debug_depth = 0;
-
- fini ();
- this->packed.push (nullptr);
- this->packed_map.init ();
- }
-
- bool check_success (bool success,
- hb_serialize_error_t err_type = HB_SERIALIZE_ERROR_OTHER)
- {
- return successful ()
- && (success || err (err_type));
- }
-
- template <typename T1, typename T2>
- bool check_equal (T1 &&v1, T2 &&v2, hb_serialize_error_t err_type)
- {
- if ((long long) v1 != (long long) v2)
- {
- return err (err_type);
- }
- return true;
- }
-
- template <typename T1, typename T2>
- bool check_assign (T1 &v1, T2 &&v2, hb_serialize_error_t err_type)
- { return check_equal (v1 = v2, v2, err_type); }
-
- template <typename T> bool propagate_error (T &&obj)
- { return check_success (!hb_deref (obj).in_error ()); }
-
- template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os)
- { return propagate_error (std::forward<T1> (o1)) &&
- propagate_error (std::forward<Ts> (os)...); }
-
- /* To be called around main operation. */
- template <typename Type>
- Type *start_serialize ()
- {
- DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
- "start [%p..%p] (%lu bytes)",
- this->start, this->end,
- (unsigned long) (this->end - this->start));
-
- assert (!current);
- return push<Type> ();
- }
- void end_serialize ()
- {
- DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
- "end [%p..%p] serialized %u bytes; %s",
- this->start, this->end,
- (unsigned) (this->head - this->start),
- successful () ? "successful" : "UNSUCCESSFUL");
-
- propagate_error (packed, packed_map);
-
- if (unlikely (!current)) return;
- if (unlikely (in_error()))
- {
- // Offset overflows that occur before link resolution cannot be handled
- // by repacking, so set a more general error.
- if (offset_overflow ()) err (HB_SERIALIZE_ERROR_OTHER);
- return;
- }
-
- assert (!current->next);
-
- /* Only "pack" if there exist other objects... Otherwise, don't bother.
- * Saves a move. */
- if (packed.length <= 1)
- return;
-
- pop_pack (false);
-
- resolve_links ();
- }
-
- template <typename Type = void>
- Type *push ()
- {
- if (unlikely (in_error ())) return start_embed<Type> ();
-
- object_t *obj = object_pool.alloc ();
- if (unlikely (!obj))
- check_success (false);
- else
- {
- obj->head = head;
- obj->tail = tail;
- obj->next = current;
- current = obj;
- }
- return start_embed<Type> ();
- }
- void pop_discard ()
- {
- object_t *obj = current;
- if (unlikely (!obj)) return;
- if (unlikely (in_error() && !only_overflow ())) return;
-
- current = current->next;
- revert (zerocopy ? zerocopy : obj->head, obj->tail);
- zerocopy = nullptr;
- obj->fini ();
- object_pool.release (obj);
- }
-
- /* Set share to false when an object is unlikely shareable with others
- * so not worth an attempt, or a contiguous table is serialized as
- * multiple consecutive objects in the reverse order so can't be shared.
- */
- objidx_t pop_pack (bool share=true)
- {
- object_t *obj = current;
- if (unlikely (!obj)) return 0;
- if (unlikely (in_error())) return 0;
-
- current = current->next;
- obj->tail = head;
- obj->next = nullptr;
- assert (obj->head <= obj->tail);
- unsigned len = obj->tail - obj->head;
- head = zerocopy ? zerocopy : obj->head; /* Rewind head. */
- bool was_zerocopy = zerocopy;
- zerocopy = nullptr;
-
- if (!len)
- {
- assert (!obj->real_links.length);
- assert (!obj->virtual_links.length);
- return 0;
- }
-
- objidx_t objidx;
- uint32_t hash = 0;
- if (share)
- {
- hash = hb_hash (obj);
- objidx = packed_map.get_with_hash (obj, hash);
- if (objidx)
- {
- merge_virtual_links (obj, objidx);
- obj->fini ();
- return objidx;
- }
- }
-
- tail -= len;
- if (was_zerocopy)
- assert (tail == obj->head);
- else
- memmove (tail, obj->head, len);
-
- obj->head = tail;
- obj->tail = tail + len;
-
- packed.push (obj);
-
- if (unlikely (!propagate_error (packed)))
- {
- /* Obj wasn't successfully added to packed, so clean it up otherwise its
- * links will be leaked. When we use constructor/destructors properly, we
- * can remove these. */
- obj->fini ();
- return 0;
- }
-
- objidx = packed.length - 1;
-
- if (share) packed_map.set_with_hash (obj, hash, objidx);
- propagate_error (packed_map);
-
- return objidx;
- }
-
- void revert (snapshot_t snap)
- {
- // Overflows that happened after the snapshot will be erased by the revert.
- if (unlikely (in_error () && !only_overflow ())) return;
- assert (snap.current == current);
- current->real_links.shrink (snap.num_real_links);
- current->virtual_links.shrink (snap.num_virtual_links);
- errors = snap.errors;
- revert (snap.head, snap.tail);
- }
-
- void revert (char *snap_head,
- char *snap_tail)
- {
- if (unlikely (in_error ())) return;
- assert (snap_head <= head);
- assert (tail <= snap_tail);
- head = snap_head;
- tail = snap_tail;
- discard_stale_objects ();
- }
-
- void discard_stale_objects ()
- {
- if (unlikely (in_error ())) return;
- while (packed.length > 1 &&
- packed.tail ()->head < tail)
- {
- packed_map.del (packed.tail ());
- assert (!packed.tail ()->next);
- packed.tail ()->fini ();
- packed.pop ();
- }
- if (packed.length > 1)
- assert (packed.tail ()->head == tail);
- }
-
- // Adds a virtual link from the current object to objidx. A virtual link is not associated with
- // an actual offset field. They are solely used to enforce ordering constraints between objects.
- // Adding a virtual link from object a to object b will ensure that object b is always packed after
- // object a in the final serialized order.
- //
- // This is useful in certain situations where there needs to be a specific ordering in the
- // final serialization. Such as when platform bugs require certain orderings, or to provide
- // guidance to the repacker for better offset overflow resolution.
- void add_virtual_link (objidx_t objidx)
- {
- if (unlikely (in_error ())) return;
-
- if (!objidx)
- return;
-
- assert (current);
-
- auto& link = *current->virtual_links.push ();
- if (current->virtual_links.in_error ())
- err (HB_SERIALIZE_ERROR_OTHER);
-
- link.width = 0;
- link.objidx = objidx;
- link.is_signed = 0;
- link.whence = 0;
- link.position = 0;
- link.bias = 0;
- }
-
- template <typename T>
- void add_link (T &ofs, objidx_t objidx,
- whence_t whence = Head,
- unsigned bias = 0)
- {
- if (unlikely (in_error ())) return;
-
- if (!objidx)
- return;
-
- assert (current);
- assert (current->head <= (const char *) &ofs);
-
- auto& link = *current->real_links.push ();
- if (current->real_links.in_error ())
- err (HB_SERIALIZE_ERROR_OTHER);
-
- link.width = sizeof (T);
- link.objidx = objidx;
- if (unlikely (!sizeof (T)))
- {
- // This link is not associated with an actual offset and exists merely to enforce
- // an ordering constraint.
- link.is_signed = 0;
- link.whence = 0;
- link.position = 0;
- link.bias = 0;
- return;
- }
-
- link.is_signed = std::is_signed<hb_unwrap_type (T)>::value;
- link.whence = (unsigned) whence;
- link.position = (const char *) &ofs - current->head;
- link.bias = bias;
- }
-
- unsigned to_bias (const void *base) const
- {
- if (unlikely (in_error ())) return 0;
- if (!base) return 0;
- assert (current);
- assert (current->head <= (const char *) base);
- return (const char *) base - current->head;
- }
-
- void resolve_links ()
- {
- if (unlikely (in_error ())) return;
-
- assert (!current);
- assert (packed.length > 1);
-
- for (const object_t* parent : ++hb_iter (packed))
- for (const object_t::link_t &link : parent->real_links)
- {
- const object_t* child = packed[link.objidx];
- if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
- unsigned offset = 0;
- switch ((whence_t) link.whence) {
- case Head: offset = child->head - parent->head; break;
- case Tail: offset = child->head - parent->tail; break;
- case Absolute: offset = (head - start) + (child->head - tail); break;
- }
-
- assert (offset >= link.bias);
- offset -= link.bias;
- if (link.is_signed)
- {
- assert (link.width == 2 || link.width == 4);
- if (link.width == 4)
- assign_offset<int32_t> (parent, link, offset);
- else
- assign_offset<int16_t> (parent, link, offset);
- }
- else
- {
- assert (link.width == 2 || link.width == 3 || link.width == 4);
- if (link.width == 4)
- assign_offset<uint32_t> (parent, link, offset);
- else if (link.width == 3)
- assign_offset<uint32_t, 3> (parent, link, offset);
- else
- assign_offset<uint16_t> (parent, link, offset);
- }
- }
- }
-
- unsigned int length () const
- {
- if (unlikely (!current)) return 0;
- return this->head - current->head;
- }
-
- void align (unsigned int alignment)
- {
- unsigned int l = length () % alignment;
- if (l)
- allocate_size<void> (alignment - l);
- }
-
- template <typename Type = void>
- Type *start_embed (const Type *obj HB_UNUSED = nullptr) const
- { return reinterpret_cast<Type *> (this->head); }
- template <typename Type>
- Type *start_embed (const Type &obj) const
- { return start_embed (std::addressof (obj)); }
-
- bool err (hb_serialize_error_t err_type)
- {
- return !bool ((errors = (errors | err_type)));
- }
-
- bool start_zerocopy (size_t size)
- {
- if (unlikely (in_error ())) return false;
-
- if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size)))
- {
- err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
- return false;
- }
-
- assert (!this->zerocopy);
- this->zerocopy = this->head;
-
- assert (this->current->head == this->head);
- this->current->head = this->current->tail = this->head = this->tail - size;
- return true;
- }
-
- template <typename Type>
- Type *allocate_size (size_t size, bool clear = true)
- {
- if (unlikely (in_error ())) return nullptr;
-
- if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size)))
- {
- err (HB_SERIALIZE_ERROR_OUT_OF_ROOM);
- return nullptr;
- }
- if (clear)
- hb_memset (this->head, 0, size);
- char *ret = this->head;
- this->head += size;
- return reinterpret_cast<Type *> (ret);
- }
-
- template <typename Type>
- Type *allocate_min ()
- { return this->allocate_size<Type> (Type::min_size); }
-
- template <typename Type>
- Type *embed (const Type *obj)
- {
- unsigned int size = obj->get_size ();
- Type *ret = this->allocate_size<Type> (size, false);
- if (unlikely (!ret)) return nullptr;
- hb_memcpy (ret, obj, size);
- return ret;
- }
- template <typename Type>
- Type *embed (const Type &obj)
- { return embed (std::addressof (obj)); }
- char *embed (const char *obj, unsigned size)
- {
- char *ret = this->allocate_size<char> (size, false);
- if (unlikely (!ret)) return nullptr;
- hb_memcpy (ret, obj, size);
- return ret;
- }
-
- template <typename Type, typename ...Ts> auto
- _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
- (Type *, src.copy (this, std::forward<Ts> (ds)...))
-
- template <typename Type> auto
- _copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src))
- {
- Type *ret = this->allocate_size<Type> (sizeof (Type));
- if (unlikely (!ret)) return nullptr;
- *ret = src;
- return ret;
- }
-
- /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
- * instead of hb_memcpy(). */
- template <typename Type, typename ...Ts>
- Type *copy (const Type &src, Ts&&... ds)
- { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); }
- template <typename Type, typename ...Ts>
- Type *copy (const Type *src, Ts&&... ds)
- { return copy (*src, std::forward<Ts> (ds)...); }
-
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator)),
- typename ...Ts>
- void copy_all (Iterator it, Ts&&... ds)
- { for (decltype (*it) _ : it) copy (_, std::forward<Ts> (ds)...); }
-
- template <typename Type>
- hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
-
- template <typename Type>
- Type *extend_size (Type *obj, size_t size, bool clear = true)
- {
- if (unlikely (in_error ())) return nullptr;
-
- assert (this->start <= (char *) obj);
- assert ((char *) obj <= this->head);
- assert ((size_t) (this->head - (char *) obj) <= size);
- if (unlikely (((char *) obj + size < (char *) obj) ||
- !this->allocate_size<Type> (((char *) obj) + size - this->head, clear))) return nullptr;
- return reinterpret_cast<Type *> (obj);
- }
- template <typename Type>
- Type *extend_size (Type &obj, size_t size, bool clear = true)
- { return extend_size (std::addressof (obj), size, clear); }
-
- template <typename Type>
- Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
- template <typename Type>
- Type *extend_min (Type &obj) { return extend_min (std::addressof (obj)); }
-
- template <typename Type, typename ...Ts>
- Type *extend (Type *obj, Ts&&... ds)
- { return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
- template <typename Type, typename ...Ts>
- Type *extend (Type &obj, Ts&&... ds)
- { return extend (std::addressof (obj), std::forward<Ts> (ds)...); }
-
- /* Output routines. */
- hb_bytes_t copy_bytes () const
- {
- assert (successful ());
- /* Copy both items from head side and tail side... */
- unsigned int len = (this->head - this->start)
- + (this->end - this->tail);
-
- // If len is zero don't hb_malloc as the memory won't get properly
- // cleaned up later.
- if (!len) return hb_bytes_t ();
-
- char *p = (char *) hb_malloc (len);
- if (unlikely (!p)) return hb_bytes_t ();
-
- hb_memcpy (p, this->start, this->head - this->start);
- hb_memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
- return hb_bytes_t (p, len);
- }
- template <typename Type>
- Type *copy () const
- { return reinterpret_cast<Type *> ((char *) copy_bytes ().arrayZ); }
- hb_blob_t *copy_blob () const
- {
- hb_bytes_t b = copy_bytes ();
- return hb_blob_create (b.arrayZ, b.length,
- HB_MEMORY_MODE_WRITABLE,
- (char *) b.arrayZ, hb_free);
- }
-
- const hb_vector_t<object_t *>& object_graph() const
- { return packed; }
-
- private:
- template <typename T, unsigned Size = sizeof (T)>
- void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset)
- {
- auto &off = * ((BEInt<T, Size> *) (parent->head + link.position));
- assert (0 == off);
- check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
- }
-
- public:
- char *start, *head, *tail, *end, *zerocopy;
- unsigned int debug_depth;
- hb_serialize_error_t errors;
-
- private:
-
- void merge_virtual_links (const object_t* from, objidx_t to_idx) {
- object_t* to = packed[to_idx];
- for (const auto& l : from->virtual_links) {
- to->virtual_links.push (l);
- }
- }
-
- /* Object memory pool. */
- hb_pool_t<object_t> object_pool;
-
- /* Stack of currently under construction objects. */
- object_t *current;
-
- /* Stack of packed objects. Object 0 is always nil object. */
- hb_vector_t<object_t *> packed;
-
- /* Map view of packed objects. */
- hb_hashmap_t<const object_t *, objidx_t> packed_map;
-};
-
-#endif /* HB_SERIALIZE_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 00000000000..e099a826414
--- /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-digest.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh
deleted file mode 100644
index e8409111f2d..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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_HH
-#define HB_SET_DIGEST_HH
-
-#include "hb.hh"
-#include "hb-machinery.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 way these are used is that the filter is first populated by
- * a lookup's or subtable's Coverage table(s), and then when we
- * want to apply the lookup or subtable to a glyph, before trying
- * to apply, we ask the filter if the glyph may be covered. If it's
- * not, we return early.
- *
- * We use these filters both at the lookup-level, and then again,
- * at the subtable-level. Both have performance win.
- *
- * The main filter we use is a combination of three bits-pattern
- * filters. A bits-pattern filter checks a number of bits (5 or 6)
- * of the input number (glyph-id in this case) and checks whether
- * its pattern is amongst the patterns of any of the accepted values.
- * The accepted patterns are represented as a "long" integer. The
- * check is done using four bitwise operations only.
- */
-
-template <typename mask_t, unsigned int shift>
-struct hb_set_digest_bits_pattern_t
-{
- static constexpr unsigned mask_bytes = sizeof (mask_t);
- static constexpr unsigned mask_bits = sizeof (mask_t) * 8;
- static constexpr unsigned 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), "");
-
- void init () { mask = 0; }
-
- void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
-
- void add (hb_codepoint_t g) { mask |= mask_for (g); }
-
- 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>
- 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 = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
- }
- }
- template <typename T>
- void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
- template <typename T>
- bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- {
- add_array (array, count, stride);
- return true;
- }
- template <typename T>
- bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
-
- bool may_have (const hb_set_digest_bits_pattern_t &o) const
- { return mask & o.mask; }
-
- bool may_have (hb_codepoint_t g) const
- { return mask & mask_for (g); }
-
- private:
-
- static 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
-{
- void init ()
- {
- head.init ();
- tail.init ();
- }
-
- void add (const hb_set_digest_combiner_t &o)
- {
- head.add (o.head);
- tail.add (o.tail);
- }
-
- void add (hb_codepoint_t g)
- {
- head.add (g);
- tail.add (g);
- }
-
- bool add_range (hb_codepoint_t a, hb_codepoint_t b)
- {
- return head.add_range (a, b) &&
- tail.add_range (a, b);
- }
- template <typename T>
- 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>
- void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
- template <typename T>
- bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- {
- return head.add_sorted_array (array, count, stride) &&
- tail.add_sorted_array (array, count, stride);
- }
- template <typename T>
- bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
-
- bool may_have (const hb_set_digest_combiner_t &o) const
- {
- return head.may_have (o.head) && tail.may_have (o.tail);
- }
-
- 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.
- */
-using hb_set_digest_t =
- hb_set_digest_combiner_t
- <
- hb_set_digest_bits_pattern_t<unsigned long, 4>,
- hb_set_digest_combiner_t
- <
- hb_set_digest_bits_pattern_t<unsigned long, 0>,
- hb_set_digest_bits_pattern_t<unsigned long, 9>
- >
- >
-;
-
-
-#endif /* HB_SET_DIGEST_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
new file mode 100644
index 00000000000..9c6f3ee37aa
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
@@ -0,0 +1,577 @@
+/*
+ * Copyright © 2012,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_SET_PRIVATE_HH
+#define HB_SET_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+
+
+/*
+ * hb_set_t
+ */
+
+/* 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? */
+
+struct hb_set_t
+{
+ struct page_map_t
+ {
+ inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; }
+
+ uint32_t major;
+ uint32_t index;
+ };
+
+ struct page_t
+ {
+ inline void init0 (void) { memset (&v, 0, sizeof (v)); }
+ inline void init1 (void) { memset (&v, 0xff, sizeof (v)); }
+
+ inline unsigned int len (void) const
+ { return ARRAY_LENGTH_CONST (v); }
+
+ 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) { 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)
+ {
+ 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 is_equal (const page_t *other) const
+ {
+ return 0 == memcmp (&v, &other->v, sizeof (v));
+ }
+
+ 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;
+
+ 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;
+
+#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;
+
+ 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, "");
+
+ 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)
+ {
+ page_map.init ();
+ pages.init ();
+ }
+ 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;
+ page_map.resize (0);
+ pages.resize (0);
+ }
+ inline bool is_empty (void) const {
+ 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;
+ page_t *page = page_for_insert (g); if (unlikely (!page)) return;
+ page->add (g);
+ }
+ 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;
+ 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;
+ 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;
+ for (unsigned int i = a; i < b + 1; i++)
+ del (i);
+ }
+ inline bool has (hb_codepoint_t g) const
+ {
+ 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
+ {
+ 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
+ {
+ 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;
+ }
+
+ template <class Op>
+ inline void process (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+
+ 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)
+ {
+ process<HbOpOr> (other);
+ }
+ inline void intersect (const hb_set_t *other)
+ {
+ process<HbOpAnd> (other);
+ }
+ inline void subtract (const hb_set_t *other)
+ {
+ process<HbOpMinus> (other);
+ }
+ inline void symmetric_difference (const hb_set_t *other)
+ {
+ process<HbOpXor> (other);
+ }
+ inline bool next (hb_codepoint_t *codepoint) const
+ {
+ if (unlikely (*codepoint == INVALID)) {
+ *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 (; 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;
+ }
+ inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
+ {
+ hb_codepoint_t i;
+
+ i = *last;
+ if (!next (&i))
+ {
+ *last = *first = INVALID;
+ return false;
+ }
+
+ *last = *first = i;
+ while (next (&i) && i == *last + 1)
+ (*last)++;
+
+ return true;
+ }
+
+ inline unsigned int get_population (void) const
+ {
+ 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
+ {
+ 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
+ {
+ 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;
+ }
+
+ static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
+
+ inline page_t *page_for_insert (hb_codepoint_t g)
+ {
+ page_map_t map = {get_major (g), pages.len};
+ unsigned int i;
+ if (!page_map.bfind (&map, &i))
+ {
+ 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;
+ }
+ return &pages[page_map[i].index];
+ }
+ inline page_t *page_for (hb_codepoint_t g)
+ {
+ 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 const page_t *page_for (hb_codepoint_t g) const
+ {
+ 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; }
+};
+
+
+#endif /* HB_SET_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
index 97caddb2262..0b4f871e852 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
@@ -24,63 +24,57 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-set.hh"
+#include "hb-set-private.hh"
-/**
- * SECTION:hb-set
- * @title: hb-set
- * @short_description: Objects representing a set of integers
- * @include: hb.h
- *
- * Set objects represent a mathematical set of integer values. They are
- * used in non-shaping APIs to query certain sets of characters or glyphs,
- * or other integer values.
- **/
+/* Public API */
/**
- * hb_set_create:
+ * hb_set_create: (Xconstructor)
*
- * Creates a new, initially empty set.
- *
- * Return value: (transfer full): The new #hb_set_t
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_set_t *
-hb_set_create ()
+hb_set_create (void)
{
hb_set_t *set;
if (!(set = hb_object_create<hb_set_t> ()))
return hb_set_get_empty ();
+ set->init ();
+
return set;
}
/**
* hb_set_get_empty:
*
- * Fetches the singleton empty #hb_set_t.
- *
- * Return value: (transfer full): The empty #hb_set_t
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_set_t *
-hb_set_get_empty ()
+hb_set_get_empty (void)
{
- return const_cast<hb_set_t *> (&Null (hb_set_t));
+ static const hb_set_t _hb_set_nil = {
+ HB_OBJECT_HEADER_STATIC,
+ true, /* in_error */
+
+ {0} /* elts */
+ };
+
+ return const_cast<hb_set_t *> (&_hb_set_nil);
}
/**
* hb_set_reference: (skip)
- * @set: A set
- *
- * Increases the reference count on a set.
+ * @set: a set.
*
- * Return value: (transfer full): The set
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -92,11 +86,7 @@ hb_set_reference (hb_set_t *set)
/**
* hb_set_destroy: (skip)
- * @set: A set
- *
- * Decreases the reference count on a set. When
- * the reference count reaches zero, the set is
- * destroyed, freeing all memory.
+ * @set: a set.
*
* Since: 0.9.2
**/
@@ -105,20 +95,20 @@ hb_set_destroy (hb_set_t *set)
{
if (!hb_object_destroy (set)) return;
- hb_free (set);
+ set->finish ();
+
+ free (set);
}
/**
* hb_set_set_user_data: (skip)
- * @set: A set
- * @key: The user-data key to set
- * @data: A pointer to the user data to set
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the specified set.
+ * @set: a set.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -134,18 +124,15 @@ hb_set_set_user_data (hb_set_t *set,
/**
* hb_set_get_user_data: (skip)
- * @set: A set
- * @key: The user-data key to query
- *
- * Fetches the user data associated with the specified key,
- * attached to the specified set.
+ * @set: a set.
+ * @key:
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_set_get_user_data (const hb_set_t *set,
+hb_set_get_user_data (hb_set_t *set,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (set, key);
@@ -154,53 +141,31 @@ hb_set_get_user_data (const hb_set_t *set,
/**
* hb_set_allocation_successful:
- * @set: A set
+ * @set: a set.
*
- * Tests whether memory allocation for a set was successful.
+ *
*
- * Return value: `true` if allocation succeeded, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
-hb_set_allocation_successful (const hb_set_t *set)
-{
- return !set->in_error ();
-}
-
-/**
- * hb_set_copy:
- * @set: A set
- *
- * Allocate a copy of @set.
- *
- * Return value: (transfer full): Newly-allocated set.
- *
- * Since: 2.8.2
- **/
-hb_set_t *
-hb_set_copy (const hb_set_t *set)
+hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
{
- hb_set_t *copy = hb_set_create ();
- if (unlikely (copy->in_error ()))
- return hb_set_get_empty ();
-
- copy->set (*set);
- return copy;
+ return !set->in_error;
}
/**
* hb_set_clear:
- * @set: A set
+ * @set: a set.
*
- * Clears out the contents of a set.
+ *
*
* Since: 0.9.2
**/
void
hb_set_clear (hb_set_t *set)
{
- /* Immutible-safe. */
set->clear ();
}
@@ -208,9 +173,9 @@ hb_set_clear (hb_set_t *set)
* hb_set_is_empty:
* @set: a set.
*
- * Tests whether a set is empty (contains no elements).
+ *
*
- * Return value: `true` if @set is empty
+ * Return value:
*
* Since: 0.9.7
**/
@@ -222,12 +187,12 @@ hb_set_is_empty (const hb_set_t *set)
/**
* hb_set_has:
- * @set: A set
- * @codepoint: The element to query
+ * @set: a set.
+ * @codepoint:
*
- * Tests whether @codepoint belongs to @set.
+ *
*
- * Return value: `true` if @codepoint is in @set, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -240,10 +205,10 @@ hb_set_has (const hb_set_t *set,
/**
* hb_set_add:
- * @set: A set
- * @codepoint: The element to add to @set
+ * @set: a set.
+ * @codepoint:
*
- * Adds @codepoint to @set.
+ *
*
* Since: 0.9.2
**/
@@ -251,41 +216,16 @@ void
hb_set_add (hb_set_t *set,
hb_codepoint_t codepoint)
{
- /* Immutible-safe. */
set->add (codepoint);
}
/**
- * hb_set_add_sorted_array:
- * @set: A set
- * @sorted_codepoints: (array length=num_codepoints): Array of codepoints to add
- * @num_codepoints: Length of @sorted_codepoints
- *
- * Adds @num_codepoints codepoints to a set at once.
- * The codepoints array must be in increasing order,
- * with size at least @num_codepoints.
- *
- * Since: 4.1.0
- */
-HB_EXTERN void
-hb_set_add_sorted_array (hb_set_t *set,
- const hb_codepoint_t *sorted_codepoints,
- unsigned int num_codepoints)
-{
- /* Immutible-safe. */
- set->add_sorted_array (sorted_codepoints,
- num_codepoints,
- sizeof(hb_codepoint_t));
-}
-
-/**
* hb_set_add_range:
- * @set: A set
- * @first: The first element to add to @set
- * @last: The final element to add to @set
+ * @set: a set.
+ * @first:
+ * @last:
*
- * Adds all of the elements from @first to @last
- * (inclusive) to @set.
+ *
*
* Since: 0.9.7
**/
@@ -294,16 +234,15 @@ hb_set_add_range (hb_set_t *set,
hb_codepoint_t first,
hb_codepoint_t last)
{
- /* Immutible-safe. */
set->add_range (first, last);
}
/**
* hb_set_del:
- * @set: A set
- * @codepoint: Removes @codepoint from @set
+ * @set: a set.
+ * @codepoint:
*
- * Removes @codepoint from @set.
+ *
*
* Since: 0.9.2
**/
@@ -311,21 +250,16 @@ void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint)
{
- /* Immutible-safe. */
set->del (codepoint);
}
/**
* hb_set_del_range:
- * @set: A set
- * @first: The first element to remove from @set
- * @last: The final element to remove from @set
- *
- * Removes all of the elements from @first to @last
- * (inclusive) from @set.
+ * @set: a set.
+ * @first:
+ * @last:
*
- * If @last is #HB_SET_VALUE_INVALID, then all values
- * greater than or equal to @first are removed.
+ *
*
* Since: 0.9.7
**/
@@ -334,19 +268,17 @@ hb_set_del_range (hb_set_t *set,
hb_codepoint_t first,
hb_codepoint_t last)
{
- /* Immutible-safe. */
set->del_range (first, last);
}
/**
* hb_set_is_equal:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Tests whether @set and @other are equal (contain the same
- * elements).
+ *
*
- * Return value: `true` if the two sets are equal, `false` otherwise.
+ * Return value:
*
* Since: 0.9.7
**/
@@ -354,50 +286,15 @@ hb_bool_t
hb_set_is_equal (const hb_set_t *set,
const hb_set_t *other)
{
- return set->is_equal (*other);
-}
-
-/**
- * hb_set_hash:
- * @set: A set
- *
- * Creates a hash representing @set.
- *
- * Return value:
- * A hash of @set.
- *
- * Since: 4.4.0
- **/
-HB_EXTERN unsigned int
-hb_set_hash (const hb_set_t *set)
-{
- return set->hash ();
-}
-
-/**
- * hb_set_is_subset:
- * @set: A set
- * @larger_set: Another set
- *
- * Tests whether @set is a subset of @larger_set.
- *
- * Return value: `true` if the @set is a subset of (or equal to) @larger_set, `false` otherwise.
- *
- * Since: 1.8.1
- **/
-hb_bool_t
-hb_set_is_subset (const hb_set_t *set,
- const hb_set_t *larger_set)
-{
- return set->is_subset (*larger_set);
+ return set->is_equal (other);
}
/**
* hb_set_set:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Makes the contents of @set equal to the contents of @other.
+ *
*
* Since: 0.9.2
**/
@@ -405,16 +302,15 @@ void
hb_set_set (hb_set_t *set,
const hb_set_t *other)
{
- /* Immutible-safe. */
- set->set (*other);
+ set->set (other);
}
/**
* hb_set_union:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Makes @set the union of @set and @other.
+ *
*
* Since: 0.9.2
**/
@@ -422,16 +318,15 @@ void
hb_set_union (hb_set_t *set,
const hb_set_t *other)
{
- /* Immutible-safe. */
- set->union_ (*other);
+ set->union_ (other);
}
/**
* hb_set_intersect:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Makes @set the intersection of @set and @other.
+ *
*
* Since: 0.9.2
**/
@@ -439,16 +334,15 @@ void
hb_set_intersect (hb_set_t *set,
const hb_set_t *other)
{
- /* Immutible-safe. */
- set->intersect (*other);
+ set->intersect (other);
}
/**
* hb_set_subtract:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Subtracts the contents of @other from @set.
+ *
*
* Since: 0.9.2
**/
@@ -456,17 +350,15 @@ void
hb_set_subtract (hb_set_t *set,
const hb_set_t *other)
{
- /* Immutible-safe. */
- set->subtract (*other);
+ set->subtract (other);
}
/**
* hb_set_symmetric_difference:
- * @set: A set
- * @other: Another set
+ * @set: a set.
+ * @other:
*
- * Makes @set the symmetric difference of @set
- * and @other.
+ *
*
* Since: 0.9.2
**/
@@ -474,48 +366,31 @@ void
hb_set_symmetric_difference (hb_set_t *set,
const hb_set_t *other)
{
- /* Immutible-safe. */
- set->symmetric_difference (*other);
+ set->symmetric_difference (other);
}
/**
* hb_set_invert:
- * @set: A set
+ * @set: a set.
*
- * Inverts the contents of @set.
+ *
*
- * Since: 3.0.0
+ * Since: 0.9.10
+ *
+ * Deprecated: 1.6.1
**/
void
hb_set_invert (hb_set_t *set)
{
- /* Immutible-safe. */
- set->invert ();
-}
-
-/**
- * hb_set_is_inverted:
- * @set: A set
- *
- * Returns whether the set is inverted.
- *
- * Return value: `true` if the set is inverted, `false` otherwise
- *
- * Since: 7.0.0
- **/
-hb_bool_t
-hb_set_is_inverted (const hb_set_t *set)
-{
- return set->is_inverted ();
}
/**
* hb_set_get_population:
- * @set: A set
+ * @set: a set.
*
- * Returns the number of elements in the set.
+ * Returns the number of numbers in the set.
*
- * Return value: The population of @set
+ * Return value: set population.
*
* Since: 0.9.7
**/
@@ -527,11 +402,11 @@ hb_set_get_population (const hb_set_t *set)
/**
* hb_set_get_min:
- * @set: A set
+ * @set: a set.
*
- * Finds the smallest element in the set.
+ * Finds the minimum number in the set.
*
- * Return value: minimum of @set, or #HB_SET_VALUE_INVALID if @set is empty.
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
*
* Since: 0.9.7
**/
@@ -543,11 +418,11 @@ hb_set_get_min (const hb_set_t *set)
/**
* hb_set_get_max:
- * @set: A set
+ * @set: a set.
*
- * Finds the largest element in the set.
+ * Finds the maximum number in the set.
*
- * Return value: maximum of @set, or #HB_SET_VALUE_INVALID if @set is empty.
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
*
* Since: 0.9.7
**/
@@ -559,15 +434,12 @@ hb_set_get_max (const hb_set_t *set)
/**
* hb_set_next:
- * @set: A set
- * @codepoint: (inout): Input = Code point to query
- * Output = Code point retrieved
- *
- * Fetches the next element in @set that is greater than current value of @codepoint.
+ * @set: a set.
+ * @codepoint: (inout):
*
- * Set @codepoint to #HB_SET_VALUE_INVALID to get started.
+ *
*
- * Return value: `true` if there was a next value, `false` otherwise
+ * Return value: whether there was a next value.
*
* Since: 0.9.2
**/
@@ -579,39 +451,15 @@ hb_set_next (const hb_set_t *set,
}
/**
- * hb_set_previous:
- * @set: A set
- * @codepoint: (inout): Input = Code point to query
- * Output = Code point retrieved
- *
- * Fetches the previous element in @set that is lower than current value of @codepoint.
- *
- * Set @codepoint to #HB_SET_VALUE_INVALID to get started.
- *
- * Return value: `true` if there was a previous value, `false` otherwise
- *
- * Since: 1.8.0
- **/
-hb_bool_t
-hb_set_previous (const hb_set_t *set,
- hb_codepoint_t *codepoint)
-{
- return set->previous (codepoint);
-}
-
-/**
* hb_set_next_range:
- * @set: A set
- * @first: (out): The first code point in the range
- * @last: (inout): Input = The current last code point in the range
- * Output = The last code point in the range
+ * @set: a set.
+ * @first: (out): output first codepoint in the range.
+ * @last: (inout): input current last and output last codepoint in the range.
*
- * Fetches the next consecutive range of elements in @set that
+ * Gets the next consecutive range of numbers in @set that
* are greater than current value of @last.
*
- * Set @last to #HB_SET_VALUE_INVALID to get started.
- *
- * Return value: `true` if there was a next range, `false` otherwise
+ * Return value: whether there was a next range.
*
* Since: 0.9.7
**/
@@ -622,52 +470,3 @@ hb_set_next_range (const hb_set_t *set,
{
return set->next_range (first, last);
}
-
-/**
- * hb_set_previous_range:
- * @set: A set
- * @first: (inout): Input = The current first code point in the range
- * Output = The first code point in the range
- * @last: (out): The last code point in the range
- *
- * Fetches the previous consecutive range of elements in @set that
- * are greater than current value of @last.
- *
- * Set @first to #HB_SET_VALUE_INVALID to get started.
- *
- * Return value: `true` if there was a previous range, `false` otherwise
- *
- * Since: 1.8.0
- **/
-hb_bool_t
-hb_set_previous_range (const hb_set_t *set,
- hb_codepoint_t *first,
- hb_codepoint_t *last)
-{
- return set->previous_range (first, last);
-}
-
-/**
- * hb_set_next_many:
- * @set: A set
- * @codepoint: Outputting codepoints starting after this one.
- * Use #HB_SET_VALUE_INVALID to get started.
- * @out: (array length=size): An array of codepoints to write to.
- * @size: The maximum number of codepoints to write out.
- *
- * Finds the next element in @set that is greater than @codepoint. Writes out
- * codepoints to @out, until either the set runs out of elements, or @size
- * codepoints are written, whichever comes first.
- *
- * Return value: the number of values written.
- *
- * Since: 4.2.0
- **/
-unsigned int
-hb_set_next_many (const hb_set_t *set,
- hb_codepoint_t codepoint,
- hb_codepoint_t *out,
- unsigned int size)
-{
- return set->next_many (codepoint, out, size);
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h
index de532310306..2ce406073ce 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -36,24 +36,11 @@
HB_BEGIN_DECLS
-/**
- * HB_SET_VALUE_INVALID:
- *
- * Unset #hb_set_t value.
- *
+/*
* Since: 0.9.21
*/
#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
-/**
- * hb_set_t:
- *
- * Data type for holding a set of integers. #hb_set_t's are
- * used to gather and contain glyph IDs, Unicode code
- * points, and various other collections of discrete
- * values.
- *
- **/
typedef struct hb_set_t hb_set_t;
@@ -77,7 +64,7 @@ hb_set_set_user_data (hb_set_t *set,
hb_bool_t replace);
HB_EXTERN void *
-hb_set_get_user_data (const hb_set_t *set,
+hb_set_get_user_data (hb_set_t *set,
hb_user_data_key_t *key);
@@ -85,25 +72,18 @@ hb_set_get_user_data (const hb_set_t *set,
HB_EXTERN hb_bool_t
hb_set_allocation_successful (const hb_set_t *set);
-HB_EXTERN hb_set_t *
-hb_set_copy (const hb_set_t *set);
-
HB_EXTERN void
hb_set_clear (hb_set_t *set);
HB_EXTERN hb_bool_t
hb_set_is_empty (const hb_set_t *set);
-HB_EXTERN void
-hb_set_invert (hb_set_t *set);
-
-HB_EXTERN hb_bool_t
-hb_set_is_inverted (const hb_set_t *set);
-
HB_EXTERN hb_bool_t
hb_set_has (const hb_set_t *set,
hb_codepoint_t codepoint);
+/* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1
+ * which we will use as a sentinel. */
HB_EXTERN void
hb_set_add (hb_set_t *set,
hb_codepoint_t codepoint);
@@ -114,11 +94,6 @@ hb_set_add_range (hb_set_t *set,
hb_codepoint_t last);
HB_EXTERN void
-hb_set_add_sorted_array (hb_set_t *set,
- const hb_codepoint_t *sorted_codepoints,
- unsigned int num_codepoints);
-
-HB_EXTERN void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint);
@@ -131,13 +106,6 @@ HB_EXTERN hb_bool_t
hb_set_is_equal (const hb_set_t *set,
const hb_set_t *other);
-HB_EXTERN unsigned int
-hb_set_hash (const hb_set_t *set);
-
-HB_EXTERN hb_bool_t
-hb_set_is_subset (const hb_set_t *set,
- const hb_set_t *larger_set);
-
HB_EXTERN void
hb_set_set (hb_set_t *set,
const hb_set_t *other);
@@ -161,42 +129,25 @@ hb_set_symmetric_difference (hb_set_t *set,
HB_EXTERN unsigned int
hb_set_get_population (const hb_set_t *set);
-/* Returns HB_SET_VALUE_INVALID if set empty. */
+/* Returns -1 if set empty. */
HB_EXTERN hb_codepoint_t
hb_set_get_min (const hb_set_t *set);
-/* Returns HB_SET_VALUE_INVALID if set empty. */
+/* Returns -1 if set empty. */
HB_EXTERN hb_codepoint_t
hb_set_get_max (const hb_set_t *set);
-/* Pass HB_SET_VALUE_INVALID in to get started. */
+/* Pass -1 in to get started. */
HB_EXTERN hb_bool_t
hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint);
-/* Pass HB_SET_VALUE_INVALID in to get started. */
-HB_EXTERN hb_bool_t
-hb_set_previous (const hb_set_t *set,
- hb_codepoint_t *codepoint);
-
-/* Pass HB_SET_VALUE_INVALID for first and last to get started. */
+/* Pass -1 for first and last to get started. */
HB_EXTERN hb_bool_t
hb_set_next_range (const hb_set_t *set,
hb_codepoint_t *first,
hb_codepoint_t *last);
-/* Pass HB_SET_VALUE_INVALID for first and last to get started. */
-HB_EXTERN hb_bool_t
-hb_set_previous_range (const hb_set_t *set,
- hb_codepoint_t *first,
- hb_codepoint_t *last);
-
-/* Pass HB_SET_VALUE_INVALID in to get started. */
-HB_EXTERN unsigned int
-hb_set_next_many (const hb_set_t *set,
- hb_codepoint_t codepoint,
- hb_codepoint_t *out,
- unsigned int size);
HB_END_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-set.hh
deleted file mode 100644
index 604802381b9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.hh
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright © 2012,2017 Google, Inc.
- * Copyright © 2021 Behdad Esfahbod
- *
- * 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_HH
-#define HB_SET_HH
-
-#include "hb.hh"
-#include "hb-bit-set-invertible.hh"
-
-
-template <typename impl_t>
-struct hb_sparseset_t
-{
- hb_object_header_t header;
- impl_t s;
-
- hb_sparseset_t () { init (); }
- ~hb_sparseset_t () { fini (); }
-
- hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); }
- hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); }
- hb_sparseset_t& operator = (const hb_sparseset_t& other) { set (other); return *this; }
- hb_sparseset_t& operator = (hb_sparseset_t&& other) { s = std::move (other.s); return *this; }
- friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); }
-
- hb_sparseset_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t ()
- {
- for (auto&& item : lst)
- add (item);
- }
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_sparseset_t (const Iterable &o) : hb_sparseset_t ()
- {
- hb_copy (o, *this);
- }
-
- void init ()
- {
- hb_object_init (this);
- s.init ();
- }
- void fini ()
- {
- hb_object_fini (this);
- s.fini ();
- }
-
- explicit operator bool () const { return !is_empty (); }
-
- void err () { s.err (); }
- bool in_error () const { return s.in_error (); }
-
- void alloc (unsigned sz) { s.alloc (sz); }
- void reset () { s.reset (); }
- void clear () { s.clear (); }
- void invert () { s.invert (); }
- bool is_inverted () const { return s.is_inverted (); }
- bool is_empty () const { return s.is_empty (); }
- uint32_t hash () const { return s.hash (); }
-
- void add (hb_codepoint_t g) { s.add (g); }
- bool add_range (hb_codepoint_t a, hb_codepoint_t b) { return s.add_range (a, b); }
-
- template <typename T>
- void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { s.add_array (array, count, stride); }
- template <typename T>
- void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
-
- /* Might return false if array looks unsorted.
- * Used for faster rejection of corrupt data. */
- template <typename T>
- bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
- { return s.add_sorted_array (array, count, stride); }
- template <typename T>
- bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
-
- void del (hb_codepoint_t g) { s.del (g); }
- void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); }
-
- bool get (hb_codepoint_t g) const { return s.get (g); }
-
- /* Has interface. */
- bool operator [] (hb_codepoint_t k) const { return get (k); }
- bool has (hb_codepoint_t k) const { return (*this)[k]; }
-
- /* Predicate. */
- bool operator () (hb_codepoint_t k) const { return has (k); }
-
- /* Sink interface. */
- hb_sparseset_t& operator << (hb_codepoint_t v)
- { add (v); return *this; }
- hb_sparseset_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
- { add_range (range.first, range.second); return *this; }
-
- bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
- { return s.intersects (first, last); }
-
- void set (const hb_sparseset_t &other) { s.set (other.s); }
-
- bool is_equal (const hb_sparseset_t &other) const { return s.is_equal (other.s); }
- bool operator == (const hb_set_t &other) const { return is_equal (other); }
- bool operator != (const hb_set_t &other) const { return !is_equal (other); }
-
- bool is_subset (const hb_sparseset_t &larger_set) const { return s.is_subset (larger_set.s); }
-
- void union_ (const hb_sparseset_t &other) { s.union_ (other.s); }
- void intersect (const hb_sparseset_t &other) { s.intersect (other.s); }
- void subtract (const hb_sparseset_t &other) { s.subtract (other.s); }
- void symmetric_difference (const hb_sparseset_t &other) { s.symmetric_difference (other.s); }
-
- bool next (hb_codepoint_t *codepoint) const { return s.next (codepoint); }
- bool previous (hb_codepoint_t *codepoint) const { return s.previous (codepoint); }
- bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- { return s.next_range (first, last); }
- bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const
- { return s.previous_range (first, last); }
- unsigned int next_many (hb_codepoint_t codepoint, hb_codepoint_t *out, unsigned int size) const
- { return s.next_many (codepoint, out, size); }
-
- unsigned int get_population () const { return s.get_population (); }
- hb_codepoint_t get_min () const { return s.get_min (); }
- hb_codepoint_t get_max () const { return s.get_max (); }
-
- static constexpr hb_codepoint_t INVALID = impl_t::INVALID;
-
- /*
- * Iterator implementation.
- */
- using iter_t = typename impl_t::iter_t;
- iter_t iter () const { return iter_t (this->s); }
- operator iter_t () const { return iter (); }
-};
-
-struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
-{
- using sparseset = hb_sparseset_t<hb_bit_set_invertible_t>;
-
- ~hb_set_t () = default;
- hb_set_t () : sparseset () {};
- hb_set_t (const hb_set_t &o) : sparseset ((sparseset &) o) {};
- hb_set_t (hb_set_t&& o) : sparseset (std::move ((sparseset &) o)) {}
- hb_set_t& operator = (const hb_set_t&) = default;
- hb_set_t& operator = (hb_set_t&&) = default;
- hb_set_t (std::initializer_list<hb_codepoint_t> lst) : sparseset (lst) {}
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_set_t (const Iterable &o) : sparseset (o) {}
-
- hb_set_t& operator << (hb_codepoint_t v)
- { sparseset::operator<< (v); return *this; }
- hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
- { sparseset::operator<< (range); return *this; }
-};
-
-static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, "");
-
-
-#endif /* HB_SET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
index 4f822c26e9f..aa0413a272d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
@@ -24,43 +24,44 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_OT_SHAPER_INDIC_HH
-#define HB_OT_SHAPER_INDIC_HH
+#ifndef HB_SHAPE_PLAN_PRIVATE_HH
+#define HB_SHAPE_PLAN_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
-#include "hb-ot-shaper-syllabic.hh"
+struct hb_shape_plan_t
+{
+ hb_object_header_t header;
+ ASSERT_POD ();
-/* Visual positions in a syllable from left to right. */
-enum ot_position_t {
- POS_START = 0,
+ hb_bool_t default_shaper_list;
+ hb_face_t *face_unsafe; /* We don't carry a reference to face. */
+ hb_segment_properties_t props;
- POS_RA_TO_BECOME_REPH = 1,
- POS_PRE_M = 2,
- POS_PRE_C = 3,
+ hb_shape_func_t *shaper_func;
+ const char *shaper_name;
- POS_BASE_C = 4,
- POS_AFTER_MAIN = 5,
+ hb_feature_t *user_features;
+ unsigned int num_user_features;
- POS_ABOVE_C = 6,
+ int *coords;
+ unsigned int num_coords;
- POS_BEFORE_SUB = 7,
- POS_BELOW_C = 8,
- POS_AFTER_SUB = 9,
-
- POS_BEFORE_POST = 10,
- POS_POST_C = 11,
- POS_AFTER_POST = 12,
-
- POS_SMVD = 13,
-
- POS_END = 14
+ struct hb_shaper_data_t shaper_data;
};
-
-HB_INTERNAL uint16_t
-hb_indic_get_categories (hb_codepoint_t u);
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
+ , const hb_feature_t *user_features \
+ , unsigned int num_user_features \
+ , const int *coords \
+ , unsigned int num_coords
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
-#endif /* HB_OT_SHAPER_INDIC_HH */
+#endif /* HB_SHAPE_PLAN_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
index 312eeb653e5..6eeba2b3d1f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
@@ -24,145 +24,64 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-#include "hb-shape-plan.hh"
-#include "hb-shaper.hh"
-#include "hb-font.hh"
-#include "hb-buffer.hh"
-
-
-#ifndef HB_NO_SHAPER
-
-/**
- * SECTION:hb-shape-plan
- * @title: hb-shape-plan
- * @short_description: Object representing a shaping plan
- * @include: hb.h
- *
- * Shape plans are an internal mechanism. Each plan contains state
- * describing how HarfBuzz will shape a particular text segment, based on
- * the combination of segment properties and the capabilities in the
- * font face in use.
- *
- * Shape plans are not used for shaping directly, but can be queried to
- * access certain information about how shaping will perform, given a set
- * of specific input parameters (script, language, direction, features,
- * etc.).
- *
- * Most client programs will not need to deal with shape plans directly.
- **/
-
-
-/*
- * hb_shape_plan_key_t
- */
-
-bool
-hb_shape_plan_key_t::init (bool copy,
- hb_face_t *face,
- const hb_segment_properties_t *props,
- const hb_feature_t *user_features,
- unsigned int num_user_features,
- const int *coords,
- unsigned int num_coords,
- const char * const *shaper_list)
+#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"
+
+
+static void
+hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const int *coords,
+ unsigned int num_coords,
+ const char * const *shaper_list)
{
- hb_feature_t *features = nullptr;
- if (copy && num_user_features && !(features = (hb_feature_t *) hb_calloc (num_user_features, sizeof (hb_feature_t))))
- goto bail;
-
- this->props = *props;
- this->num_user_features = num_user_features;
- this->user_features = copy ? features : user_features;
- if (copy && num_user_features)
- {
- hb_memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
- /* Make start/end uniform to easier catch bugs. */
- for (unsigned int i = 0; i < num_user_features; i++)
- {
- if (features[0].start != HB_FEATURE_GLOBAL_START)
- features[0].start = 1;
- if (features[0].end != HB_FEATURE_GLOBAL_END)
- features[0].end = 2;
- }
- }
- this->shaper_func = nullptr;
- this->shaper_name = nullptr;
-#ifndef HB_NO_OT_SHAPE
- this->ot.init (face, coords, num_coords);
-#endif
+ DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
+ "num_features=%d num_coords=%d shaper_list=%p",
+ num_user_features,
+ num_coords,
+ shaper_list);
- /*
- * Choose shaper.
- */
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
- if (face->data.shaper) \
- { \
- this->shaper_func = _hb_##shaper##_shape; \
- this->shaper_name = #shaper; \
- return true; \
+ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
+ HB_SHAPER_DATA (shaper, shape_plan) = \
+ HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \
+ user_features, num_user_features, \
+ coords, num_coords); \
+ shape_plan->shaper_func = _hb_##shaper##_shape; \
+ shape_plan->shaper_name = #shaper; \
+ return; \
} \
} HB_STMT_END
- if (unlikely (shaper_list))
- {
- for (; *shaper_list; shaper_list++)
- if (false)
+ if (likely (!shaper_list)) {
+ for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+ if (0)
;
#define HB_SHAPER_IMPLEMENT(shaper) \
- else if (0 == strcmp (*shaper_list, #shaper)) \
+ else if (shapers[i].func == _hb_##shaper##_shape) \
HB_SHAPER_PLAN (shaper);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
- }
- else
- {
- const HB_UNUSED hb_shaper_entry_t *shapers = _hb_shapers_get ();
- for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
- if (false)
+ } else {
+ for (; *shaper_list; shaper_list++)
+ if (0)
;
#define HB_SHAPER_IMPLEMENT(shaper) \
- else if (shapers[i].func == _hb_##shaper##_shape) \
+ else if (0 == strcmp (*shaper_list, #shaper)) \
HB_SHAPER_PLAN (shaper);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
}
-#undef HB_SHAPER_PLAN
-
-bail:
- ::hb_free (features);
- return false;
-}
-
-bool
-hb_shape_plan_key_t::user_features_match (const hb_shape_plan_key_t *other)
-{
- if (this->num_user_features != other->num_user_features)
- return false;
- for (unsigned int i = 0; i < num_user_features; i++)
- {
- if (this->user_features[i].tag != other->user_features[i].tag ||
- this->user_features[i].value != other->user_features[i].value ||
- (this->user_features[i].start == HB_FEATURE_GLOBAL_START &&
- this->user_features[i].end == HB_FEATURE_GLOBAL_END) !=
- (other->user_features[i].start == HB_FEATURE_GLOBAL_START &&
- other->user_features[i].end == HB_FEATURE_GLOBAL_END))
- return false;
- }
- return true;
-}
-bool
-hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
-{
- return hb_segment_properties_equal (&this->props, &other->props) &&
- this->user_features_match (other) &&
-#ifndef HB_NO_OT_SHAPE
- this->ot.equal (&other->ot) &&
-#endif
- this->shaper_func == other->shaper_func;
+#undef HB_SHAPER_PLAN
}
@@ -170,19 +89,17 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
* hb_shape_plan_t
*/
-
/**
- * hb_shape_plan_create:
- * @face: #hb_face_t to use
- * @props: The #hb_segment_properties_t of the segment
- * @user_features: (array length=num_user_features): The list of user-selected features
- * @num_user_features: The number of user-selected features
- * @shaper_list: (array zero-terminated=1): List of shapers to try
+ * hb_shape_plan_create: (Xconstructor)
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
*
- * Constructs a shaping plan for a combination of @face, @user_features, @props,
- * and @shaper_list.
+ *
*
- * Return value: (transfer full): The shaping plan
+ * Return value: (transfer full):
*
* Since: 0.9.7
**/
@@ -199,103 +116,112 @@ hb_shape_plan_create (hb_face_t *face,
shaper_list);
}
-/**
- * hb_shape_plan_create2:
- * @face: #hb_face_t to use
- * @props: The #hb_segment_properties_t of the segment
- * @user_features: (array length=num_user_features): The list of user-selected features
- * @num_user_features: The number of user-selected features
- * @coords: (array length=num_coords): The list of variation-space coordinates
- * @num_coords: The number of variation-space coordinates
- * @shaper_list: (array zero-terminated=1): List of shapers to try
- *
- * The variable-font version of #hb_shape_plan_create.
- * Constructs a shaping plan for a combination of @face, @user_features, @props,
- * and @shaper_list, plus the variation-space coordinates @coords.
- *
- * Return value: (transfer full): The shaping plan
- *
- * Since: 1.4.0
- **/
hb_shape_plan_t *
hb_shape_plan_create2 (hb_face_t *face,
const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features,
- const int *coords,
+ const int *orig_coords,
unsigned int num_coords,
const char * const *shaper_list)
{
DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,
- "face=%p num_features=%u num_coords=%u shaper_list=%p",
+ "face=%p num_features=%d num_coords=%d shaper_list=%p",
face,
num_user_features,
num_coords,
shaper_list);
- if (unlikely (props->direction == HB_DIRECTION_INVALID))
- return hb_shape_plan_get_empty ();
-
hb_shape_plan_t *shape_plan;
+ hb_feature_t *features = nullptr;
+ int *coords = nullptr;
+ if (unlikely (!face))
+ face = hb_face_get_empty ();
if (unlikely (!props))
- goto bail;
+ return hb_shape_plan_get_empty ();
+ if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
+ return hb_shape_plan_get_empty ();
+ if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
+ {
+ free (features);
+ return hb_shape_plan_get_empty ();
+ }
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
- goto bail;
+ {
+ free (coords);
+ free (features);
+ return hb_shape_plan_get_empty ();
+ }
+
+ assert (props->direction != HB_DIRECTION_INVALID);
- if (unlikely (!face))
- face = hb_face_get_empty ();
hb_face_make_immutable (face);
+ shape_plan->default_shaper_list = !shaper_list;
shape_plan->face_unsafe = face;
-
- if (unlikely (!shape_plan->key.init (true,
- face,
- props,
- user_features,
- num_user_features,
- coords,
- num_coords,
- shaper_list)))
- goto bail2;
-#ifndef HB_NO_OT_SHAPE
- if (unlikely (!shape_plan->ot.init0 (face, &shape_plan->key)))
- goto bail3;
-#endif
+ shape_plan->props = *props;
+ shape_plan->num_user_features = num_user_features;
+ shape_plan->user_features = features;
+ if (num_user_features)
+ memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
+ shape_plan->num_coords = num_coords;
+ shape_plan->coords = coords;
+ if (num_coords)
+ memcpy (coords, orig_coords, num_coords * sizeof (int));
+
+ hb_shape_plan_plan (shape_plan,
+ user_features, num_user_features,
+ coords, num_coords,
+ shaper_list);
return shape_plan;
-
-#ifndef HB_NO_OT_SHAPE
-bail3:
-#endif
- shape_plan->key.fini ();
-bail2:
- hb_free (shape_plan);
-bail:
- return hb_shape_plan_get_empty ();
}
/**
* hb_shape_plan_get_empty:
*
- * Fetches the singleton empty shaping plan.
+ *
*
- * Return value: (transfer full): The empty shaping plan
+ * Return value: (transfer full):
*
* Since: 0.9.7
**/
hb_shape_plan_t *
-hb_shape_plan_get_empty ()
+hb_shape_plan_get_empty (void)
{
- return const_cast<hb_shape_plan_t *> (&Null (hb_shape_plan_t));
+ static const hb_shape_plan_t _hb_shape_plan_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ true, /* default_shaper_list */
+ nullptr, /* face */
+ HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
+
+ nullptr, /* shaper_func */
+ nullptr, /* shaper_name */
+
+ nullptr, /* user_features */
+ 0, /* num_user_featurs */
+
+ nullptr, /* coords */
+ 0, /* num_coords */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
+ };
+
+ return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
}
/**
* hb_shape_plan_reference: (skip)
- * @shape_plan: A shaping plan
+ * @shape_plan: a shape plan.
*
- * Increases the reference count on the given shaping plan.
+ *
*
- * Return value: (transfer full): @shape_plan
+ * Return value: (transfer full):
*
* Since: 0.9.7
**/
@@ -307,11 +233,9 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
/**
* hb_shape_plan_destroy: (skip)
- * @shape_plan: A shaping plan
+ * @shape_plan: a shape plan.
*
- * Decreases the reference count on the given shaping plan. When the
- * reference count reaches zero, the shaping plan is destroyed,
- * freeing all memory.
+ *
*
* Since: 0.9.7
**/
@@ -320,20 +244,27 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
{
if (!hb_object_destroy (shape_plan)) return;
- hb_free (shape_plan);
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+ free (shape_plan->user_features);
+ free (shape_plan->coords);
+
+ free (shape_plan);
}
/**
* hb_shape_plan_set_user_data: (skip)
- * @shape_plan: A shaping plan
- * @key: The user-data key to set
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @shape_plan: a shape plan.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the given shaping plan.
+ *
*
- * Return value: `true` if success, `false` otherwise.
+ * Return value:
*
* Since: 0.9.7
**/
@@ -349,76 +280,73 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_get_user_data: (skip)
- * @shape_plan: A shaping plan
- * @key: The user-data key to query
+ * @shape_plan: a shape plan.
+ * @key:
*
- * Fetches the user data associated with the specified key,
- * attached to the specified shaping plan.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.7
**/
void *
-hb_shape_plan_get_user_data (const hb_shape_plan_t *shape_plan,
- hb_user_data_key_t *key)
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key)
{
return hb_object_get_user_data (shape_plan, key);
}
+
/**
- * hb_shape_plan_get_shaper:
- * @shape_plan: A shaping plan
+ * hb_shape_plan_execute:
+ * @shape_plan: a shape plan.
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
*
- * Fetches the shaper from a given shaping plan.
+ *
*
- * Return value: (transfer none): The shaper
+ * Return value:
*
* Since: 0.9.7
**/
-const char *
-hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
-{
- return shape_plan->key.shaper_name;
-}
-
-
-static bool
-_hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
{
DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
- "num_features=%u shaper_func=%p, shaper_name=%s",
+ "num_features=%d shaper_func=%p, shaper_name=%s",
num_features,
- shape_plan->key.shaper_func,
- shape_plan->key.shaper_name);
+ shape_plan->shaper_func,
+ shape_plan->shaper_name);
if (unlikely (!buffer->len))
return true;
- assert (!hb_object_is_immutable (buffer));
-
- buffer->assert_unicode ();
+ assert (!hb_object_is_inert (buffer));
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
- if (unlikely (!hb_object_is_valid (shape_plan)))
+ if (unlikely (hb_object_is_inert (shape_plan)))
return false;
assert (shape_plan->face_unsafe == font->face);
- assert (hb_segment_properties_equal (&shape_plan->key.props, &buffer->props));
+ assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
#define HB_SHAPER_EXECUTE(shaper) \
HB_STMT_START { \
- return font->data.shaper && \
+ return HB_SHAPER_DATA (shaper, shape_plan) && \
+ hb_##shaper##_shaper_font_data_ensure (font) && \
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
} HB_STMT_END
- if (false)
+ if (0)
;
#define HB_SHAPER_IMPLEMENT(shaper) \
- else if (shape_plan->key.shaper_func == _hb_##shaper##_shape) \
+ else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
HB_SHAPER_EXECUTE (shaper);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
@@ -427,54 +355,106 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
return false;
}
-/**
- * hb_shape_plan_execute:
- * @shape_plan: A shaping plan
- * @font: The #hb_font_t to use
- * @buffer: The #hb_buffer_t to work upon
- * @features: (array length=num_features): Features to enable
- * @num_features: The number of features to enable
- *
- * Executes the given shaping plan on the specified buffer, using
- * the given @font and @features.
- *
- * Return value: `true` if success, `false` otherwise.
- *
- * Since: 0.9.7
- **/
-hb_bool_t
-hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
+
+
+/*
+ * caching
+ */
+
+#if 0
+static unsigned int
+hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
{
- bool ret = _hb_shape_plan_execute_internal (shape_plan, font, buffer,
- features, num_features);
+ return hb_segment_properties_hash (&shape_plan->props) +
+ shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
+}
+#endif
- if (ret && buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE)
- buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+/* User-feature caching is currently somewhat dumb:
+ * it only finds matches where the feature array is identical,
+ * not cases where the feature lists would be compatible for plan purposes
+ * but have different ranges, for example.
+ */
+struct hb_shape_plan_proposal_t
+{
+ const hb_segment_properties_t props;
+ const char * const *shaper_list;
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
+ const int *coords;
+ unsigned int num_coords;
+ hb_shape_func_t *shaper_func;
+};
+
+static inline hb_bool_t
+hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ if (proposal->num_user_features != shape_plan->num_user_features)
+ return false;
+ for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
+ if (proposal->user_features[i].tag != shape_plan->user_features[i].tag ||
+ proposal->user_features[i].value != shape_plan->user_features[i].value ||
+ proposal->user_features[i].start != shape_plan->user_features[i].start ||
+ proposal->user_features[i].end != shape_plan->user_features[i].end)
+ return false;
+ return true;
+}
- return ret;
+static inline hb_bool_t
+hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ if (proposal->num_coords != shape_plan->num_coords)
+ return false;
+ for (unsigned int i = 0, n = proposal->num_coords; i < n; i++)
+ if (proposal->coords[i] != shape_plan->coords[i])
+ return false;
+ return true;
}
+static hb_bool_t
+hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ 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) ||
+ (shape_plan->shaper_func == proposal->shaper_func));
+}
-/*
- * Caching
- */
+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) {
+ if (user_features->start != 0 || user_features->end != (unsigned int) -1)
+ return true;
+ num_user_features--;
+ user_features++;
+ }
+ return false;
+}
+
+static inline hb_bool_t
+hb_coords_present (const int *coords,
+ unsigned int num_coords)
+{
+ return num_coords != 0;
+}
/**
* hb_shape_plan_create_cached:
- * @face: #hb_face_t to use
- * @props: The #hb_segment_properties_t of the segment
- * @user_features: (array length=num_user_features): The list of user-selected features
- * @num_user_features: The number of user-selected features
- * @shaper_list: (array zero-terminated=1): List of shapers to try
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
*
- * Creates a cached shaping plan suitable for reuse, for a combination
- * of @face, @user_features, @props, and @shaper_list.
+ *
*
- * Return value: (transfer full): The shaping plan
+ * Return value: (transfer full):
*
* Since: 0.9.7
**/
@@ -491,25 +471,6 @@ hb_shape_plan_create_cached (hb_face_t *face,
shaper_list);
}
-/**
- * hb_shape_plan_create_cached2:
- * @face: #hb_face_t to use
- * @props: The #hb_segment_properties_t of the segment
- * @user_features: (array length=num_user_features): The list of user-selected features
- * @num_user_features: The number of user-selected features
- * @coords: (array length=num_coords): The list of variation-space coordinates
- * @num_coords: The number of variation-space coordinates
- * @shaper_list: (array zero-terminated=1): List of shapers to try
- *
- * The variable-font version of #hb_shape_plan_create_cached.
- * Creates a cached shaping plan suitable for reuse, for a combination
- * of @face, @user_features, @props, and @shaper_list, plus the
- * variation-space coordinates @coords.
- *
- * Return value: (transfer full): The shaping plan
- *
- * Since: 1.4.0
- **/
hb_shape_plan_t *
hb_shape_plan_create_cached2 (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -520,56 +481,79 @@ hb_shape_plan_create_cached2 (hb_face_t *face,
const char * const *shaper_list)
{
DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,
- "face=%p num_features=%u shaper_list=%p",
+ "face=%p num_features=%d shaper_list=%p",
face,
num_user_features,
shaper_list);
-retry:
- hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans;
-
- bool dont_cache = !hb_object_is_valid (face);
+ hb_shape_plan_proposal_t proposal = {
+ *props,
+ shaper_list,
+ user_features,
+ num_user_features,
+ nullptr
+ };
+
+ if (shaper_list) {
+ /* Choose shaper. Adapted from hb_shape_plan_plan().
+ * Must choose shaper exactly the same way as that function. */
+ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (0 == strcmp (*shaper_item, #shaper) && \
+ hb_##shaper##_shaper_face_data_ensure (face)) \
+ { \
+ proposal.shaper_func = _hb_##shaper##_shape; \
+ break; \
+ }
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
- if (likely (!dont_cache))
- {
- hb_shape_plan_key_t key;
- if (!key.init (false,
- face,
- props,
- user_features,
- num_user_features,
- coords,
- num_coords,
- shaper_list))
+ if (unlikely (!proposal.shaper_func))
return hb_shape_plan_get_empty ();
+ }
+
+
+retry:
+ hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
+ /* 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 (node->shape_plan->key.equal (&key))
+ 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);
+ 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,
shaper_list);
- if (unlikely (dont_cache))
+ /* Don't add to the cache if face is inert. */
+ if (unlikely (hb_object_is_inert (face)))
return shape_plan;
- hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) hb_calloc (1, sizeof (hb_face_t::plan_node_t));
+ /* Don't add the plan to the cache if there were user features with non-global ranges */
+ if (hb_non_global_user_features_present (user_features, num_user_features))
+ return shape_plan;
+ /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */
+ if (hb_coords_present (coords, num_coords))
+ return shape_plan;
+
+ hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
if (unlikely (!node))
return shape_plan;
node->shape_plan = shape_plan;
node->next = cached_plan_nodes;
- if (unlikely (!face->shape_plans.cmpexch (cached_plan_nodes, node)))
- {
+ if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
hb_shape_plan_destroy (shape_plan);
- hb_free (node);
+ free (node);
goto retry;
}
DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "inserted into cache");
@@ -577,5 +561,18 @@ retry:
return hb_shape_plan_reference (shape_plan);
}
-
-#endif
+/**
+ * hb_shape_plan_get_shaper:
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.7
+ **/
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
+{
+ return shape_plan->shaper_name;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
index aaf5cf9c457..b62ae7ca350 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -36,20 +36,6 @@
HB_BEGIN_DECLS
-/**
- * hb_shape_plan_t:
- *
- * Data type for holding a shaping plan.
- *
- * Shape plans contain information about how HarfBuzz will shape a
- * particular text segment, based on the segment's properties and the
- * capabilities in the font face in use.
- *
- * Shape plans can be queried about how shaping will perform, given a set
- * of specific input parameters (script, language, direction, features,
- * etc.).
- *
- **/
typedef struct hb_shape_plan_t hb_shape_plan_t;
HB_EXTERN hb_shape_plan_t *
@@ -102,8 +88,8 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
hb_bool_t replace);
HB_EXTERN void *
-hb_shape_plan_get_user_data (const hb_shape_plan_t *shape_plan,
- hb_user_data_key_t *key);
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key);
HB_EXTERN hb_bool_t
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.hh
deleted file mode 100644
index 6fc73939b37..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.hh
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright © 2012,2018 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_SHAPE_PLAN_HH
-#define HB_SHAPE_PLAN_HH
-
-#include "hb.hh"
-#include "hb-shaper.hh"
-#include "hb-ot-shape.hh"
-
-
-struct hb_shape_plan_key_t
-{
- hb_segment_properties_t props;
-
- const hb_feature_t *user_features;
- unsigned int num_user_features;
-
-#ifndef HB_NO_OT_SHAPE
- hb_ot_shape_plan_key_t ot;
-#endif
-
- hb_shape_func_t *shaper_func;
- const char *shaper_name;
-
- HB_INTERNAL bool init (bool copy,
- hb_face_t *face,
- const hb_segment_properties_t *props,
- const hb_feature_t *user_features,
- unsigned int num_user_features,
- const int *coords,
- unsigned int num_coords,
- const char * const *shaper_list);
-
- HB_INTERNAL void fini () { hb_free ((void *) user_features); user_features = nullptr; }
-
- HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other);
-
- HB_INTERNAL bool equal (const hb_shape_plan_key_t *other);
-};
-
-struct hb_shape_plan_t
-{
- ~hb_shape_plan_t () { key.fini (); }
- hb_object_header_t header;
- hb_face_t *face_unsafe; /* We don't carry a reference to face. */
- hb_shape_plan_key_t key;
-#ifndef HB_NO_OT_SHAPE
- hb_ot_shape_plan_t ot;
-#endif
-};
-
-
-#endif /* HB_SHAPE_PLAN_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
index d9598fc7044..39355b337d6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -26,65 +26,34 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-shaper.hh"
-#include "hb-shape-plan.hh"
-#include "hb-buffer.hh"
-#include "hb-font.hh"
-#include "hb-machinery.hh"
-
-
-#ifndef HB_NO_SHAPER
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-font-private.hh"
/**
* SECTION:hb-shape
- * @title: hb-shape
+ * @title: Shaping
* @short_description: Conversion of text strings into positioned glyphs
* @include: hb.h
*
* Shaping is the central operation of HarfBuzz. Shaping operates on buffers,
* which are sequences of Unicode characters that use the same font and have
- * the same text direction, script, and language. After shaping the buffer
+ * the same text direction, script and language. After shaping the buffer
* contains the output glyphs and their positions.
**/
+static const char **static_shaper_list;
-static inline void free_static_shaper_list ();
-
-static const char * const nil_shaper_list[] = {nullptr};
-
-static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *,
- hb_shaper_list_lazy_loader_t>
-{
- static const char ** create ()
- {
- const char **shaper_list = (const char **) hb_calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
- if (unlikely (!shaper_list))
- return nullptr;
-
- const hb_shaper_entry_t *shapers = _hb_shapers_get ();
- unsigned int i;
- for (i = 0; i < HB_SHAPERS_COUNT; i++)
- shaper_list[i] = shapers[i].name;
- shaper_list[i] = nullptr;
-
- hb_atexit (free_static_shaper_list);
-
- return shaper_list;
- }
- static void destroy (const char **l)
- { hb_free (l); }
- static const char * const * get_null ()
- { return nil_shaper_list; }
-} static_shaper_list;
-
-static inline
-void free_static_shaper_list ()
+#ifdef HB_USE_ATEXIT
+static
+void free_static_shaper_list (void)
{
- static_shaper_list.free_instance ();
+ free (static_shaper_list);
}
-
+#endif
/**
* hb_shape_list_shapers:
@@ -97,9 +66,37 @@ void free_static_shaper_list ()
* Since: 0.9.2
**/
const char **
-hb_shape_list_shapers ()
+hb_shape_list_shapers (void)
{
- return static_shaper_list.get_unconst ();
+retry:
+ const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+
+ if (unlikely (!shaper_list))
+ {
+ /* 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[] = {nullptr};
+ return nil_shaper_list;
+ }
+
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+ unsigned int i;
+ for (i = 0; i < HB_SHAPERS_COUNT; i++)
+ shaper_list[i] = shapers[i].name;
+ shaper_list[i] = nullptr;
+
+ if (!hb_atomic_ptr_cmpexch (&static_shaper_list, nullptr, shaper_list)) {
+ free (shaper_list);
+ goto retry;
+ }
+
+#ifdef HB_USE_ATEXIT
+ atexit (free_static_shaper_list); /* First person registers atexit() callback. */
+#endif
+ }
+
+ return shaper_list;
}
@@ -107,13 +104,13 @@ hb_shape_list_shapers ()
* hb_shape_full:
* @font: an #hb_font_t to use for shaping
* @buffer: an #hb_buffer_t to shape
- * @features: (array length=num_features) (nullable): an array of user
- * specified #hb_feature_t or `NULL`
+ * @features: (array length=num_features) (allow-none): an array of user
+ * specified #hb_feature_t or %NULL
* @num_features: the length of @features array
- * @shaper_list: (array zero-terminated=1) (nullable): a `NULL`-terminated
- * array of shapers to use or `NULL`
+ * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated
+ * array of shapers to use or %NULL
*
- * See hb_shape() for details. If @shaper_list is not `NULL`, the specified
+ * See hb_shape() for details. If @shaper_list is not %NULL, the specified
* shapers will be used in the given order, otherwise the default shapers list
* will be used.
*
@@ -128,45 +125,15 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
- if (unlikely (!buffer->len))
- return true;
-
- buffer->enter ();
-
- hb_buffer_t *text_buffer = nullptr;
- if (buffer->flags & HB_BUFFER_FLAG_VERIFY)
- {
- text_buffer = hb_buffer_create ();
- hb_buffer_append (text_buffer, buffer, 0, -1);
- }
-
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props,
features, num_features,
font->coords, font->num_coords,
shaper_list);
-
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
-
- if (buffer->max_ops <= 0)
- buffer->shaping_failed = true;
-
hb_shape_plan_destroy (shape_plan);
- if (text_buffer)
- {
- if (res && buffer->successful && !buffer->shaping_failed
- && text_buffer->successful
- && !buffer->verify (text_buffer,
- font,
- features,
- num_features,
- shaper_list))
- res = false;
- hb_buffer_destroy (text_buffer);
- }
-
- buffer->leave ();
-
+ if (res)
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
return res;
}
@@ -174,15 +141,13 @@ hb_shape_full (hb_font_t *font,
* hb_shape:
* @font: an #hb_font_t to use for shaping
* @buffer: an #hb_buffer_t to shape
- * @features: (array length=num_features) (nullable): an array of user
- * specified #hb_feature_t or `NULL`
+ * @features: (array length=num_features) (allow-none): an array of user
+ * specified #hb_feature_t or %NULL
* @num_features: the length of @features array
*
* Shapes @buffer using @font turning its Unicode characters content to
- * positioned glyphs. If @features is not `NULL`, it will be used to control the
- * features applied during shaping. If two @features have the same tag but
- * overlapping ranges the value of the feature with the higher index takes
- * precedence.
+ * positioned glyphs. If @features is not %NULL, it will be used to control the
+ * features applied during shaping.
*
* Since: 0.9.2
**/
@@ -194,252 +159,3 @@ hb_shape (hb_font_t *font,
{
hb_shape_full (font, buffer, features, num_features, nullptr);
}
-
-
-#ifdef HB_EXPERIMENTAL_API
-
-static float
-buffer_advance (hb_buffer_t *buffer)
-{
- float a = 0;
- auto *pos = buffer->pos;
- unsigned count = buffer->len;
- if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
- for (unsigned i = 0; i < count; i++)
- a += pos[i].x_advance;
- else
- for (unsigned i = 0; i < count; i++)
- a += pos[i].y_advance;
- return a;
-}
-
-static void
-reset_buffer (hb_buffer_t *buffer,
- hb_array_t<const hb_glyph_info_t> text)
-{
- assert (buffer->ensure (text.length));
- buffer->have_positions = false;
- buffer->len = text.length;
- memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
- hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
-}
-
-/**
- * hb_shape_justify:
- * @font: a mutable #hb_font_t to use for shaping
- * @buffer: an #hb_buffer_t to shape
- * @features: (array length=num_features) (nullable): an array of user
- * specified #hb_feature_t or `NULL`
- * @num_features: the length of @features array
- * @shaper_list: (array zero-terminated=1) (nullable): a `NULL`-terminated
- * array of shapers to use or `NULL`
- * @min_target_advance: Minimum advance width/height to aim for.
- * @max_target_advance: Maximum advance width/height to aim for.
- * @advance: (inout): Input/output advance width/height of the buffer.
- * @var_tag: (out): Variation-axis tag used for justification.
- * @var_value: (out): Variation-axis value used to reach target justification.
- *
- * See hb_shape_full() for basic details. If @shaper_list is not `NULL`, the specified
- * shapers will be used in the given order, otherwise the default shapers list
- * will be used.
- *
- * In addition, justify the shaping results such that the shaping results reach
- * the target advance width/height, depending on the buffer direction.
- *
- * If the advance of the buffer shaped with hb_shape_full() is already known,
- * put that in *advance. Otherwise set *advance to zero.
- *
- * This API is currently experimental and will probably change in the future.
- *
- * Return value: false if all shapers failed, true otherwise
- *
- * XSince: EXPERIMENTAL
- **/
-hb_bool_t
-hb_shape_justify (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shaper_list,
- float min_target_advance,
- float max_target_advance,
- float *advance, /* IN/OUT */
- hb_tag_t *var_tag, /* OUT */
- float *var_value /* OUT */)
-{
- // TODO Negative font scales?
-
- /* If default advance already matches target, nothing to do. Shape and return. */
- if (min_target_advance <= *advance && *advance <= max_target_advance)
- {
- *var_tag = HB_TAG_NONE;
- *var_value = 0.0f;
- return hb_shape_full (font, buffer,
- features, num_features,
- shaper_list);
- }
-
- hb_face_t *face = font->face;
-
- /* Choose variation tag to use for justification. */
-
- hb_tag_t tag = HB_TAG_NONE;
- hb_ot_var_axis_info_t axis_info;
-
- hb_tag_t tags[] =
- {
- HB_TAG ('j','s','t','f'),
- HB_TAG ('w','d','t','h'),
- };
- for (unsigned i = 0; i < ARRAY_LENGTH (tags); i++)
- if (hb_ot_var_find_axis_info (face, tags[i], &axis_info))
- {
- tag = *var_tag = tags[i];
- break;
- }
-
- /* If no suitable variation axis found, can't justify. Just shape and return. */
- if (!tag)
- {
- *var_tag = HB_TAG_NONE;
- *var_value = 0.0f;
- if (hb_shape_full (font, buffer,
- features, num_features,
- shaper_list))
- {
- *advance = buffer_advance (buffer);
- return true;
- }
- else
- return false;
- }
-
- /* Copy buffer text as we need it so we can shape multiple times. */
- unsigned text_len = buffer->len;
- auto *text_info = (hb_glyph_info_t *) hb_malloc (text_len * sizeof (buffer->info[0]));
- if (unlikely (text_len && !text_info))
- return false;
- hb_memcpy (text_info, buffer->info, text_len * sizeof (buffer->info[0]));
- auto text = hb_array<const hb_glyph_info_t> (text_info, text_len);
-
- /* If default advance was not provided to us, calculate it. */
- if (!*advance)
- {
- hb_font_set_variation (font, tag, axis_info.default_value);
- if (!hb_shape_full (font, buffer,
- features, num_features,
- shaper_list))
- return false;
- *advance = buffer_advance (buffer);
- }
-
- /* If default advance already matches target, nothing to do. Shape and return.
- * Do this again, in case advance was just calculated.
- */
- if (min_target_advance <= *advance && *advance <= max_target_advance)
- {
- *var_tag = HB_TAG_NONE;
- *var_value = 0.0f;
- return true;
- }
-
- /* Prepare for running the solver. */
- double a, b, ya, yb;
- if (*advance < min_target_advance)
- {
- /* Need to expand. */
- ya = (double) *advance;
- a = (double) axis_info.default_value;
- b = (double) axis_info.max_value;
-
- /* Shape buffer for maximum expansion to use as other
- * starting point for the solver. */
- hb_font_set_variation (font, tag, (float) b);
- reset_buffer (buffer, text);
- if (!hb_shape_full (font, buffer,
- features, num_features,
- shaper_list))
- return false;
- yb = (double) buffer_advance (buffer);
- /* If the maximum expansion is less than max target,
- * there's nothing to solve for. Just return it. */
- if (yb <= (double) max_target_advance)
- {
- *var_value = (float) b;
- *advance = (float) yb;
- return true;
- }
- }
- else
- {
- /* Need to shrink. */
- yb = (double) *advance;
- a = (double) axis_info.min_value;
- b = (double) axis_info.default_value;
-
- /* Shape buffer for maximum shrinkate to use as other
- * starting point for the solver. */
- hb_font_set_variation (font, tag, (float) a);
- reset_buffer (buffer, text);
- if (!hb_shape_full (font, buffer,
- features, num_features,
- shaper_list))
- return false;
- ya = (double) buffer_advance (buffer);
- /* If the maximum shrinkate is more than min target,
- * there's nothing to solve for. Just return it. */
- if (ya >= (double) min_target_advance)
- {
- *var_value = (float) a;
- *advance = (float) ya;
- return true;
- }
- }
-
- /* Run the solver to find a var axis value that hits
- * the desired width. */
-
- double epsilon = (b - a) / (1<<14);
- bool failed = false;
-
- auto f = [&] (double x)
- {
- hb_font_set_variation (font, tag, (float) x);
- reset_buffer (buffer, text);
- if (unlikely (!hb_shape_full (font, buffer,
- features, num_features,
- shaper_list)))
- {
- failed = true;
- return (double) min_target_advance;
- }
-
- double w = (double) buffer_advance (buffer);
- DEBUG_MSG (JUSTIFY, nullptr, "Trying '%c%c%c%c' axis parameter %f. Advance %g. Target: min %g max %g",
- HB_UNTAG (tag), x, w,
- (double) min_target_advance, (double) max_target_advance);
- return w;
- };
-
- double y = 0;
- double itp = solve_itp (f,
- a, b,
- epsilon,
- (double) min_target_advance, (double) max_target_advance,
- ya, yb, y);
-
- hb_free (text_info);
-
- if (failed)
- return false;
-
- *var_value = (float) itp;
- *advance = (float) y;
-
- return true;
-}
-
-#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
index d4d4fdfd267..39507ff744b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
@@ -26,7 +26,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -53,18 +53,6 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list);
-HB_EXTERN hb_bool_t
-hb_shape_justify (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features,
- const char * const *shaper_list,
- float min_target_advance,
- float max_target_advance,
- float *advance, /* IN/OUT */
- hb_tag_t *var_tag, /* OUT */
- float *var_value /* OUT */);
-
HB_EXTERN const char **
hb_shape_list_shapers (void);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
index b674fceb6af..7844081e95b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-impl-private.hh
@@ -24,15 +24,20 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_SHAPER_IMPL_HH
-#define HB_SHAPER_IMPL_HH
+#ifndef HB_SHAPER_IMPL_PRIVATE_HH
+#define HB_SHAPER_IMPL_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-shaper.hh"
-#include "hb-face.hh"
-#include "hb-font.hh"
-#include "hb-shape-plan.hh"
-#include "hb-buffer.hh"
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
-#endif /* HB_SHAPER_IMPL_HH */
+
+#ifdef HB_SHAPER
+#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object)
+#endif
+
+
+#endif /* HB_SHAPER_IMPL_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
index 4158b7094c9..b0835d31ab1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
@@ -28,18 +28,19 @@
#define HB_SHAPER_LIST_HH
#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
-#ifndef HB_NO_SHAPER
-
-
/* v--- Add new shapers in the right place here. */
#ifdef HAVE_GRAPHITE2
/* Only picks up fonts that have a "Silf" table. */
HB_SHAPER_IMPLEMENT (graphite2)
#endif
+#ifdef HAVE_CORETEXT
+/* Only picks up fonts that have a "mort" or "morx" table. */
+HB_SHAPER_IMPLEMENT (coretext_aat)
+#endif
-#ifndef HB_NO_OT_SHAPE
-HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main shaper. */
+#ifdef HAVE_OT
+HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
#endif
#ifdef HAVE_UNISCRIBE
@@ -52,9 +53,6 @@ HB_SHAPER_IMPLEMENT (directwrite)
HB_SHAPER_IMPLEMENT (coretext)
#endif
-#ifndef HB_NO_FALLBACK_SHAPE
+#ifdef HAVE_FALLBACK
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
#endif
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
new file mode 100644
index 00000000000..ce2d9f28395
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
@@ -0,0 +1,124 @@
+/*
+ * 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_SHAPER_PRIVATE_HH
+#define HB_SHAPER_PRIVATE_HH
+
+#include "hb-private.hh"
+
+typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+#define HB_SHAPER_IMPLEMENT(name) \
+ extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+struct hb_shaper_pair_t {
+ char name[16];
+ hb_shape_func_t *func;
+};
+
+HB_INTERNAL const hb_shaper_pair_t *
+_hb_shapers_get (void);
+
+
+/* For embedding in face / font / ... */
+struct hb_shaper_data_t {
+#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
+
+/* Means: succeeded, but don't need to keep any data. */
+#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
+
+/* Means: tried but failed to create. */
+#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_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_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); \
+ 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_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), nullptr, data)) { \
+ if (data && \
+ data != HB_SHAPER_DATA_INVALID && \
+ data != HB_SHAPER_DATA_SUCCEEDED) \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
+ goto retry; \
+ } \
+ } \
+ return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \
+}
+
+
+#endif /* HB_SHAPER_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
index c4885cda949..2c44cf26533 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
@@ -24,52 +24,68 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
-#include "hb-shaper.hh"
-#include "hb-machinery.hh"
+#include "hb-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-atomic-private.hh"
-static const hb_shaper_entry_t _hb_all_shapers[] = {
+static const hb_shaper_pair_t all_shapers[] = {
#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
};
-#ifndef HB_NO_SHAPER
-static_assert (0 != ARRAY_LENGTH_CONST (_hb_all_shapers), "No shaper enabled.");
-#endif
-static inline void free_static_shapers ();
-static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t,
- hb_shapers_lazy_loader_t>
+/* Thread-safe, lock-free, shapers */
+
+static const hb_shaper_pair_t *static_shapers;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_static_shapers (void)
+{
+ if (unlikely (static_shapers != all_shapers))
+ free ((void *) static_shapers);
+}
+#endif
+
+const hb_shaper_pair_t *
+_hb_shapers_get (void)
{
- static hb_shaper_entry_t *create ()
+retry:
+ hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+
+ if (unlikely (!shapers))
{
char *env = getenv ("HB_SHAPER_LIST");
- if (!env || !*env)
- return nullptr;
+ if (!env || !*env) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, nullptr, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
- hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (_hb_all_shapers));
- if (unlikely (!shapers))
- return nullptr;
+ /* Not found; allocate one. */
+ shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
+ if (unlikely (!shapers)) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, nullptr, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
- hb_memcpy (shapers, _hb_all_shapers, sizeof (_hb_all_shapers));
+ memcpy (shapers, all_shapers, sizeof (all_shapers));
/* Reorder shaper list to prefer requested shapers. */
unsigned int i = 0;
char *end, *p = env;
- for (;;)
- {
+ for (;;) {
end = strchr (p, ',');
if (!end)
end = p + strlen (p);
- for (unsigned int j = i; j < ARRAY_LENGTH_CONST (_hb_all_shapers); j++)
+ for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
if (end - p == (int) strlen (shapers[j].name) &&
0 == strncmp (shapers[j].name, p, end - p))
{
/* Reorder this shaper to position i */
- struct hb_shaper_entry_t t = shapers[j];
+ struct hb_shaper_pair_t t = shapers[j];
memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
shapers[i] = t;
i++;
@@ -81,22 +97,15 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t,
p = end + 1;
}
- hb_atexit (free_static_shapers);
+ if (!hb_atomic_ptr_cmpexch (&static_shapers, nullptr, shapers)) {
+ free (shapers);
+ goto retry;
+ }
- return shapers;
+#ifdef HB_USE_ATEXIT
+ atexit (free_static_shapers); /* First person registers atexit() callback. */
+#endif
}
- static void destroy (hb_shaper_entry_t *p) { hb_free (p); }
- static const hb_shaper_entry_t *get_null () { return _hb_all_shapers; }
-} static_shapers;
-static inline
-void free_static_shapers ()
-{
- static_shapers.free_instance ();
-}
-
-const hb_shaper_entry_t *
-_hb_shapers_get ()
-{
- return static_shapers.get_unconst ();
+ return shapers;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh
deleted file mode 100644
index b4138a324ff..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper.hh
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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_SHAPER_HH
-#define HB_SHAPER_HH
-
-#include "hb.hh"
-#include "hb-machinery.hh"
-
-typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-#define HB_SHAPER_IMPLEMENT(name) \
- extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-
-struct hb_shaper_entry_t {
- char name[16];
- hb_shape_func_t *func;
-};
-
-HB_INTERNAL const hb_shaper_entry_t *
-_hb_shapers_get ();
-
-
-template <typename Data, unsigned int WheresData, typename T>
-struct hb_shaper_lazy_loader_t;
-
-#define HB_SHAPER_ORDER(Shaper) \
- HB_PASTE (HB_SHAPER_ORDER_, Shaper)
-enum hb_shaper_order_t
-{
- _HB_SHAPER_ORDER_ORDER_ZERO,
-#define HB_SHAPER_IMPLEMENT(Shaper) \
- HB_SHAPER_ORDER (Shaper),
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
- _HB_SHAPERS_COUNT_PLUS_ONE,
- HB_SHAPERS_COUNT = _HB_SHAPERS_COUNT_PLUS_ONE - 1,
-};
-
-template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object_data_type_t;
-
-#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
-#define HB_SHAPER_DATA_TYPE(shaper, object) hb_##shaper##_##object##_data_t
-#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_INSTANTIATE_SHAPERS(shaper, object) \
- \
- struct 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); \
- extern "C" HB_INTERNAL void \
- HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \
- \
- template <> \
- struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \
- { \
- typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \
- }; \
- \
- template <unsigned int WheresData> \
- struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \
- : hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \
- hb_shaper_lazy_loader_t<hb_##object##_t, \
- WheresData, \
- HB_SHAPER_DATA_TYPE(shaper, object)>, \
- hb_##object##_t, WheresData> \
- { \
- typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \
- static Type* create (hb_##object##_t *data) \
- { return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \
- static Type *get_null () { return nullptr; } \
- static void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
- }; \
- \
- static_assert (true, "") /* Require semicolon after. */
-
-
-template <typename Object>
-struct hb_shaper_object_dataset_t
-{
- void init0 (Object *parent_data)
- {
- this->parent_data = parent_data;
-#define HB_SHAPER_IMPLEMENT(shaper) shaper.init0 ();
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
- }
- void fini ()
- {
-#define HB_SHAPER_IMPLEMENT(shaper) shaper.fini ();
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
- }
-
- Object *parent_data; /* MUST be JUST before the lazy loaders. */
-#define HB_SHAPER_IMPLEMENT(shaper) \
- hb_shaper_lazy_loader_t<Object, HB_SHAPER_ORDER(shaper), \
- typename hb_shaper_object_data_type_t<HB_SHAPER_ORDER(shaper), Object>::value \
- > shaper;
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-};
-
-#endif /* HB_SHAPER_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-static.cc b/src/3rdparty/harfbuzz-ng/src/hb-static.cc
deleted file mode 100644
index a1a2522edf9..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-static.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright © 2018 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.hh"
-
-#include "hb-open-type.hh"
-#include "hb-face.hh"
-
-#include "hb-aat-layout-common.hh"
-#include "hb-aat-layout-feat-table.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-cmap-table.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-maxp-table.hh"
-
-#ifndef HB_NO_VISIBILITY
-#include "hb-ot-name-language-static.hh"
-
-uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
-/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
-
-DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF};
-DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF};
-DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};
-DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01};
-DEFINE_NULL_NAMESPACE_BYTES (OT, ClipRecord) = {0x01};
-DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00};
-DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF};
-DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF};
-
-
-/* hb_map_t */
-
-const hb_codepoint_t minus_1 = -1;
-
-/* hb_face_t */
-
-#ifndef HB_NO_BEYOND_64K
-static inline unsigned
-load_num_glyphs_from_loca (const hb_face_t *face)
-{
- unsigned ret = 0;
-
- unsigned indexToLocFormat = face->table.head->indexToLocFormat;
-
- if (indexToLocFormat <= 1)
- {
- bool short_offset = 0 == indexToLocFormat;
- hb_blob_t *loca_blob = face->table.loca.get_blob ();
- ret = hb_max (1u, loca_blob->length / (short_offset ? 2 : 4)) - 1;
- }
-
- return ret;
-}
-#endif
-
-static inline unsigned
-load_num_glyphs_from_maxp (const hb_face_t *face)
-{
- return face->table.maxp->get_num_glyphs ();
-}
-
-unsigned int
-hb_face_t::load_num_glyphs () const
-{
- unsigned ret = 0;
-
-#ifndef HB_NO_BEYOND_64K
- ret = hb_max (ret, load_num_glyphs_from_loca (this));
-#endif
-
- ret = hb_max (ret, load_num_glyphs_from_maxp (this));
-
- num_glyphs = ret;
- return ret;
-}
-
-unsigned int
-hb_face_t::load_upem () const
-{
- unsigned int ret = table.head->get_upem ();
- upem = ret;
- return ret;
-}
-
-
-#ifndef HB_NO_VAR
-bool
-_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
- int *lsb)
-{
- return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
-}
-
-unsigned
-_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
-{
- return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
-}
-#endif
-
-bool
-_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb)
-{
- return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb);
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
index e7ac1192324..ba829b0cf04 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
@@ -29,7 +29,7 @@
#define HB_STRING_ARRAY_HH
#endif
-#include "hb.hh"
+#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 */
@@ -37,19 +37,18 @@
#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)
-#define HB_STRING_ARRAY_LENG_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _length)
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/q/28433862
+ * 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[HB_VAR_ARRAY];
+ char str[VAR];
}
HB_STRING_ARRAY_POOL_NAME =
{
@@ -67,19 +66,16 @@ static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] =
sizeof (HB_STRING_ARRAY_TYPE_NAME)
};
-static const unsigned int HB_STRING_ARRAY_LENG_NAME = ARRAY_LENGTH_CONST (HB_STRING_ARRAY_OFFS_NAME) - 1;
-
-static inline hb_bytes_t
+static inline hb_string_t
HB_STRING_ARRAY_NAME (unsigned int i)
{
assert (i < ARRAY_LENGTH (HB_STRING_ARRAY_OFFS_NAME) - 1);
- return hb_bytes_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);
+ 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
-#undef HB_STRING_ARRAY_LENG_NAME
#endif /* HB_STRING_ARRAY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-style.cc b/src/3rdparty/harfbuzz-ng/src/hb-style.cc
deleted file mode 100644
index bd5cb5c6be0..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-style.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_STYLE
-
-#include "hb-ot-var-avar-table.hh"
-#include "hb-ot-var-fvar-table.hh"
-#include "hb-ot-stat-table.hh"
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-post-table.hh"
-#include "hb-ot-face.hh"
-
-/**
- * SECTION:hb-style
- * @title: hb-style
- * @short_description: Font Styles
- * @include: hb.h
- *
- * Functions for fetching style information from fonts.
- **/
-
-static inline float
-_hb_angle_to_ratio (float a)
-{
- return tanf (a * -HB_PI / 180.f);
-}
-
-static inline float
-_hb_ratio_to_angle (float r)
-{
- return atanf (r) * -180.f / HB_PI;
-}
-
-/**
- * hb_style_get_value:
- * @font: a #hb_font_t object.
- * @style_tag: a style tag.
- *
- * Searches variation axes of a #hb_font_t object for a specific axis first,
- * if not set, then tries to get default style values from different
- * tables of the font.
- *
- * Returns: Corresponding axis or default value to a style tag.
- *
- * Since: 3.0.0
- **/
-float
-hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
-{
- if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
- return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
-
- hb_face_t *face = font->face;
-
-#ifndef HB_NO_VAR
- hb_ot_var_axis_info_t axis;
- if (hb_ot_var_find_axis_info (face, style_tag, &axis))
- {
- if (axis.axis_index < font->num_coords) return font->design_coords[axis.axis_index];
- /* If a face is variable, fvar's default_value is better than STAT records */
- return axis.default_value;
- }
-#endif
-
- if (style_tag == HB_STYLE_TAG_OPTICAL_SIZE && font->ptem)
- return font->ptem;
-
- /* STAT */
- float value;
- if (face->table.STAT->get_value (style_tag, &value))
- return value;
-
- switch ((unsigned) style_tag)
- {
- case HB_STYLE_TAG_ITALIC:
- return face->table.OS2->is_italic () || face->table.head->is_italic () ? 1 : 0;
- case HB_STYLE_TAG_OPTICAL_SIZE:
- {
- unsigned int lower, design, upper;
- return face->table.OS2->v5 ().get_optical_size (&lower, &upper)
- ? (float) (lower + upper) / 2.f
- : hb_ot_layout_get_size_params (face, &design, nullptr, nullptr, nullptr, nullptr)
- ? design / 10.f
- : 12.f;
- }
- case HB_STYLE_TAG_SLANT_ANGLE:
- {
- float angle = face->table.post->table->italicAngle.to_float ();
-
- if (font->slant)
- angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle));
-
- return angle;
- }
- case HB_STYLE_TAG_WIDTH:
- return face->table.OS2->has_data ()
- ? face->table.OS2->get_width ()
- : (face->table.head->is_condensed () ? 75 :
- face->table.head->is_expanded () ? 125 :
- 100);
- case HB_STYLE_TAG_WEIGHT:
- return face->table.OS2->has_data ()
- ? face->table.OS2->usWeightClass
- : (face->table.head->is_bold () ? 700 : 400);
- default:
- return 0;
- }
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-style.h b/src/3rdparty/harfbuzz-ng/src/hb-style.h
deleted file mode 100644
index d17d2daa5f8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-style.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright © 2019 Ebrahim Byagowi
- *
- * 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.
- */
-
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
-#error "Include <hb.h> instead."
-#endif
-
-#ifndef HB_STYLE_H
-#define HB_STYLE_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-/**
- * hb_style_tag_t:
- * @HB_STYLE_TAG_ITALIC: Used to vary between non-italic and italic.
- * A value of 0 can be interpreted as "Roman" (non-italic); a value of 1 can
- * be interpreted as (fully) italic.
- * @HB_STYLE_TAG_OPTICAL_SIZE: Used to vary design to suit different text sizes.
- * Non-zero. Values can be interpreted as text size, in points.
- * @HB_STYLE_TAG_SLANT_ANGLE: Used to vary between upright and slanted text. Values
- * must be greater than -90 and less than +90. Values can be interpreted as
- * the angle, in counter-clockwise degrees, of oblique slant from whatever the
- * designer considers to be upright for that font design. Typical right-leaning
- * Italic fonts have a negative slant angle (typically around -12)
- * @HB_STYLE_TAG_SLANT_RATIO: same as @HB_STYLE_TAG_SLANT_ANGLE expression as ratio.
- * Typical right-leaning Italic fonts have a positive slant ratio (typically around 0.2)
- * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider.
- * Non-zero. Values can be interpreted as a percentage of whatever the font
- * designer considers “normal width” for that font design.
- * @HB_STYLE_TAG_WEIGHT: Used to vary stroke thicknesses or other design details
- * to give variation from lighter to blacker. Values can be interpreted in direct
- * comparison to values for usWeightClass in the OS/2 table,
- * or the CSS font-weight property.
- *
- * Defined by [OpenType Design-Variation Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg).
- *
- * Since: 3.0.0
- **/
-typedef enum
-{
- HB_STYLE_TAG_ITALIC = HB_TAG ('i','t','a','l'),
- HB_STYLE_TAG_OPTICAL_SIZE = HB_TAG ('o','p','s','z'),
- HB_STYLE_TAG_SLANT_ANGLE = HB_TAG ('s','l','n','t'),
- HB_STYLE_TAG_SLANT_RATIO = HB_TAG ('S','l','n','t'),
- HB_STYLE_TAG_WIDTH = HB_TAG ('w','d','t','h'),
- HB_STYLE_TAG_WEIGHT = HB_TAG ('w','g','h','t'),
-
- /*< private >*/
- _HB_STYLE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
-} hb_style_tag_t;
-
-
-HB_EXTERN float
-hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag);
-
-HB_END_DECLS
-
-#endif /* HB_STYLE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh
deleted file mode 100644
index e523c258203..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright © 2022 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): Garret Rieger
- */
-
-#ifndef HB_SUBSET_ACCELERATOR_HH
-#define HB_SUBSET_ACCELERATOR_HH
-
-
-#include "hb.hh"
-
-#include "hb-map.hh"
-#include "hb-multimap.hh"
-#include "hb-set.hh"
-
-extern HB_INTERNAL hb_user_data_key_t _hb_subset_accelerator_user_data_key;
-
-namespace CFF {
-struct cff_subset_accelerator_t;
-}
-
-namespace OT {
-struct SubtableUnicodesCache;
-};
-
-struct hb_subset_accelerator_t
-{
- static hb_user_data_key_t* user_data_key()
- {
- return &_hb_subset_accelerator_user_data_key;
- }
-
- static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
- const hb_multimap_t gid_to_unicodes_,
- const hb_set_t& unicodes_,
- bool has_seac_) {
- hb_subset_accelerator_t* accel =
- (hb_subset_accelerator_t*) hb_calloc (1, sizeof(hb_subset_accelerator_t));
-
- new (accel) hb_subset_accelerator_t (unicode_to_gid_,
- gid_to_unicodes_,
- unicodes_,
- has_seac_);
-
- return accel;
- }
-
- static void destroy (void* p)
- {
- if (!p) return;
-
- hb_subset_accelerator_t *accel = (hb_subset_accelerator_t *) p;
-
- accel->~hb_subset_accelerator_t ();
-
- hb_free (accel);
- }
-
- hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_,
- const hb_multimap_t& gid_to_unicodes_,
- const hb_set_t& unicodes_,
- bool has_seac_) :
- unicode_to_gid(unicode_to_gid_),
- gid_to_unicodes (gid_to_unicodes_),
- unicodes(unicodes_),
- cmap_cache(nullptr),
- destroy_cmap_cache(nullptr),
- has_seac(has_seac_),
- cff_accelerator(nullptr),
- destroy_cff_accelerator(nullptr) {}
-
- ~hb_subset_accelerator_t ()
- {
- if (cff_accelerator && destroy_cff_accelerator)
- destroy_cff_accelerator ((void*) cff_accelerator);
-
- if (cmap_cache && destroy_cmap_cache)
- destroy_cmap_cache ((void*) cmap_cache);
- }
-
- // Generic
-
- mutable hb_mutex_t sanitized_table_cache_lock;
- mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
-
- const hb_map_t unicode_to_gid;
- const hb_multimap_t gid_to_unicodes;
- const hb_set_t unicodes;
-
- // cmap
- const OT::SubtableUnicodesCache* cmap_cache;
- hb_destroy_func_t destroy_cmap_cache;
-
- // CFF
- bool has_seac;
- const CFF::cff_subset_accelerator_t* cff_accelerator;
- hb_destroy_func_t destroy_cff_accelerator;
-
- // TODO(garretrieger): cumulative glyf checksum map
-
- bool in_error () const
- {
- return unicode_to_gid.in_error () ||
- gid_to_unicodes.in_error () ||
- unicodes.in_error () ||
- sanitized_table_cache.in_error ();
- }
-};
-
-
-#endif /* HB_SUBSET_ACCELERATOR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc
deleted file mode 100644
index 6e1b6f713d2..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.cc
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_SUBSET_CFF
-
-#include "hb-ot-cff-common.hh"
-#include "hb-ot-cff2-table.hh"
-#include "hb-subset-cff-common.hh"
-
-/* Disable FDSelect format 0 for compatibility with fonttools which doesn't seem choose it.
- * Rarely any/much smaller than format 3 anyway. */
-#define CFF_SERIALIZE_FDSELECT_0 0
-
-using namespace CFF;
-
-
-/* Determine an optimal FDSelect format according to a provided plan.
- *
- * Return value: FDSelect format, size, and ranges for the most compact subset FDSelect
- * along with a font index remapping table
- */
-
-bool
-hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
- unsigned int fdCount,
- const FDSelect &src, /* IN */
- unsigned int &subset_fd_count /* OUT */,
- unsigned int &subset_fdselect_size /* OUT */,
- unsigned int &subset_fdselect_format /* OUT */,
- hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
- hb_inc_bimap_t &fdmap /* OUT */)
-{
- subset_fd_count = 0;
- subset_fdselect_size = 0;
- subset_fdselect_format = 0;
- unsigned int num_ranges = 0;
-
- unsigned int subset_num_glyphs = plan->num_output_glyphs ();
- if (subset_num_glyphs == 0)
- return true;
-
- {
- /* use hb_set to determine the subset of font dicts */
- hb_set_t set;
- hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
- for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
- {
- hb_codepoint_t glyph;
- hb_codepoint_t fd;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- {
- /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */
- glyph = i;
- }
- fd = src.get_fd (glyph);
- set.add (fd);
-
- if (fd != prev_fd)
- {
- num_ranges++;
- prev_fd = fd;
- code_pair_t pair = { fd, i };
- fdselect_ranges.push (pair);
- }
- }
-
- subset_fd_count = set.get_population ();
- if (subset_fd_count == fdCount)
- {
- /* all font dicts belong to the subset. no need to subset FDSelect & FDArray */
- fdmap.identity (fdCount);
- }
- else
- {
- /* create a fdmap */
- fdmap.reset ();
-
- hb_codepoint_t fd = CFF_UNDEF_CODE;
- while (set.next (&fd))
- fdmap.add (fd);
- if (unlikely (fdmap.get_population () != subset_fd_count))
- return false;
- }
-
- /* update each font dict index stored as "code" in fdselect_ranges */
- for (unsigned int i = 0; i < fdselect_ranges.length; i++)
- fdselect_ranges[i].code = fdmap[fdselect_ranges[i].code];
- }
-
- /* determine which FDSelect format is most compact */
- if (subset_fd_count > 0xFF)
- {
- if (unlikely (src.format != 4))
- return false;
- subset_fdselect_format = 4;
- subset_fdselect_size = FDSelect::min_size + FDSelect4::min_size + FDSelect4_Range::static_size * num_ranges + HBUINT32::static_size;
- }
- else
- {
-#if CFF_SERIALIZE_FDSELECT_0
- unsigned int format0_size = FDSelect::min_size + FDSelect0::min_size + HBUINT8::static_size * subset_num_glyphs;
-#endif
- unsigned int format3_size = FDSelect::min_size + FDSelect3::min_size + FDSelect3_Range::static_size * num_ranges + HBUINT16::static_size;
-
-#if CFF_SERIALIZE_FDSELECT_0
- if (format0_size <= format3_size)
- {
- // subset_fdselect_format = 0;
- subset_fdselect_size = format0_size;
- }
- else
-#endif
- {
- subset_fdselect_format = 3;
- subset_fdselect_size = format3_size;
- }
- }
-
- return true;
-}
-
-template <typename FDSELECT3_4>
-static inline bool
-serialize_fdselect_3_4 (hb_serialize_context_t *c,
- const unsigned int num_glyphs,
- const FDSelect &src,
- unsigned int size,
- const hb_vector_t<code_pair_t> &fdselect_ranges)
-{
- TRACE_SERIALIZE (this);
- FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
- if (unlikely (!p)) return_trace (false);
- p->nRanges () = fdselect_ranges.length;
- for (unsigned int i = 0; i < fdselect_ranges.length; i++)
- {
- p->ranges[i].first = fdselect_ranges[i].glyph;
- p->ranges[i].fd = fdselect_ranges[i].code;
- }
- p->sentinel () = num_glyphs;
- return_trace (true);
-}
-
-/* Serialize a subset FDSelect format planned above. */
-bool
-hb_serialize_cff_fdselect (hb_serialize_context_t *c,
- const unsigned int num_glyphs,
- const FDSelect &src,
- unsigned int fd_count,
- unsigned int fdselect_format,
- unsigned int size,
- const hb_vector_t<code_pair_t> &fdselect_ranges)
-{
- TRACE_SERIALIZE (this);
- FDSelect *p = c->allocate_min<FDSelect> ();
- if (unlikely (!p)) return_trace (false);
- p->format = fdselect_format;
- size -= FDSelect::min_size;
-
- switch (fdselect_format)
- {
-#if CFF_SERIALIZE_FDSELECT_0
- case 0:
- {
- FDSelect0 *p = c->allocate_size<FDSelect0> (size);
- if (unlikely (!p)) return_trace (false);
- unsigned int range_index = 0;
- unsigned int fd = fdselect_ranges[range_index++].code;
- for (unsigned int i = 0; i < num_glyphs; i++)
- {
- if ((range_index < fdselect_ranges.len) &&
- (i >= fdselect_ranges[range_index].glyph))
- {
- fd = fdselect_ranges[range_index++].code;
- }
- p->fds[i] = fd;
- }
- return_trace (true);
- }
-#endif /* CFF_SERIALIZE_FDSELECT_0 */
-
- case 3:
- return serialize_fdselect_3_4<FDSelect3> (c, num_glyphs, src,
- size, fdselect_ranges);
-
- case 4:
- return serialize_fdselect_3_4<FDSelect4> (c, num_glyphs, src,
- size, fdselect_ranges);
-
- default:
- return_trace (false);
- }
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh
deleted file mode 100644
index ff50b0e5185..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff-common.hh
+++ /dev/null
@@ -1,1165 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF_COMMON_HH
-#define HB_SUBSET_CFF_COMMON_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-#include "hb-cff-interp-cs-common.hh"
-
-namespace CFF {
-
-/* Used for writing a temporary charstring */
-struct str_encoder_t
-{
- str_encoder_t (str_buff_t &buff_)
- : buff (buff_) {}
-
- void reset () { buff.reset (); }
-
- void encode_byte (unsigned char b)
- {
- if (likely ((signed) buff.length < buff.allocated))
- buff.arrayZ[buff.length++] = b;
- else
- buff.push (b);
- }
-
- void encode_int (int v)
- {
- if ((-1131 <= v) && (v <= 1131))
- {
- if ((-107 <= v) && (v <= 107))
- encode_byte (v + 139);
- else if (v > 0)
- {
- v -= 108;
- encode_byte ((v >> 8) + OpCode_TwoBytePosInt0);
- encode_byte (v & 0xFF);
- }
- else
- {
- v = -v - 108;
- encode_byte ((v >> 8) + OpCode_TwoByteNegInt0);
- encode_byte (v & 0xFF);
- }
- }
- else
- {
- if (unlikely (v < -32768))
- v = -32768;
- else if (unlikely (v > 32767))
- v = 32767;
- encode_byte (OpCode_shortint);
- encode_byte ((v >> 8) & 0xFF);
- encode_byte (v & 0xFF);
- }
- }
-
- // Encode number for CharString
- void encode_num_cs (const number_t& n)
- {
- if (n.in_int_range ())
- {
- encode_int (n.to_int ());
- }
- else
- {
- int32_t v = n.to_fixed ();
- encode_byte (OpCode_fixedcs);
- encode_byte ((v >> 24) & 0xFF);
- encode_byte ((v >> 16) & 0xFF);
- encode_byte ((v >> 8) & 0xFF);
- encode_byte (v & 0xFF);
- }
- }
-
- // Encode number for TopDict / Private
- void encode_num_tp (const number_t& n)
- {
- if (n.in_int_range ())
- {
- // TODO longint
- encode_int (n.to_int ());
- }
- else
- {
- // Sigh. BCD
- // https://learn.microsoft.com/en-us/typography/opentype/spec/cff2#table-5-nibble-definitions
- double v = n.to_real ();
- encode_byte (OpCode_BCD);
-
- // Based on:
- // https://github.com/fonttools/fonttools/blob/97ed3a61cde03e17b8be36f866192fbd56f1d1a7/Lib/fontTools/misc/psCharStrings.py#L265-L294
-
- char buf[16];
- /* FontTools has the following comment:
- *
- * # Note: 14 decimal digits seems to be the limitation for CFF real numbers
- * # in macOS. However, we use 8 here to match the implementation of AFDKO.
- *
- * We use 8 here to match FontTools X-).
- */
-
- hb_locale_t clocale HB_UNUSED;
- hb_locale_t oldlocale HB_UNUSED;
- oldlocale = hb_uselocale (clocale = newlocale (LC_ALL_MASK, "C", NULL));
- snprintf (buf, sizeof (buf), "%.8G", v);
- (void) hb_uselocale (((void) freelocale (clocale), oldlocale));
-
- char *s = buf;
- if (s[0] == '0' && s[1] == '.')
- s++;
- else if (s[0] == '-' && s[1] == '0' && s[2] == '.')
- {
- s[1] = '-';
- s++;
- }
- hb_vector_t<char> nibbles;
- while (*s)
- {
- char c = s[0];
- s++;
-
- switch (c)
- {
- case 'E':
- {
- char c2 = *s;
- if (c2 == '-')
- {
- s++;
- nibbles.push (0x0C); // E-
- continue;
- }
- if (c2 == '+')
- s++;
- nibbles.push (0x0B); // E
- continue;
- }
-
- case '.': case ',': // Comma for some European locales in case no uselocale available.
- nibbles.push (0x0A); // .
- continue;
-
- case '-':
- nibbles.push (0x0E); // .
- continue;
- }
-
- nibbles.push (c - '0');
- }
- nibbles.push (0x0F);
- if (nibbles.length % 2)
- nibbles.push (0x0F);
-
- unsigned count = nibbles.length;
- for (unsigned i = 0; i < count; i += 2)
- encode_byte ((nibbles[i] << 4) | nibbles[i+1]);
- }
- }
-
- void encode_op (op_code_t op)
- {
- if (Is_OpCode_ESC (op))
- {
- encode_byte (OpCode_escape);
- encode_byte (Unmake_OpCode_ESC (op));
- }
- else
- encode_byte (op);
- }
-
- void copy_str (const unsigned char *str, unsigned length)
- {
- assert ((signed) (buff.length + length) <= buff.allocated);
- hb_memcpy (buff.arrayZ + buff.length, str, length);
- buff.length += length;
- }
-
- bool in_error () const { return buff.in_error (); }
-
- protected:
-
- str_buff_t &buff;
-};
-
-struct cff_sub_table_info_t {
- cff_sub_table_info_t ()
- : fd_array_link (0),
- char_strings_link (0)
- {
- fd_select.init ();
- }
-
- table_info_t fd_select;
- objidx_t fd_array_link;
- objidx_t char_strings_link;
-};
-
-template <typename OPSTR=op_str_t>
-struct cff_top_dict_op_serializer_t : op_serializer_t
-{
- bool serialize (hb_serialize_context_t *c,
- const OPSTR &opstr,
- const cff_sub_table_info_t &info) const
- {
- TRACE_SERIALIZE (this);
-
- switch (opstr.op)
- {
- case OpCode_CharStrings:
- return_trace (FontDict::serialize_link4_op(c, opstr.op, info.char_strings_link, whence_t::Absolute));
-
- case OpCode_FDArray:
- return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_array_link, whence_t::Absolute));
-
- case OpCode_FDSelect:
- return_trace (FontDict::serialize_link4_op(c, opstr.op, info.fd_select.link, whence_t::Absolute));
-
- default:
- return_trace (copy_opstr (c, opstr));
- }
- return_trace (true);
- }
-};
-
-struct cff_font_dict_op_serializer_t : op_serializer_t
-{
- bool serialize (hb_serialize_context_t *c,
- const op_str_t &opstr,
- const table_info_t &privateDictInfo) const
- {
- TRACE_SERIALIZE (this);
-
- if (opstr.op == OpCode_Private)
- {
- /* serialize the private dict size & offset as 2-byte & 4-byte integers */
- return_trace (UnsizedByteStr::serialize_int2 (c, privateDictInfo.size) &&
- Dict::serialize_link4_op (c, opstr.op, privateDictInfo.link, whence_t::Absolute));
- }
- else
- {
- unsigned char *d = c->allocate_size<unsigned char> (opstr.length);
- if (unlikely (!d)) return_trace (false);
- /* Faster than hb_memcpy for small strings. */
- for (unsigned i = 0; i < opstr.length; i++)
- d[i] = opstr.ptr[i];
- //hb_memcpy (d, opstr.ptr, opstr.length);
- }
- return_trace (true);
- }
-};
-
-struct flatten_param_t
-{
- str_buff_t &flatStr;
- bool drop_hints;
- const hb_subset_plan_t *plan;
-};
-
-template <typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
-struct subr_flattener_t
-{
- subr_flattener_t (const ACC &acc_,
- const hb_subset_plan_t *plan_)
- : acc (acc_), plan (plan_) {}
-
- bool flatten (str_buff_vec_t &flat_charstrings)
- {
- unsigned count = plan->num_output_glyphs ();
- if (!flat_charstrings.resize_exact (count))
- return false;
- for (unsigned int i = 0; i < count; i++)
- {
- hb_codepoint_t glyph;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- {
- /* add an endchar only charstring for a missing glyph if CFF1 */
- if (endchar_op != OpCode_Invalid) flat_charstrings[i].push (endchar_op);
- continue;
- }
- const hb_ubytes_t str = (*acc.charStrings)[glyph];
- unsigned int fd = acc.fdSelect->get_fd (glyph);
- if (unlikely (fd >= acc.fdCount))
- return false;
-
-
- ENV env (str, acc, fd,
- plan->normalized_coords.arrayZ, plan->normalized_coords.length);
- cs_interpreter_t<ENV, OPSET, flatten_param_t> interp (env);
- flatten_param_t param = {
- flat_charstrings.arrayZ[i],
- (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING),
- plan
- };
- if (unlikely (!interp.interpret (param)))
- return false;
- }
- return true;
- }
-
- const ACC &acc;
- const hb_subset_plan_t *plan;
-};
-
-struct subr_closures_t
-{
- subr_closures_t (unsigned int fd_count) : global_closure (), local_closures ()
- {
- local_closures.resize_exact (fd_count);
- }
-
- void reset ()
- {
- global_closure.clear();
- for (unsigned int i = 0; i < local_closures.length; i++)
- local_closures[i].clear();
- }
-
- bool in_error () const { return local_closures.in_error (); }
- hb_set_t global_closure;
- hb_vector_t<hb_set_t> local_closures;
-};
-
-struct parsed_cs_op_t : op_str_t
-{
- parsed_cs_op_t (unsigned int subr_num_ = 0) :
- subr_num (subr_num_) {}
-
- bool is_hinting () const { return hinting_flag; }
- void set_hinting () { hinting_flag = true; }
-
- /* The layout of this struct is designed to fit within the
- * padding of op_str_t! */
-
- protected:
- bool hinting_flag = false;
-
- public:
- uint16_t subr_num;
-};
-
-struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t>
-{
- parsed_cs_str_t () :
- parsed (false),
- hint_dropped (false),
- has_prefix_ (false),
- has_calls_ (false)
- {
- SUPER::init ();
- }
-
- void add_op (op_code_t op, const byte_str_ref_t& str_ref)
- {
- if (!is_parsed ())
- SUPER::add_op (op, str_ref);
- }
-
- void add_call_op (op_code_t op, const byte_str_ref_t& str_ref, unsigned int subr_num)
- {
- if (!is_parsed ())
- {
- has_calls_ = true;
-
- /* Pop the subroutine number. */
- values.pop ();
-
- SUPER::add_op (op, str_ref, {subr_num});
- }
- }
-
- void set_prefix (const number_t &num, op_code_t op = OpCode_Invalid)
- {
- has_prefix_ = true;
- prefix_op_ = op;
- prefix_num_ = num;
- }
-
- bool at_end (unsigned int pos) const
- {
- return ((pos + 1 >= values.length) /* CFF2 */
- || (values[pos + 1].op == OpCode_return));
- }
-
- bool is_parsed () const { return parsed; }
- void set_parsed () { parsed = true; }
-
- bool is_hint_dropped () const { return hint_dropped; }
- void set_hint_dropped () { hint_dropped = true; }
-
- bool is_vsindex_dropped () const { return vsindex_dropped; }
- void set_vsindex_dropped () { vsindex_dropped = true; }
-
- bool has_prefix () const { return has_prefix_; }
- op_code_t prefix_op () const { return prefix_op_; }
- const number_t &prefix_num () const { return prefix_num_; }
-
- bool has_calls () const { return has_calls_; }
-
- void compact ()
- {
- unsigned count = values.length;
- if (!count) return;
- auto &opstr = values.arrayZ;
- unsigned j = 0;
- for (unsigned i = 1; i < count; i++)
- {
- /* See if we can combine op j and op i. */
- bool combine =
- (opstr[j].op != OpCode_callsubr && opstr[j].op != OpCode_callgsubr) &&
- (opstr[i].op != OpCode_callsubr && opstr[i].op != OpCode_callgsubr) &&
- (opstr[j].is_hinting () == opstr[i].is_hinting ()) &&
- (opstr[j].ptr + opstr[j].length == opstr[i].ptr) &&
- (opstr[j].length + opstr[i].length <= 255);
-
- if (combine)
- {
- opstr[j].length += opstr[i].length;
- opstr[j].op = OpCode_Invalid;
- }
- else
- {
- opstr[++j] = opstr[i];
- }
- }
- values.shrink (j + 1);
- }
-
- protected:
- bool parsed : 1;
- bool hint_dropped : 1;
- bool vsindex_dropped : 1;
- bool has_prefix_ : 1;
- bool has_calls_ : 1;
- op_code_t prefix_op_;
- number_t prefix_num_;
-
- private:
- typedef parsed_values_t<parsed_cs_op_t> SUPER;
-};
-
-struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t>
-{
- private:
- typedef hb_vector_t<parsed_cs_str_t> SUPER;
-};
-
-struct cff_subset_accelerator_t
-{
- static cff_subset_accelerator_t* create (
- hb_blob_t* original_blob,
- const parsed_cs_str_vec_t& parsed_charstrings,
- const parsed_cs_str_vec_t& parsed_global_subrs,
- const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) {
- cff_subset_accelerator_t* accel =
- (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t));
- new (accel) cff_subset_accelerator_t (original_blob,
- parsed_charstrings,
- parsed_global_subrs,
- parsed_local_subrs);
- return accel;
- }
-
- static void destroy (void* value) {
- if (!value) return;
-
- cff_subset_accelerator_t* accel = (cff_subset_accelerator_t*) value;
- accel->~cff_subset_accelerator_t ();
- hb_free (accel);
- }
-
- cff_subset_accelerator_t(
- hb_blob_t* original_blob_,
- const parsed_cs_str_vec_t& parsed_charstrings_,
- const parsed_cs_str_vec_t& parsed_global_subrs_,
- const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs_)
- {
- parsed_charstrings = parsed_charstrings_;
- parsed_global_subrs = parsed_global_subrs_;
- parsed_local_subrs = parsed_local_subrs_;
-
- // the parsed charstrings point to memory in the original CFF table so we must hold a reference
- // to it to keep the memory valid.
- original_blob = hb_blob_reference (original_blob_);
- }
-
- ~cff_subset_accelerator_t() {
- hb_blob_destroy (original_blob);
- hb_map_destroy (glyph_to_sid_map.get_relaxed ());
- }
-
- parsed_cs_str_vec_t parsed_charstrings;
- parsed_cs_str_vec_t parsed_global_subrs;
- hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
- mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr;
-
- private:
- hb_blob_t* original_blob;
-};
-
-struct subr_subset_param_t
-{
- subr_subset_param_t (parsed_cs_str_t *parsed_charstring_,
- parsed_cs_str_vec_t *parsed_global_subrs_,
- parsed_cs_str_vec_t *parsed_local_subrs_,
- hb_set_t *global_closure_,
- hb_set_t *local_closure_,
- bool drop_hints_) :
- current_parsed_str (parsed_charstring_),
- parsed_charstring (parsed_charstring_),
- parsed_global_subrs (parsed_global_subrs_),
- parsed_local_subrs (parsed_local_subrs_),
- global_closure (global_closure_),
- local_closure (local_closure_),
- drop_hints (drop_hints_) {}
-
- parsed_cs_str_t *get_parsed_str_for_context (call_context_t &context)
- {
- switch (context.type)
- {
- case CSType_CharString:
- return parsed_charstring;
-
- case CSType_LocalSubr:
- if (likely (context.subr_num < parsed_local_subrs->length))
- return &(*parsed_local_subrs)[context.subr_num];
- break;
-
- case CSType_GlobalSubr:
- if (likely (context.subr_num < parsed_global_subrs->length))
- return &(*parsed_global_subrs)[context.subr_num];
- break;
- }
- return nullptr;
- }
-
- template <typename ENV>
- void set_current_str (ENV &env, bool calling)
- {
- parsed_cs_str_t *parsed_str = get_parsed_str_for_context (env.context);
- if (unlikely (!parsed_str))
- {
- env.set_error ();
- return;
- }
- /* If the called subroutine is parsed partially but not completely yet,
- * it must be because we are calling it recursively.
- * Handle it as an error. */
- if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.length > 0)))
- env.set_error ();
- else
- {
- if (!parsed_str->is_parsed ())
- parsed_str->alloc (env.str_ref.total_size ());
- current_parsed_str = parsed_str;
- }
- }
-
- parsed_cs_str_t *current_parsed_str;
-
- parsed_cs_str_t *parsed_charstring;
- parsed_cs_str_vec_t *parsed_global_subrs;
- parsed_cs_str_vec_t *parsed_local_subrs;
- hb_set_t *global_closure;
- hb_set_t *local_closure;
- bool drop_hints;
-};
-
-struct subr_remap_t : hb_inc_bimap_t
-{
- void create (const hb_set_t *closure)
- {
- /* create a remapping of subroutine numbers from old to new.
- * no optimization based on usage counts. fonttools doesn't appear doing that either.
- */
-
- resize (closure->get_population ());
- hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
- while (hb_set_next (closure, &old_num))
- add (old_num);
-
- if (get_population () < 1240)
- bias = 107;
- else if (get_population () < 33900)
- bias = 1131;
- else
- bias = 32768;
- }
-
- int biased_num (unsigned int old_num) const
- {
- hb_codepoint_t new_num = get (old_num);
- return (int)new_num - bias;
- }
-
- protected:
- int bias;
-};
-
-struct subr_remaps_t
-{
- subr_remaps_t (unsigned int fdCount)
- {
- local_remaps.resize (fdCount);
- }
-
- bool in_error()
- {
- return local_remaps.in_error ();
- }
-
- void create (subr_closures_t& closures)
- {
- global_remap.create (&closures.global_closure);
- for (unsigned int i = 0; i < local_remaps.length; i++)
- local_remaps.arrayZ[i].create (&closures.local_closures[i]);
- }
-
- subr_remap_t global_remap;
- hb_vector_t<subr_remap_t> local_remaps;
-};
-
-template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typename OPSET, op_code_t endchar_op=OpCode_Invalid>
-struct subr_subsetter_t
-{
- subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
- : acc (acc_), plan (plan_), closures(acc_.fdCount),
- remaps(acc_.fdCount)
- {}
-
- /* Subroutine subsetting with --no-desubroutinize runs in phases:
- *
- * 1. execute charstrings/subroutines to determine subroutine closures
- * 2. parse out all operators and numbers
- * 3. mark hint operators and operands for removal if --no-hinting
- * 4. re-encode all charstrings and subroutines with new subroutine numbers
- *
- * Phases #1 and #2 are done at the same time in collect_subrs ().
- * Phase #3 walks charstrings/subroutines forward then backward (hence parsing required),
- * because we can't tell if a number belongs to a hint op until we see the first moveto.
- *
- * Assumption: a callsubr/callgsubr operator must immediately follow a (biased) subroutine number
- * within the same charstring/subroutine, e.g., not split across a charstring and a subroutine.
- */
- bool subset (void)
- {
- unsigned fd_count = acc.fdCount;
- const cff_subset_accelerator_t* cff_accelerator = nullptr;
- if (plan->accelerator && plan->accelerator->cff_accelerator) {
- cff_accelerator = plan->accelerator->cff_accelerator;
- fd_count = cff_accelerator->parsed_local_subrs.length;
- }
-
- if (cff_accelerator) {
- // If we are not dropping hinting then charstrings are not modified so we can
- // just use a reference to the cached copies.
- cached_charstrings.resize_exact (plan->num_output_glyphs ());
- parsed_global_subrs = &cff_accelerator->parsed_global_subrs;
- parsed_local_subrs = &cff_accelerator->parsed_local_subrs;
- } else {
- parsed_charstrings.resize_exact (plan->num_output_glyphs ());
- parsed_global_subrs_storage.resize_exact (acc.globalSubrs->count);
-
- if (unlikely (!parsed_local_subrs_storage.resize (fd_count))) return false;
-
- for (unsigned int i = 0; i < acc.fdCount; i++)
- {
- unsigned count = acc.privateDicts[i].localSubrs->count;
- parsed_local_subrs_storage[i].resize (count);
- if (unlikely (parsed_local_subrs_storage[i].in_error ())) return false;
- }
-
- parsed_global_subrs = &parsed_global_subrs_storage;
- parsed_local_subrs = &parsed_local_subrs_storage;
- }
-
- if (unlikely (remaps.in_error()
- || cached_charstrings.in_error ()
- || parsed_charstrings.in_error ()
- || parsed_global_subrs->in_error ()
- || closures.in_error ())) {
- return false;
- }
-
- /* phase 1 & 2 */
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
- {
- hb_codepoint_t glyph;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- continue;
-
- const hb_ubytes_t str = (*acc.charStrings)[glyph];
- unsigned int fd = acc.fdSelect->get_fd (glyph);
- if (unlikely (fd >= acc.fdCount))
- return false;
-
- if (cff_accelerator)
- {
- // parsed string already exists in accelerator, copy it and move
- // on.
- if (cached_charstrings)
- cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph];
- else
- parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph];
-
- continue;
- }
-
- ENV env (str, acc, fd);
- cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env);
-
- parsed_charstrings[i].alloc (str.length);
- subr_subset_param_t param (&parsed_charstrings[i],
- &parsed_global_subrs_storage,
- &parsed_local_subrs_storage[fd],
- &closures.global_closure,
- &closures.local_closures[fd],
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-
- if (unlikely (!interp.interpret (param)))
- return false;
-
- /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
- SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
-
- /* mark hint ops and arguments for drop */
- if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING) || plan->inprogress_accelerator)
- {
- subr_subset_param_t param (&parsed_charstrings[i],
- &parsed_global_subrs_storage,
- &parsed_local_subrs_storage[fd],
- &closures.global_closure,
- &closures.local_closures[fd],
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-
- drop_hints_param_t drop;
- if (drop_hints_in_str (parsed_charstrings[i], param, drop))
- {
- parsed_charstrings[i].set_hint_dropped ();
- if (drop.vsindex_dropped)
- parsed_charstrings[i].set_vsindex_dropped ();
- }
- }
-
- /* Doing this here one by one instead of compacting all at the en
- * has massive peak-memory saving.
- *
- * The compacting both saves memory and makes further operations
- * faster.
- */
- parsed_charstrings[i].compact ();
- }
-
- /* Since parsed strings were loaded from accelerator, we still need
- * to compute the subroutine closures which would have normally happened during
- * parsing.
- *
- * Or if we are dropping hinting, redo closure to get actually used subrs.
- */
- if ((cff_accelerator ||
- (!cff_accelerator && plan->flags & HB_SUBSET_FLAGS_NO_HINTING)) &&
- !closure_subroutines(*parsed_global_subrs,
- *parsed_local_subrs))
- return false;
-
- remaps.create (closures);
-
- populate_subset_accelerator ();
- return true;
- }
-
- bool encode_charstrings (str_buff_vec_t &buffArray, bool encode_prefix = true) const
- {
- if (unlikely (!buffArray.resize_exact (plan->num_output_glyphs ())))
- return false;
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
- {
- hb_codepoint_t glyph;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- {
- /* add an endchar only charstring for a missing glyph if CFF1 */
- if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op);
- continue;
- }
- unsigned int fd = acc.fdSelect->get_fd (glyph);
- if (unlikely (fd >= acc.fdCount))
- return false;
- if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i], encode_prefix)))
- return false;
- }
- return true;
- }
-
- bool encode_subrs (const parsed_cs_str_vec_t &subrs, const subr_remap_t& remap, unsigned int fd, str_buff_vec_t &buffArray) const
- {
- unsigned int count = remap.get_population ();
-
- if (unlikely (!buffArray.resize_exact (count)))
- return false;
- for (unsigned int new_num = 0; new_num < count; new_num++)
- {
- hb_codepoint_t old_num = remap.backward (new_num);
- assert (old_num != CFF_UNDEF_CODE);
-
- if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
- return false;
- }
- return true;
- }
-
- bool encode_globalsubrs (str_buff_vec_t &buffArray)
- {
- return encode_subrs (*parsed_global_subrs, remaps.global_remap, 0, buffArray);
- }
-
- bool encode_localsubrs (unsigned int fd, str_buff_vec_t &buffArray) const
- {
- return encode_subrs ((*parsed_local_subrs)[fd], remaps.local_remaps[fd], fd, buffArray);
- }
-
- protected:
- struct drop_hints_param_t
- {
- drop_hints_param_t ()
- : seen_moveto (false),
- ends_in_hint (false),
- all_dropped (false),
- vsindex_dropped (false) {}
-
- bool seen_moveto;
- bool ends_in_hint;
- bool all_dropped;
- bool vsindex_dropped;
- };
-
- bool drop_hints_in_subr (parsed_cs_str_t &str, unsigned int pos,
- parsed_cs_str_vec_t &subrs, unsigned int subr_num,
- const subr_subset_param_t &param, drop_hints_param_t &drop)
- {
- drop.ends_in_hint = false;
- bool has_hint = drop_hints_in_str (subrs[subr_num], param, drop);
-
- /* if this subr ends with a stem hint (i.e., not a number; potential argument for moveto),
- * then this entire subroutine must be a hint. drop its call. */
- if (drop.ends_in_hint)
- {
- str.values[pos].set_hinting ();
- /* if this subr call is at the end of the parent subr, propagate the flag
- * otherwise reset the flag */
- if (!str.at_end (pos))
- drop.ends_in_hint = false;
- }
- else if (drop.all_dropped)
- {
- str.values[pos].set_hinting ();
- }
-
- return has_hint;
- }
-
- /* returns true if it sees a hint op before the first moveto */
- bool drop_hints_in_str (parsed_cs_str_t &str, const subr_subset_param_t &param, drop_hints_param_t &drop)
- {
- bool seen_hint = false;
-
- unsigned count = str.values.length;
- auto *values = str.values.arrayZ;
- for (unsigned int pos = 0; pos < count; pos++)
- {
- bool has_hint = false;
- switch (values[pos].op)
- {
- case OpCode_callsubr:
- has_hint = drop_hints_in_subr (str, pos,
- *param.parsed_local_subrs, values[pos].subr_num,
- param, drop);
- break;
-
- case OpCode_callgsubr:
- has_hint = drop_hints_in_subr (str, pos,
- *param.parsed_global_subrs, values[pos].subr_num,
- param, drop);
- break;
-
- case OpCode_rmoveto:
- case OpCode_hmoveto:
- case OpCode_vmoveto:
- drop.seen_moveto = true;
- break;
-
- case OpCode_hintmask:
- case OpCode_cntrmask:
- if (drop.seen_moveto)
- {
- values[pos].set_hinting ();
- break;
- }
- HB_FALLTHROUGH;
-
- case OpCode_hstemhm:
- case OpCode_vstemhm:
- case OpCode_hstem:
- case OpCode_vstem:
- has_hint = true;
- values[pos].set_hinting ();
- if (str.at_end (pos))
- drop.ends_in_hint = true;
- break;
-
- case OpCode_dotsection:
- values[pos].set_hinting ();
- break;
-
- default:
- /* NONE */
- break;
- }
- if (has_hint)
- {
- for (int i = pos - 1; i >= 0; i--)
- {
- parsed_cs_op_t &csop = values[(unsigned)i];
- if (csop.is_hinting ())
- break;
- csop.set_hinting ();
- if (csop.op == OpCode_vsindexcs)
- drop.vsindex_dropped = true;
- }
- seen_hint |= has_hint;
- }
- }
-
- /* Raise all_dropped flag if all operators except return are dropped from a subr.
- * It may happen even after seeing the first moveto if a subr contains
- * only (usually one) hintmask operator, then calls to this subr can be dropped.
- */
- drop.all_dropped = true;
- for (unsigned int pos = 0; pos < count; pos++)
- {
- parsed_cs_op_t &csop = values[pos];
- if (csop.op == OpCode_return)
- break;
- if (!csop.is_hinting ())
- {
- drop.all_dropped = false;
- break;
- }
- }
-
- return seen_hint;
- }
-
- bool closure_subroutines (const parsed_cs_str_vec_t& global_subrs,
- const hb_vector_t<parsed_cs_str_vec_t>& local_subrs)
- {
- closures.reset ();
- for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
- {
- hb_codepoint_t glyph;
- if (!plan->old_gid_for_new_gid (i, &glyph))
- continue;
- unsigned int fd = acc.fdSelect->get_fd (glyph);
- if (unlikely (fd >= acc.fdCount))
- return false;
-
- // Note: const cast is safe here because the collect_subr_refs_in_str only performs a
- // closure and does not modify any of the charstrings.
- subr_subset_param_t param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)),
- const_cast<parsed_cs_str_vec_t*> (&global_subrs),
- const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]),
- &closures.global_closure,
- &closures.local_closures[fd],
- plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
- collect_subr_refs_in_str (get_parsed_charstring (i), param);
- }
-
- return true;
- }
-
- void collect_subr_refs_in_subr (unsigned int subr_num, parsed_cs_str_vec_t &subrs,
- hb_set_t *closure,
- const subr_subset_param_t &param)
- {
- if (closure->has (subr_num))
- return;
- closure->add (subr_num);
- collect_subr_refs_in_str (subrs[subr_num], param);
- }
-
- void collect_subr_refs_in_str (const parsed_cs_str_t &str,
- const subr_subset_param_t &param)
- {
- if (!str.has_calls ())
- return;
-
- for (auto &opstr : str.values)
- {
- if (!param.drop_hints || !opstr.is_hinting ())
- {
- switch (opstr.op)
- {
- case OpCode_callsubr:
- collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_local_subrs,
- param.local_closure, param);
- break;
-
- case OpCode_callgsubr:
- collect_subr_refs_in_subr (opstr.subr_num, *param.parsed_global_subrs,
- param.global_closure, param);
- break;
-
- default: break;
- }
- }
- }
- }
-
- bool encode_str (const parsed_cs_str_t &str, const unsigned int fd, str_buff_t &buff, bool encode_prefix = true) const
- {
- str_encoder_t encoder (buff);
- encoder.reset ();
- bool hinting = !(plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
- /* if a prefix (CFF1 width or CFF2 vsindex) has been removed along with hints,
- * re-insert it at the beginning of charstreing */
- if (encode_prefix && str.has_prefix () && !hinting && str.is_hint_dropped ())
- {
- encoder.encode_num_cs (str.prefix_num ());
- if (str.prefix_op () != OpCode_Invalid)
- encoder.encode_op (str.prefix_op ());
- }
-
- unsigned size = 0;
- for (auto &opstr : str.values)
- {
- size += opstr.length;
- if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr)
- size += 3;
- }
- if (!buff.alloc (buff.length + size, true))
- return false;
-
- for (auto &opstr : str.values)
- {
- if (hinting || !opstr.is_hinting ())
- {
- switch (opstr.op)
- {
- case OpCode_callsubr:
- encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num));
- encoder.copy_str (opstr.ptr, opstr.length);
- break;
-
- case OpCode_callgsubr:
- encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num));
- encoder.copy_str (opstr.ptr, opstr.length);
- break;
-
- default:
- encoder.copy_str (opstr.ptr, opstr.length);
- break;
- }
- }
- }
- return !encoder.in_error ();
- }
-
- void compact_parsed_subrs () const
- {
- for (auto &cs : parsed_global_subrs_storage)
- cs.compact ();
- for (auto &vec : parsed_local_subrs_storage)
- for (auto &cs : vec)
- cs.compact ();
- }
-
- void populate_subset_accelerator () const
- {
- if (!plan->inprogress_accelerator) return;
-
- compact_parsed_subrs ();
-
- plan->inprogress_accelerator->cff_accelerator =
- cff_subset_accelerator_t::create(acc.blob,
- parsed_charstrings,
- parsed_global_subrs_storage,
- parsed_local_subrs_storage);
- plan->inprogress_accelerator->destroy_cff_accelerator =
- cff_subset_accelerator_t::destroy;
-
- }
-
- const parsed_cs_str_t& get_parsed_charstring (unsigned i) const
- {
- if (cached_charstrings) return *(cached_charstrings[i]);
- return parsed_charstrings[i];
- }
-
- protected:
- const ACC &acc;
- const hb_subset_plan_t *plan;
-
- subr_closures_t closures;
-
- hb_vector_t<const parsed_cs_str_t*> cached_charstrings;
- const parsed_cs_str_vec_t* parsed_global_subrs;
- const hb_vector_t<parsed_cs_str_vec_t>* parsed_local_subrs;
-
- subr_remaps_t remaps;
-
- private:
-
- parsed_cs_str_vec_t parsed_charstrings;
- parsed_cs_str_vec_t parsed_global_subrs_storage;
- hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs_storage;
- typedef typename SUBRS::count_type subr_count_type;
-};
-
-} /* namespace CFF */
-
-HB_INTERNAL bool
-hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
- unsigned int fdCount,
- const CFF::FDSelect &src, /* IN */
- unsigned int &subset_fd_count /* OUT */,
- unsigned int &subset_fdselect_size /* OUT */,
- unsigned int &subset_fdselect_format /* OUT */,
- hb_vector_t<CFF::code_pair_t> &fdselect_ranges /* OUT */,
- hb_inc_bimap_t &fdmap /* OUT */);
-
-HB_INTERNAL bool
-hb_serialize_cff_fdselect (hb_serialize_context_t *c,
- unsigned int num_glyphs,
- const CFF::FDSelect &src,
- unsigned int fd_count,
- unsigned int fdselect_format,
- unsigned int size,
- const hb_vector_t<CFF::code_pair_t> &fdselect_ranges);
-
-#endif /* HB_SUBSET_CFF_COMMON_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc
deleted file mode 100644
index 1d7ed6444ac..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.cc
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_SUBSET_CFF
-
-#include "hb-open-type.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-set.h"
-#include "hb-bimap.hh"
-#include "hb-subset-cff1.hh"
-#include "hb-subset-plan.hh"
-#include "hb-subset-cff-common.hh"
-#include "hb-cff1-interp-cs.hh"
-
-using namespace CFF;
-
-struct remap_sid_t : hb_inc_bimap_t
-{
- unsigned int add (unsigned int sid)
- {
- if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
- return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
- else
- return sid;
- }
-
- unsigned int operator[] (unsigned int sid) const
- {
- if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
- return sid;
- else
- return offset_sid (get (unoffset_sid (sid)));
- }
-
- static const unsigned int num_std_strings = 391;
-
- static bool is_std_std (unsigned int sid) { return sid < num_std_strings; }
- static unsigned int offset_sid (unsigned int sid) { return sid + num_std_strings; }
- static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; }
-};
-
-struct cff1_sub_table_info_t : cff_sub_table_info_t
-{
- cff1_sub_table_info_t ()
- : cff_sub_table_info_t (),
- encoding_link (0),
- charset_link (0)
- {
- privateDictInfo.init ();
- }
-
- objidx_t encoding_link;
- objidx_t charset_link;
- table_info_t privateDictInfo;
-};
-
-/* a copy of a parsed out cff1_top_dict_values_t augmented with additional operators */
-struct cff1_top_dict_values_mod_t : cff1_top_dict_values_t
-{
- void init (const cff1_top_dict_values_t *base_= &Null (cff1_top_dict_values_t))
- {
- SUPER::init ();
- base = base_;
- }
-
- void fini () { SUPER::fini (); }
-
- unsigned get_count () const { return base->get_count () + SUPER::get_count (); }
- const cff1_top_dict_val_t &get_value (unsigned int i) const
- {
- if (i < base->get_count ())
- return (*base)[i];
- else
- return SUPER::values[i - base->get_count ()];
- }
- const cff1_top_dict_val_t &operator [] (unsigned int i) const { return get_value (i); }
-
- void reassignSIDs (const remap_sid_t& sidmap)
- {
- for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
- nameSIDs[i] = sidmap[base->nameSIDs[i]];
- }
-
- protected:
- typedef cff1_top_dict_values_t SUPER;
- const cff1_top_dict_values_t *base;
-};
-
-struct top_dict_modifiers_t
-{
- top_dict_modifiers_t (const cff1_sub_table_info_t &info_,
- const unsigned int (&nameSIDs_)[name_dict_values_t::ValCount])
- : info (info_),
- nameSIDs (nameSIDs_)
- {}
-
- const cff1_sub_table_info_t &info;
- const unsigned int (&nameSIDs)[name_dict_values_t::ValCount];
-};
-
-struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dict_val_t>
-{
- bool serialize (hb_serialize_context_t *c,
- const cff1_top_dict_val_t &opstr,
- const top_dict_modifiers_t &mod) const
- {
- TRACE_SERIALIZE (this);
-
- op_code_t op = opstr.op;
- switch (op)
- {
- case OpCode_charset:
- if (mod.info.charset_link)
- return_trace (FontDict::serialize_link4_op(c, op, mod.info.charset_link, whence_t::Absolute));
- else
- goto fall_back;
-
- case OpCode_Encoding:
- if (mod.info.encoding_link)
- return_trace (FontDict::serialize_link4_op(c, op, mod.info.encoding_link, whence_t::Absolute));
- else
- goto fall_back;
-
- case OpCode_Private:
- return_trace (UnsizedByteStr::serialize_int2 (c, mod.info.privateDictInfo.size) &&
- Dict::serialize_link4_op (c, op, mod.info.privateDictInfo.link, whence_t::Absolute));
-
- case OpCode_version:
- case OpCode_Notice:
- case OpCode_Copyright:
- case OpCode_FullName:
- case OpCode_FamilyName:
- case OpCode_Weight:
- case OpCode_PostScript:
- case OpCode_BaseFontName:
- case OpCode_FontName:
- return_trace (FontDict::serialize_int2_op (c, op, mod.nameSIDs[name_dict_values_t::name_op_to_index (op)]));
-
- case OpCode_ROS:
- {
- /* for registry & ordering, reassigned SIDs are serialized
- * for supplement, the original byte string is copied along with the op code */
- op_str_t supp_op;
- supp_op.op = op;
- if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3)))
- return_trace (false);
- supp_op.ptr = opstr.ptr + opstr.last_arg_offset;
- supp_op.length = opstr.length - opstr.last_arg_offset;
- return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) &&
- UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
- copy_opstr (c, supp_op));
- }
- fall_back:
- default:
- return_trace (cff_top_dict_op_serializer_t<cff1_top_dict_val_t>::serialize (c, opstr, mod.info));
- }
- return_trace (true);
- }
-
-};
-
-struct cff1_font_dict_op_serializer_t : cff_font_dict_op_serializer_t
-{
- bool serialize (hb_serialize_context_t *c,
- const op_str_t &opstr,
- const cff1_font_dict_values_mod_t &mod) const
- {
- TRACE_SERIALIZE (this);
-
- if (opstr.op == OpCode_FontName)
- return_trace (FontDict::serialize_int2_op (c, opstr.op, mod.fontName));
- else
- return_trace (SUPER::serialize (c, opstr, mod.privateDictInfo));
- }
-
- private:
- typedef cff_font_dict_op_serializer_t SUPER;
-};
-
-struct cff1_cs_opset_flatten_t : cff1_cs_opset_t<cff1_cs_opset_flatten_t, flatten_param_t>
-{
- static void flush_args_and_op (op_code_t op, cff1_cs_interp_env_t &env, flatten_param_t& param)
- {
- if (env.arg_start > 0)
- flush_width (env, param);
-
- switch (op)
- {
- case OpCode_hstem:
- case OpCode_hstemhm:
- case OpCode_vstem:
- case OpCode_vstemhm:
- case OpCode_hintmask:
- case OpCode_cntrmask:
- case OpCode_dotsection:
- if (param.drop_hints)
- {
- env.clear_args ();
- return;
- }
- HB_FALLTHROUGH;
-
- default:
- SUPER::flush_args_and_op (op, env, param);
- break;
- }
- }
- static void flush_args (cff1_cs_interp_env_t &env, flatten_param_t& param)
- {
- str_encoder_t encoder (param.flatStr);
- for (unsigned int i = env.arg_start; i < env.argStack.get_count (); i++)
- encoder.encode_num_cs (env.eval_arg (i));
- SUPER::flush_args (env, param);
- }
-
- static void flush_op (op_code_t op, cff1_cs_interp_env_t &env, flatten_param_t& param)
- {
- str_encoder_t encoder (param.flatStr);
- encoder.encode_op (op);
- }
-
- static void flush_width (cff1_cs_interp_env_t &env, flatten_param_t& param)
- {
- assert (env.has_width);
- str_encoder_t encoder (param.flatStr);
- encoder.encode_num_cs (env.width);
- }
-
- static void flush_hintmask (op_code_t op, cff1_cs_interp_env_t &env, flatten_param_t& param)
- {
- SUPER::flush_hintmask (op, env, param);
- if (!param.drop_hints)
- {
- str_encoder_t encoder (param.flatStr);
- for (unsigned int i = 0; i < env.hintmask_size; i++)
- encoder.encode_byte (env.str_ref[i]);
- }
- }
-
- private:
- typedef cff1_cs_opset_t<cff1_cs_opset_flatten_t, flatten_param_t> SUPER;
-};
-
-struct range_list_t : hb_vector_t<code_pair_t>
-{
- /* replace the first glyph ID in the "glyph" field each range with a nLeft value */
- bool complete (unsigned int last_glyph)
- {
- bool two_byte = false;
- unsigned count = this->length;
- for (unsigned int i = count; i; i--)
- {
- code_pair_t &pair = arrayZ[i - 1];
- unsigned int nLeft = last_glyph - pair.glyph - 1;
- two_byte |= nLeft >= 0x100;
- last_glyph = pair.glyph;
- pair.glyph = nLeft;
- }
- return two_byte;
- }
-};
-
-struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t, subr_subset_param_t>
-{
- static void process_op (op_code_t op, cff1_cs_interp_env_t &env, subr_subset_param_t& param)
- {
- switch (op) {
-
- case OpCode_return:
- param.current_parsed_str->add_op (op, env.str_ref);
- param.current_parsed_str->set_parsed ();
- env.return_from_subr ();
- param.set_current_str (env, false);
- break;
-
- case OpCode_endchar:
- param.current_parsed_str->add_op (op, env.str_ref);
- param.current_parsed_str->set_parsed ();
- SUPER::process_op (op, env, param);
- break;
-
- case OpCode_callsubr:
- process_call_subr (op, CSType_LocalSubr, env, param, env.localSubrs, param.local_closure);
- break;
-
- case OpCode_callgsubr:
- process_call_subr (op, CSType_GlobalSubr, env, param, env.globalSubrs, param.global_closure);
- break;
-
- default:
- SUPER::process_op (op, env, param);
- param.current_parsed_str->add_op (op, env.str_ref);
- break;
- }
- }
-
- protected:
- static void process_call_subr (op_code_t op, cs_type_t type,
- cff1_cs_interp_env_t &env, subr_subset_param_t& param,
- cff1_biased_subrs_t& subrs, hb_set_t *closure)
- {
- byte_str_ref_t str_ref = env.str_ref;
- env.call_subr (subrs, type);
- param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
- closure->add (env.context.subr_num);
- param.set_current_str (env, true);
- }
-
- private:
- typedef cff1_cs_opset_t<cff1_cs_opset_subr_subset_t, subr_subset_param_t> SUPER;
-};
-
-struct cff1_private_dict_op_serializer_t : op_serializer_t
-{
- cff1_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_)
- : desubroutinize (desubroutinize_), drop_hints (drop_hints_) {}
-
- bool serialize (hb_serialize_context_t *c,
- const op_str_t &opstr,
- objidx_t subrs_link) const
- {
- TRACE_SERIALIZE (this);
-
- if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
- return_trace (true);
-
- if (opstr.op == OpCode_Subrs)
- {
- if (desubroutinize || !subrs_link)
- return_trace (true);
- else
- return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
- }
-
- return_trace (copy_opstr (c, opstr));
- }
-
- protected:
- const bool desubroutinize;
- const bool drop_hints;
-};
-
-struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar>
-{
- cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
- : subr_subsetter_t (acc_, plan_) {}
-
- static void complete_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
- {
- /* insert width at the beginning of the charstring as necessary */
- if (env.has_width)
- charstring.set_prefix (env.width);
-
- /* subroutines/charstring left on the call stack are legally left unmarked
- * unmarked when a subroutine terminates with endchar. mark them.
- */
- param.current_parsed_str->set_parsed ();
- for (unsigned int i = 0; i < env.callStack.get_count (); i++)
- {
- parsed_cs_str_t *parsed_str = param.get_parsed_str_for_context (env.callStack[i]);
- if (likely (parsed_str))
- parsed_str->set_parsed ();
- else
- env.set_error ();
- }
- }
-};
-
-struct cff_subset_plan {
- cff_subset_plan ()
- {
- for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
- topDictModSIDs[i] = CFF_UNDEF_SID;
- }
-
- void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
- {
- const Encoding *encoding = acc.encoding;
- unsigned int size0, size1;
- hb_codepoint_t code, last_code = CFF_UNDEF_CODE;
- hb_vector_t<hb_codepoint_t> supp_codes;
-
- if (unlikely (!subset_enc_code_ranges.resize (0)))
- {
- plan->check_success (false);
- return;
- }
-
- supp_codes.init ();
-
- subset_enc_num_codes = plan->num_output_glyphs () - 1;
- unsigned int glyph;
- for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
- {
- hb_codepoint_t old_glyph;
- if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
- {
- /* Retain the code for the old missing glyph ID */
- old_glyph = glyph;
- }
- code = acc.glyph_to_code (old_glyph);
- if (code == CFF_UNDEF_CODE)
- {
- subset_enc_num_codes = glyph - 1;
- break;
- }
-
- if ((last_code == CFF_UNDEF_CODE) || (code != last_code + 1))
- {
- code_pair_t pair = { code, glyph };
- subset_enc_code_ranges.push (pair);
- }
- last_code = code;
-
- if (encoding != &Null (Encoding))
- {
- hb_codepoint_t sid = acc.glyph_to_sid (old_glyph);
- encoding->get_supplement_codes (sid, supp_codes);
- for (unsigned int i = 0; i < supp_codes.length; i++)
- {
- code_pair_t pair = { supp_codes[i], sid };
- subset_enc_supp_codes.push (pair);
- }
- }
- }
- supp_codes.fini ();
-
- subset_enc_code_ranges.complete (glyph);
-
- assert (subset_enc_num_codes <= 0xFF);
- size0 = Encoding0::min_size + HBUINT8::static_size * subset_enc_num_codes;
- size1 = Encoding1::min_size + Encoding1_Range::static_size * subset_enc_code_ranges.length;
-
- if (size0 < size1)
- subset_enc_format = 0;
- else
- subset_enc_format = 1;
- }
-
- void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
- {
- unsigned int size0, size_ranges;
- hb_codepoint_t sid, last_sid = CFF_UNDEF_CODE;
-
- if (unlikely (!subset_charset_ranges.resize (0)))
- {
- plan->check_success (false);
- return;
- }
-
- hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ?
- plan->accelerator->cff_accelerator->glyph_to_sid_map :
- nullptr;
- bool created_map = false;
- if (!glyph_to_sid_map &&
- ((plan->accelerator && plan->accelerator->cff_accelerator) ||
- plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
- {
- created_map = true;
- glyph_to_sid_map = acc.create_glyph_to_sid_map ();
- }
-
- unsigned int glyph;
- for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
- {
- hb_codepoint_t old_glyph;
- if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
- {
- /* Retain the SID for the old missing glyph ID */
- old_glyph = glyph;
- }
- sid = glyph_to_sid_map ? glyph_to_sid_map->get (old_glyph) : acc.glyph_to_sid (old_glyph);
-
- if (!acc.is_CID ())
- sid = sidmap.add (sid);
-
- if ((last_sid == CFF_UNDEF_CODE) || (sid != last_sid + 1))
- {
- code_pair_t pair = { sid, glyph };
- subset_charset_ranges.push (pair);
- }
- last_sid = sid;
- }
-
- if (created_map)
- {
- if (!(plan->accelerator && plan->accelerator->cff_accelerator) ||
- !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
- hb_map_destroy (glyph_to_sid_map);
- }
-
- bool two_byte = subset_charset_ranges.complete (glyph);
-
- size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1);
- if (!two_byte)
- size_ranges = Charset1::min_size + Charset1_Range::static_size * subset_charset_ranges.length;
- else
- size_ranges = Charset2::min_size + Charset2_Range::static_size * subset_charset_ranges.length;
-
- if (size0 < size_ranges)
- subset_charset_format = 0;
- else if (!two_byte)
- subset_charset_format = 1;
- else
- subset_charset_format = 2;
- }
-
- bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
- {
- sidmap.reset ();
-
- for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
- {
- unsigned int sid = acc.topDict.nameSIDs[i];
- if (sid != CFF_UNDEF_SID)
- {
- (void)sidmap.add (sid);
- topDictModSIDs[i] = sidmap[sid];
- }
- }
-
- if (acc.fdArray != &Null (CFF1FDArray))
- for (unsigned int i = 0; i < orig_fdcount; i++)
- if (fdmap.has (i))
- (void)sidmap.add (acc.fontDicts[i].fontName);
-
- return true;
- }
-
- bool create (const OT::cff1::accelerator_subset_t &acc,
- hb_subset_plan_t *plan)
- {
- /* make sure notdef is first */
- hb_codepoint_t old_glyph;
- if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false;
-
- num_glyphs = plan->num_output_glyphs ();
- orig_fdcount = acc.fdCount;
- drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
- desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE;
-
- /* check whether the subset renumbers any glyph IDs */
- gid_renum = false;
- for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++)
- {
- if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph))
- continue;
- if (new_glyph != old_glyph) {
- gid_renum = true;
- break;
- }
- }
-
- subset_charset = gid_renum || !acc.is_predef_charset ();
- subset_encoding = !acc.is_CID() && !acc.is_predef_encoding ();
-
- /* top dict INDEX */
- {
- /* Add encoding/charset to a (copy of) top dict as necessary */
- topdict_mod.init (&acc.topDict);
- bool need_to_add_enc = (subset_encoding && !acc.topDict.has_op (OpCode_Encoding));
- bool need_to_add_set = (subset_charset && !acc.topDict.has_op (OpCode_charset));
- if (need_to_add_enc || need_to_add_set)
- {
- if (need_to_add_enc)
- topdict_mod.add_op (OpCode_Encoding);
- if (need_to_add_set)
- topdict_mod.add_op (OpCode_charset);
- }
- }
-
- /* Determine re-mapping of font index as fdmap among other info */
- if (acc.fdSelect != &Null (CFF1FDSelect))
- {
- if (unlikely (!hb_plan_subset_cff_fdselect (plan,
- orig_fdcount,
- *acc.fdSelect,
- subset_fdcount,
- info.fd_select.size,
- subset_fdselect_format,
- subset_fdselect_ranges,
- fdmap)))
- return false;
- }
- else
- fdmap.identity (1);
-
- /* remove unused SIDs & reassign SIDs */
- {
- /* SIDs for name strings in dicts are added before glyph names so they fit in 16-bit int range */
- if (unlikely (!collect_sids_in_dicts (acc)))
- return false;
- if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */
- return false;
-
- if (subset_charset) plan_subset_charset (acc, plan);
-
- topdict_mod.reassignSIDs (sidmap);
- }
-
- if (desubroutinize)
- {
- /* Flatten global & local subrs */
- subr_flattener_t<const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_flatten_t, OpCode_endchar>
- flattener(acc, plan);
- if (!flattener.flatten (subset_charstrings))
- return false;
- }
- else
- {
- cff1_subr_subsetter_t subr_subsetter (acc, plan);
-
- /* Subset subrs: collect used subroutines, leaving all unused ones behind */
- if (!subr_subsetter.subset ())
- return false;
-
- /* encode charstrings, global subrs, local subrs with new subroutine numbers */
- if (!subr_subsetter.encode_charstrings (subset_charstrings))
- return false;
-
- if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs))
- return false;
-
- /* local subrs */
- if (!subset_localsubrs.resize (orig_fdcount))
- return false;
- for (unsigned int fd = 0; fd < orig_fdcount; fd++)
- {
- subset_localsubrs[fd].init ();
- if (fdmap.has (fd))
- {
- if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
- return false;
- }
- }
- }
-
- /* Encoding */
- if (subset_encoding)
- plan_subset_encoding (acc, plan);
-
- /* private dicts & local subrs */
- if (!acc.is_CID ())
- fontdicts_mod.push (cff1_font_dict_values_mod_t ());
- else
- {
- + hb_iter (acc.fontDicts)
- | hb_filter ([&] (const cff1_font_dict_values_t &_)
- { return fdmap.has (&_ - &acc.fontDicts[0]); } )
- | hb_map ([&] (const cff1_font_dict_values_t &_)
- {
- cff1_font_dict_values_mod_t mod;
- mod.init (&_, sidmap[_.fontName]);
- return mod;
- })
- | hb_sink (fontdicts_mod)
- ;
- }
-
- return ((subset_charstrings.length == plan->num_output_glyphs ())
- && (fontdicts_mod.length == subset_fdcount));
- }
-
- cff1_top_dict_values_mod_t topdict_mod;
- cff1_sub_table_info_t info;
-
- unsigned int num_glyphs;
- unsigned int orig_fdcount = 0;
- unsigned int subset_fdcount = 1;
- unsigned int subset_fdselect_format = 0;
- hb_vector_t<code_pair_t> subset_fdselect_ranges;
-
- /* font dict index remap table from fullset FDArray to subset FDArray.
- * set to CFF_UNDEF_CODE if excluded from subset */
- hb_inc_bimap_t fdmap;
-
- str_buff_vec_t subset_charstrings;
- str_buff_vec_t subset_globalsubrs;
- hb_vector_t<str_buff_vec_t> subset_localsubrs;
- hb_vector_t<cff1_font_dict_values_mod_t> fontdicts_mod;
-
- bool drop_hints = false;
-
- bool gid_renum;
- bool subset_encoding;
- uint8_t subset_enc_format;
- unsigned int subset_enc_num_codes;
- range_list_t subset_enc_code_ranges;
- hb_vector_t<code_pair_t> subset_enc_supp_codes;
-
- uint8_t subset_charset_format;
- range_list_t subset_charset_ranges;
- bool subset_charset;
-
- remap_sid_t sidmap;
- unsigned int topDictModSIDs[name_dict_values_t::ValCount];
-
- bool desubroutinize = false;
-};
-
-static bool _serialize_cff1 (hb_serialize_context_t *c,
- cff_subset_plan &plan,
- const OT::cff1::accelerator_subset_t &acc,
- unsigned int num_glyphs)
-{
- /* private dicts & local subrs */
- for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
- {
- if (plan.fdmap.has (i))
- {
- objidx_t subrs_link = 0;
- if (plan.subset_localsubrs[i].length > 0)
- {
- CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
- if (unlikely (!dest)) return false;
- c->push ();
- if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i])))
- subrs_link = c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- PrivateDict *pd = c->start_embed<PrivateDict> ();
- if (unlikely (!pd)) return false;
- c->push ();
- cff1_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
- /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
- if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
- {
- unsigned fd = plan.fdmap[i];
- plan.fontdicts_mod[fd].privateDictInfo.size = c->length ();
- plan.fontdicts_mod[fd].privateDictInfo.link = c->pop_pack ();
- }
- else
- {
- c->pop_discard ();
- return false;
- }
- }
- }
-
- if (!acc.is_CID ())
- plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo;
-
- /* CharStrings */
- {
- c->push<CFF1CharStrings> ();
-
- unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
- if (unlikely (!c->start_zerocopy (total_size)))
- return false;
-
- CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> ();
- if (unlikely (!cs)) return false;
-
- if (likely (cs->serialize (c, plan.subset_charstrings)))
- plan.info.char_strings_link = c->pop_pack (false);
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* FDArray (FD Index) */
- if (acc.fdArray != &Null (CFF1FDArray))
- {
- CFF1FDArray *fda = c->start_embed<CFF1FDArray> ();
- if (unlikely (!fda)) return false;
- c->push ();
- cff1_font_dict_op_serializer_t fontSzr;
- auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod));
- if (likely (fda->serialize (c, it, fontSzr)))
- plan.info.fd_array_link = c->pop_pack (false);
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* FDSelect */
- if (acc.fdSelect != &Null (CFF1FDSelect))
- {
- c->push ();
- if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount,
- plan.subset_fdselect_format, plan.info.fd_select.size,
- plan.subset_fdselect_ranges)))
- plan.info.fd_select.link = c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* Charset */
- if (plan.subset_charset)
- {
- Charset *dest = c->start_embed<Charset> ();
- if (unlikely (!dest)) return false;
- c->push ();
- if (likely (dest->serialize (c,
- plan.subset_charset_format,
- plan.num_glyphs,
- plan.subset_charset_ranges)))
- plan.info.charset_link = c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* Encoding */
- if (plan.subset_encoding)
- {
- Encoding *dest = c->start_embed<Encoding> ();
- if (unlikely (!dest)) return false;
- c->push ();
- if (likely (dest->serialize (c,
- plan.subset_enc_format,
- plan.subset_enc_num_codes,
- plan.subset_enc_code_ranges,
- plan.subset_enc_supp_codes)))
- plan.info.encoding_link = c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* global subrs */
- {
- c->push ();
- CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
- if (unlikely (!dest)) return false;
- if (likely (dest->serialize (c, plan.subset_globalsubrs)))
- c->pop_pack (false);
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* String INDEX */
- {
- CFF1StringIndex *dest = c->start_embed<CFF1StringIndex> ();
- if (unlikely (!dest)) return false;
- c->push ();
- if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap)))
- c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- OT::cff1 *cff = c->allocate_min<OT::cff1> ();
- if (unlikely (!cff))
- return false;
-
- /* header */
- cff->version.major = 0x01;
- cff->version.minor = 0x00;
- cff->nameIndex = cff->min_size;
- cff->offSize = 4; /* unused? */
-
- /* name INDEX */
- if (unlikely (!(*acc.nameIndex).copy (c))) return false;
-
- /* top dict INDEX */
- {
- /* serialize singleton TopDict */
- TopDict *top = c->start_embed<TopDict> ();
- if (!top) return false;
- c->push ();
- cff1_top_dict_op_serializer_t topSzr;
- unsigned top_size = 0;
- top_dict_modifiers_t modifier (plan.info, plan.topDictModSIDs);
- if (likely (top->serialize (c, plan.topdict_mod, topSzr, modifier)))
- {
- top_size = c->length ();
- c->pop_pack (false);
- }
- else
- {
- c->pop_discard ();
- return false;
- }
- /* serialize INDEX header for above */
- CFF1Index *dest = c->start_embed<CFF1Index> ();
- if (!dest) return false;
- return dest->serialize_header (c, hb_iter (hb_array_t<unsigned> (&top_size, 1)));
- }
-}
-
-static bool
-_hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc,
- hb_subset_context_t *c)
-{
- cff_subset_plan cff_plan;
-
- if (unlikely (!cff_plan.create (acc, c->plan)))
- {
- DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan.");
- return false;
- }
-
- return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ());
-}
-
-bool
-hb_subset_cff1 (hb_subset_context_t *c)
-{
- OT::cff1::accelerator_subset_t acc;
- acc.init (c->plan->source);
- bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c);
- acc.fini ();
-
- return result;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh
deleted file mode 100644
index aaf5def1ed5..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff1.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF1_HH
-#define HB_SUBSET_CFF1_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff1 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF1_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc
deleted file mode 100644
index 8ab4620194b..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.cc
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#include "hb.hh"
-
-#ifndef HB_NO_SUBSET_CFF
-
-#include "hb-open-type.hh"
-#include "hb-ot-cff2-table.hh"
-#include "hb-set.h"
-#include "hb-subset-cff2.hh"
-#include "hb-subset-plan.hh"
-#include "hb-subset-cff-common.hh"
-#include "hb-cff2-interp-cs.hh"
-
-using namespace CFF;
-
-struct cff2_sub_table_info_t : cff_sub_table_info_t
-{
- cff2_sub_table_info_t ()
- : cff_sub_table_info_t (),
- var_store_link (0)
- {}
-
- objidx_t var_store_link;
-};
-
-struct cff2_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<>
-{
- bool serialize (hb_serialize_context_t *c,
- const op_str_t &opstr,
- const cff2_sub_table_info_t &info) const
- {
- TRACE_SERIALIZE (this);
-
- switch (opstr.op)
- {
- case OpCode_vstore:
- if (info.var_store_link)
- return_trace (FontDict::serialize_link4_op(c, opstr.op, info.var_store_link));
- else
- return_trace (true);
-
- default:
- return_trace (cff_top_dict_op_serializer_t<>::serialize (c, opstr, info));
- }
- }
-};
-
-struct cff2_cs_opset_flatten_t : cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatten_param_t, blend_arg_t>
-{
- static void flush_args_and_op (op_code_t op, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
- {
- switch (op)
- {
- case OpCode_return:
- case OpCode_endchar:
- /* dummy opcodes in CFF2. ignore */
- break;
-
- case OpCode_hstem:
- case OpCode_hstemhm:
- case OpCode_vstem:
- case OpCode_vstemhm:
- case OpCode_hintmask:
- case OpCode_cntrmask:
- if (param.drop_hints)
- {
- env.clear_args ();
- return;
- }
- HB_FALLTHROUGH;
-
- default:
- SUPER::flush_args_and_op (op, env, param);
- break;
- }
- }
-
- static void flush_args (cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
- {
- for (unsigned int i = 0; i < env.argStack.get_count ();)
- {
- const blend_arg_t &arg = env.argStack[i];
- if (arg.blending ())
- {
- if (unlikely (!((arg.numValues > 0) && (env.argStack.get_count () >= arg.numValues))))
- {
- env.set_error ();
- return;
- }
- flatten_blends (arg, i, env, param);
- i += arg.numValues;
- }
- else
- {
- str_encoder_t encoder (param.flatStr);
- encoder.encode_num_cs (arg);
- i++;
- }
- }
- SUPER::flush_args (env, param);
- }
-
- static void flatten_blends (const blend_arg_t &arg, unsigned int i, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
- {
- /* flatten the default values */
- str_encoder_t encoder (param.flatStr);
- for (unsigned int j = 0; j < arg.numValues; j++)
- {
- const blend_arg_t &arg1 = env.argStack[i + j];
- if (unlikely (!((arg1.blending () && (arg.numValues == arg1.numValues) && (arg1.valueIndex == j) &&
- (arg1.deltas.length == env.get_region_count ())))))
- {
- env.set_error ();
- return;
- }
- encoder.encode_num_cs (arg1);
- }
- /* flatten deltas for each value */
- for (unsigned int j = 0; j < arg.numValues; j++)
- {
- const blend_arg_t &arg1 = env.argStack[i + j];
- for (unsigned int k = 0; k < arg1.deltas.length; k++)
- encoder.encode_num_cs (arg1.deltas[k]);
- }
- /* flatten the number of values followed by blend operator */
- encoder.encode_int (arg.numValues);
- encoder.encode_op (OpCode_blendcs);
- }
-
- static void flush_op (op_code_t op, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
- {
- switch (op)
- {
- case OpCode_return:
- case OpCode_endchar:
- return;
- default:
- str_encoder_t encoder (param.flatStr);
- encoder.encode_op (op);
- }
- }
-
- static void flush_hintmask (op_code_t op, cff2_cs_interp_env_t<blend_arg_t> &env, flatten_param_t& param)
- {
- SUPER::flush_hintmask (op, env, param);
- if (!param.drop_hints)
- {
- str_encoder_t encoder (param.flatStr);
- for (unsigned int i = 0; i < env.hintmask_size; i++)
- encoder.encode_byte (env.str_ref[i]);
- }
- }
-
- private:
- typedef cff2_cs_opset_t<cff2_cs_opset_flatten_t, flatten_param_t, blend_arg_t> SUPER;
- typedef cs_opset_t<blend_arg_t, cff2_cs_opset_flatten_t, cff2_cs_opset_flatten_t, cff2_cs_interp_env_t<blend_arg_t>, flatten_param_t> CSOPSET;
-};
-
-struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t, subr_subset_param_t, blend_arg_t>
-{
- static void process_op (op_code_t op, cff2_cs_interp_env_t<blend_arg_t> &env, subr_subset_param_t& param)
- {
- switch (op) {
-
- case OpCode_return:
- param.current_parsed_str->set_parsed ();
- env.return_from_subr ();
- param.set_current_str (env, false);
- break;
-
- case OpCode_endchar:
- param.current_parsed_str->set_parsed ();
- SUPER::process_op (op, env, param);
- break;
-
- case OpCode_callsubr:
- process_call_subr (op, CSType_LocalSubr, env, param, env.localSubrs, param.local_closure);
- break;
-
- case OpCode_callgsubr:
- process_call_subr (op, CSType_GlobalSubr, env, param, env.globalSubrs, param.global_closure);
- break;
-
- default:
- SUPER::process_op (op, env, param);
- param.current_parsed_str->add_op (op, env.str_ref);
- break;
- }
- }
-
- protected:
- static void process_call_subr (op_code_t op, cs_type_t type,
- cff2_cs_interp_env_t<blend_arg_t> &env, subr_subset_param_t& param,
- cff2_biased_subrs_t& subrs, hb_set_t *closure)
- {
- byte_str_ref_t str_ref = env.str_ref;
- env.call_subr (subrs, type);
- param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
- closure->add (env.context.subr_num);
- param.set_current_str (env, true);
- }
-
- private:
- typedef cff2_cs_opset_t<cff2_cs_opset_subr_subset_t, subr_subset_param_t, blend_arg_t> SUPER;
-};
-
-struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs, const OT::cff2::accelerator_subset_t, cff2_cs_interp_env_t<blend_arg_t>, cff2_cs_opset_subr_subset_t>
-{
- cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
- : subr_subsetter_t (acc_, plan_) {}
-
- static void complete_parsed_str (cff2_cs_interp_env_t<blend_arg_t> &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
- {
- /* vsindex is inserted at the beginning of the charstring as necessary */
- if (env.seen_vsindex ())
- {
- number_t ivs;
- ivs.set_int ((int)env.get_ivs ());
- charstring.set_prefix (ivs, OpCode_vsindexcs);
- }
- }
-};
-
-struct cff2_private_blend_encoder_param_t
-{
- cff2_private_blend_encoder_param_t (hb_serialize_context_t *c,
- const CFF2VariationStore *varStore,
- hb_array_t<int> normalized_coords) :
- c (c), varStore (varStore), normalized_coords (normalized_coords) {}
-
- void init () {}
-
- void process_blend ()
- {
- if (!seen_blend)
- {
- region_count = varStore->varStore.get_region_index_count (ivs);
- scalars.resize_exact (region_count);
- varStore->varStore.get_region_scalars (ivs, normalized_coords.arrayZ, normalized_coords.length,
- &scalars[0], region_count);
- seen_blend = true;
- }
- }
-
- double blend_deltas (hb_array_t<const number_t> deltas) const
- {
- double v = 0;
- if (likely (scalars.length == deltas.length))
- {
- unsigned count = scalars.length;
- for (unsigned i = 0; i < count; i++)
- v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real ();
- }
- return v;
- }
-
-
- hb_serialize_context_t *c = nullptr;
- bool seen_blend = false;
- unsigned ivs = 0;
- unsigned region_count = 0;
- hb_vector_t<float> scalars;
- const CFF2VariationStore *varStore = nullptr;
- hb_array_t<int> normalized_coords;
-};
-
-struct cff2_private_dict_blend_opset_t : dict_opset_t
-{
- static void process_arg_blend (cff2_private_blend_encoder_param_t& param,
- number_t &arg,
- const hb_array_t<const number_t> blends,
- unsigned n, unsigned i)
- {
- arg.set_int (round (arg.to_real () + param.blend_deltas (blends)));
- }
-
- static void process_blend (cff2_priv_dict_interp_env_t& env, cff2_private_blend_encoder_param_t& param)
- {
- unsigned int n, k;
-
- param.process_blend ();
- k = param.region_count;
- n = env.argStack.pop_uint ();
- /* copy the blend values into blend array of the default values */
- unsigned int start = env.argStack.get_count () - ((k+1) * n);
- /* let an obvious error case fail, but note CFF2 spec doesn't forbid n==0 */
- if (unlikely (start > env.argStack.get_count ()))
- {
- env.set_error ();
- return;
- }
- for (unsigned int i = 0; i < n; i++)
- {
- const hb_array_t<const number_t> blends = env.argStack.sub_array (start + n + (i * k), k);
- process_arg_blend (param, env.argStack[start + i], blends, n, i);
- }
-
- /* pop off blend values leaving default values now adorned with blend values */
- env.argStack.pop (k * n);
- }
-
- static void process_op (op_code_t op, cff2_priv_dict_interp_env_t& env, cff2_private_blend_encoder_param_t& param)
- {
- switch (op) {
- case OpCode_StdHW:
- case OpCode_StdVW:
- case OpCode_BlueScale:
- case OpCode_BlueShift:
- case OpCode_BlueFuzz:
- case OpCode_ExpansionFactor:
- case OpCode_LanguageGroup:
- case OpCode_BlueValues:
- case OpCode_OtherBlues:
- case OpCode_FamilyBlues:
- case OpCode_FamilyOtherBlues:
- case OpCode_StemSnapH:
- case OpCode_StemSnapV:
- break;
- case OpCode_vsindexdict:
- env.process_vsindex ();
- param.ivs = env.get_ivs ();
- env.clear_args ();
- return;
- case OpCode_blenddict:
- process_blend (env, param);
- return;
-
- default:
- dict_opset_t::process_op (op, env);
- if (!env.argStack.is_empty ()) return;
- break;
- }
-
- if (unlikely (env.in_error ())) return;
-
- // Write args then op
-
- str_buff_t str;
- str_encoder_t encoder (str);
-
- unsigned count = env.argStack.get_count ();
- for (unsigned i = 0; i < count; i++)
- encoder.encode_num_tp (env.argStack[i]);
-
- encoder.encode_op (op);
-
- auto bytes = str.as_bytes ();
- param.c->embed (&bytes, bytes.length);
-
- env.clear_args ();
- }
-};
-
-struct cff2_private_dict_op_serializer_t : op_serializer_t
-{
- cff2_private_dict_op_serializer_t (bool desubroutinize_, bool drop_hints_, bool pinned_,
- const CFF::CFF2VariationStore* varStore_,
- hb_array_t<int> normalized_coords_)
- : desubroutinize (desubroutinize_), drop_hints (drop_hints_), pinned (pinned_),
- varStore (varStore_), normalized_coords (normalized_coords_) {}
-
- bool serialize (hb_serialize_context_t *c,
- const op_str_t &opstr,
- objidx_t subrs_link) const
- {
- TRACE_SERIALIZE (this);
-
- if (drop_hints && dict_opset_t::is_hint_op (opstr.op))
- return_trace (true);
-
- if (opstr.op == OpCode_Subrs)
- {
- if (desubroutinize || !subrs_link)
- return_trace (true);
- else
- return_trace (FontDict::serialize_link2_op (c, opstr.op, subrs_link));
- }
-
- if (pinned)
- {
- // Reinterpret opstr and process blends.
- cff2_priv_dict_interp_env_t env {hb_ubytes_t (opstr.ptr, opstr.length)};
- cff2_private_blend_encoder_param_t param (c, varStore, normalized_coords);
- dict_interpreter_t<cff2_private_dict_blend_opset_t, cff2_private_blend_encoder_param_t, cff2_priv_dict_interp_env_t> interp (env);
- return_trace (interp.interpret (param));
- }
-
- return_trace (copy_opstr (c, opstr));
- }
-
- protected:
- const bool desubroutinize;
- const bool drop_hints;
- const bool pinned;
- const CFF::CFF2VariationStore* varStore;
- hb_array_t<int> normalized_coords;
-};
-
-
-struct cff2_subset_plan
-{
- bool create (const OT::cff2::accelerator_subset_t &acc,
- hb_subset_plan_t *plan)
- {
- orig_fdcount = acc.fdArray->count;
-
- drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
- pinned = (bool) plan->normalized_coords;
- desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE ||
- pinned; // For instancing we need this path
-
- if (desubroutinize)
- {
- /* Flatten global & local subrs */
- subr_flattener_t<const OT::cff2::accelerator_subset_t, cff2_cs_interp_env_t<blend_arg_t>, cff2_cs_opset_flatten_t>
- flattener(acc, plan);
- if (!flattener.flatten (subset_charstrings))
- return false;
- }
- else
- {
- cff2_subr_subsetter_t subr_subsetter (acc, plan);
-
- /* Subset subrs: collect used subroutines, leaving all unused ones behind */
- if (!subr_subsetter.subset ())
- return false;
-
- /* encode charstrings, global subrs, local subrs with new subroutine numbers */
- if (!subr_subsetter.encode_charstrings (subset_charstrings, !pinned))
- return false;
-
- if (!subr_subsetter.encode_globalsubrs (subset_globalsubrs))
- return false;
-
- /* local subrs */
- if (!subset_localsubrs.resize (orig_fdcount))
- return false;
- for (unsigned int fd = 0; fd < orig_fdcount; fd++)
- {
- subset_localsubrs[fd].init ();
- if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
- return false;
- }
- }
-
- /* FDSelect */
- if (acc.fdSelect != &Null (CFF2FDSelect))
- {
- if (unlikely (!hb_plan_subset_cff_fdselect (plan,
- orig_fdcount,
- *(const FDSelect *)acc.fdSelect,
- subset_fdcount,
- subset_fdselect_size,
- subset_fdselect_format,
- subset_fdselect_ranges,
- fdmap)))
- return false;
- }
- else
- fdmap.identity (1);
-
- return true;
- }
-
- cff2_sub_table_info_t info;
-
- unsigned int orig_fdcount = 0;
- unsigned int subset_fdcount = 1;
- unsigned int subset_fdselect_size = 0;
- unsigned int subset_fdselect_format = 0;
- bool pinned = false;
- hb_vector_t<code_pair_t> subset_fdselect_ranges;
-
- hb_inc_bimap_t fdmap;
-
- str_buff_vec_t subset_charstrings;
- str_buff_vec_t subset_globalsubrs;
- hb_vector_t<str_buff_vec_t> subset_localsubrs;
-
- bool drop_hints = false;
- bool desubroutinize = false;
-};
-
-static bool _serialize_cff2 (hb_serialize_context_t *c,
- cff2_subset_plan &plan,
- const OT::cff2::accelerator_subset_t &acc,
- unsigned int num_glyphs,
- hb_array_t<int> normalized_coords)
-{
- /* private dicts & local subrs */
- hb_vector_t<table_info_t> private_dict_infos;
- if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false;
-
- for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
- {
- if (plan.fdmap.has (i))
- {
- objidx_t subrs_link = 0;
-
- if (plan.subset_localsubrs[i].length > 0)
- {
- CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
- if (unlikely (!dest)) return false;
- c->push ();
- if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
- subrs_link = c->pop_pack (false);
- else
- {
- c->pop_discard ();
- return false;
- }
- }
- PrivateDict *pd = c->start_embed<PrivateDict> ();
- if (unlikely (!pd)) return false;
- c->push ();
- cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned,
- acc.varStore, normalized_coords);
- if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
- {
- unsigned fd = plan.fdmap[i];
- private_dict_infos[fd].size = c->length ();
- private_dict_infos[fd].link = c->pop_pack ();
- }
- else
- {
- c->pop_discard ();
- return false;
- }
- }
- }
-
- /* CharStrings */
- {
- c->push ();
-
- unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
- if (unlikely (!c->start_zerocopy (total_size)))
- return false;
-
- CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> ();
- if (unlikely (!cs)) return false;
-
- if (likely (cs->serialize (c, plan.subset_charstrings)))
- plan.info.char_strings_link = c->pop_pack (false);
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* FDSelect */
- if (acc.fdSelect != &Null (CFF2FDSelect))
- {
- c->push ();
- if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect,
- plan.orig_fdcount,
- plan.subset_fdselect_format, plan.subset_fdselect_size,
- plan.subset_fdselect_ranges)))
- plan.info.fd_select.link = c->pop_pack ();
- else
- {
- c->pop_discard ();
- return false;
- }
- }
-
- /* FDArray (FD Index) */
- {
- c->push ();
- CFF2FDArray *fda = c->start_embed<CFF2FDArray> ();
- if (unlikely (!fda)) return false;
- cff_font_dict_op_serializer_t fontSzr;
- auto it =
- + hb_zip (+ hb_iter (acc.fontDicts)
- | hb_filter ([&] (const cff2_font_dict_values_t &_)
- { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }),
- hb_iter (private_dict_infos))
- ;
- if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
- plan.info.fd_array_link = c->pop_pack (false);
- }
-
- /* variation store */
- if (acc.varStore != &Null (CFF2VariationStore) &&
- !plan.pinned)
- {
- c->push ();
- CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> ();
- if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
- plan.info.var_store_link = c->pop_pack (false);
- }
-
- OT::cff2 *cff2 = c->allocate_min<OT::cff2> ();
- if (unlikely (!cff2)) return false;
-
- /* header */
- cff2->version.major = 0x02;
- cff2->version.minor = 0x00;
- cff2->topDict = OT::cff2::static_size;
-
- /* top dict */
- {
- TopDict &dict = cff2 + cff2->topDict;
- cff2_top_dict_op_serializer_t topSzr;
- if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false;
- cff2->topDictSize = c->head - (const char *)&dict;
- }
-
- /* global subrs */
- {
- CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
- if (unlikely (!dest)) return false;
- return dest->serialize (c, plan.subset_globalsubrs);
- }
-}
-
-static bool
-_hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc,
- hb_subset_context_t *c)
-{
- cff2_subset_plan cff2_plan;
-
- if (unlikely (!cff2_plan.create (acc, c->plan))) return false;
- return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs (),
- c->plan->normalized_coords.as_array ());
-}
-
-bool
-hb_subset_cff2 (hb_subset_context_t *c)
-{
- OT::cff2::accelerator_subset_t acc (c->plan->source);
- return acc.is_valid () && _hb_subset_cff2 (acc, c);
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh
deleted file mode 100644
index f10556ddd74..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-cff2.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe 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.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF2_HH
-#define HB_SUBSET_CFF2_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff2 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF2_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
deleted file mode 100644
index 5f001ac2511..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Rod Sheeter, Behdad Esfahbod
- */
-
-#include "hb-subset.hh"
-#include "hb-set.hh"
-#include "hb-utf.hh"
-
-
-hb_subset_input_t::hb_subset_input_t ()
-{
- for (auto& set : sets_iter ())
- set = hb::shared_ptr<hb_set_t> (hb_set_create ());
-
- if (in_error ())
- return;
-
- flags = HB_SUBSET_FLAGS_DEFAULT;
-
- hb_set_add_range (sets.name_ids, 0, 6);
- hb_set_add (sets.name_languages, 0x0409);
-
- hb_tag_t default_drop_tables[] = {
- // Layout disabled by default
- HB_TAG ('m', 'o', 'r', 'x'),
- HB_TAG ('m', 'o', 'r', 't'),
- HB_TAG ('k', 'e', 'r', 'x'),
- HB_TAG ('k', 'e', 'r', 'n'),
-
- // Copied from fontTools:
- HB_TAG ('B', 'A', 'S', 'E'),
- HB_TAG ('J', 'S', 'T', 'F'),
- HB_TAG ('D', 'S', 'I', 'G'),
- HB_TAG ('E', 'B', 'D', 'T'),
- HB_TAG ('E', 'B', 'L', 'C'),
- HB_TAG ('E', 'B', 'S', 'C'),
- HB_TAG ('S', 'V', 'G', ' '),
- HB_TAG ('P', 'C', 'L', 'T'),
- HB_TAG ('L', 'T', 'S', 'H'),
- // Graphite tables
- HB_TAG ('F', 'e', 'a', 't'),
- HB_TAG ('G', 'l', 'a', 't'),
- HB_TAG ('G', 'l', 'o', 'c'),
- HB_TAG ('S', 'i', 'l', 'f'),
- HB_TAG ('S', 'i', 'l', 'l'),
- };
- sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
-
- hb_tag_t default_no_subset_tables[] = {
- HB_TAG ('a', 'v', 'a', 'r'),
- HB_TAG ('g', 'a', 's', 'p'),
- HB_TAG ('f', 'p', 'g', 'm'),
- HB_TAG ('p', 'r', 'e', 'p'),
- HB_TAG ('V', 'D', 'M', 'X'),
- HB_TAG ('D', 'S', 'I', 'G'),
- HB_TAG ('M', 'V', 'A', 'R'),
- HB_TAG ('c', 'v', 'a', 'r'),
- };
- sets.no_subset_tables->add_array (default_no_subset_tables,
- ARRAY_LENGTH (default_no_subset_tables));
-
- //copied from _layout_features_groups in fonttools
- hb_tag_t default_layout_features[] = {
- // default shaper
- // common
- HB_TAG ('r', 'v', 'r', 'n'),
- HB_TAG ('c', 'c', 'm', 'p'),
- HB_TAG ('l', 'i', 'g', 'a'),
- HB_TAG ('l', 'o', 'c', 'l'),
- HB_TAG ('m', 'a', 'r', 'k'),
- HB_TAG ('m', 'k', 'm', 'k'),
- HB_TAG ('r', 'l', 'i', 'g'),
-
- //fractions
- HB_TAG ('f', 'r', 'a', 'c'),
- HB_TAG ('n', 'u', 'm', 'r'),
- HB_TAG ('d', 'n', 'o', 'm'),
-
- //horizontal
- HB_TAG ('c', 'a', 'l', 't'),
- HB_TAG ('c', 'l', 'i', 'g'),
- HB_TAG ('c', 'u', 'r', 's'),
- HB_TAG ('k', 'e', 'r', 'n'),
- HB_TAG ('r', 'c', 'l', 't'),
-
- //vertical
- HB_TAG ('v', 'a', 'l', 't'),
- HB_TAG ('v', 'e', 'r', 't'),
- HB_TAG ('v', 'k', 'r', 'n'),
- HB_TAG ('v', 'p', 'a', 'l'),
- HB_TAG ('v', 'r', 't', '2'),
-
- //ltr
- HB_TAG ('l', 't', 'r', 'a'),
- HB_TAG ('l', 't', 'r', 'm'),
-
- //rtl
- HB_TAG ('r', 't', 'l', 'a'),
- HB_TAG ('r', 't', 'l', 'm'),
-
- //random
- HB_TAG ('r', 'a', 'n', 'd'),
-
- //justify
- HB_TAG ('j', 'a', 'l', 't'), // HarfBuzz doesn't use; others might
-
- //private
- HB_TAG ('H', 'a', 'r', 'f'),
- HB_TAG ('H', 'A', 'R', 'F'),
- HB_TAG ('B', 'u', 'z', 'z'),
- HB_TAG ('B', 'U', 'Z', 'Z'),
-
- //shapers
-
- //arabic
- HB_TAG ('i', 'n', 'i', 't'),
- HB_TAG ('m', 'e', 'd', 'i'),
- HB_TAG ('f', 'i', 'n', 'a'),
- HB_TAG ('i', 's', 'o', 'l'),
- HB_TAG ('m', 'e', 'd', '2'),
- HB_TAG ('f', 'i', 'n', '2'),
- HB_TAG ('f', 'i', 'n', '3'),
- HB_TAG ('c', 's', 'w', 'h'),
- HB_TAG ('m', 's', 'e', 't'),
- HB_TAG ('s', 't', 'c', 'h'),
-
- //hangul
- HB_TAG ('l', 'j', 'm', 'o'),
- HB_TAG ('v', 'j', 'm', 'o'),
- HB_TAG ('t', 'j', 'm', 'o'),
-
- //tibetan
- HB_TAG ('a', 'b', 'v', 's'),
- HB_TAG ('b', 'l', 'w', 's'),
- HB_TAG ('a', 'b', 'v', 'm'),
- HB_TAG ('b', 'l', 'w', 'm'),
-
- //indic
- HB_TAG ('n', 'u', 'k', 't'),
- HB_TAG ('a', 'k', 'h', 'n'),
- HB_TAG ('r', 'p', 'h', 'f'),
- HB_TAG ('r', 'k', 'r', 'f'),
- HB_TAG ('p', 'r', 'e', 'f'),
- HB_TAG ('b', 'l', 'w', 'f'),
- HB_TAG ('h', 'a', 'l', 'f'),
- HB_TAG ('a', 'b', 'v', 'f'),
- HB_TAG ('p', 's', 't', 'f'),
- HB_TAG ('c', 'f', 'a', 'r'),
- HB_TAG ('v', 'a', 't', 'u'),
- HB_TAG ('c', 'j', 'c', 't'),
- HB_TAG ('i', 'n', 'i', 't'),
- HB_TAG ('p', 'r', 'e', 's'),
- HB_TAG ('a', 'b', 'v', 's'),
- HB_TAG ('b', 'l', 'w', 's'),
- HB_TAG ('p', 's', 't', 's'),
- HB_TAG ('h', 'a', 'l', 'n'),
- HB_TAG ('d', 'i', 's', 't'),
- HB_TAG ('a', 'b', 'v', 'm'),
- HB_TAG ('b', 'l', 'w', 'm'),
- };
-
- sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features));
-
- sets.layout_scripts->invert (); // Default to all scripts.
-}
-
-/**
- * hb_subset_input_create_or_fail:
- *
- * Creates a new subset input object.
- *
- * Return value: (transfer full): New subset input, or `NULL` if failed. Destroy
- * with hb_subset_input_destroy().
- *
- * Since: 1.8.0
- **/
-hb_subset_input_t *
-hb_subset_input_create_or_fail (void)
-{
- hb_subset_input_t *input = hb_object_create<hb_subset_input_t>();
-
- if (unlikely (!input))
- return nullptr;
-
- if (input->in_error ())
- {
- hb_subset_input_destroy (input);
- return nullptr;
- }
-
- return input;
-}
-
-/**
- * hb_subset_input_reference: (skip)
- * @input: a #hb_subset_input_t object.
- *
- * Increases the reference count on @input.
- *
- * Return value: @input.
- *
- * Since: 1.8.0
- **/
-hb_subset_input_t *
-hb_subset_input_reference (hb_subset_input_t *input)
-{
- return hb_object_reference (input);
-}
-
-/**
- * hb_subset_input_destroy:
- * @input: a #hb_subset_input_t object.
- *
- * Decreases the reference count on @input, and if it reaches zero, destroys
- * @input, freeing all memory.
- *
- * Since: 1.8.0
- **/
-void
-hb_subset_input_destroy (hb_subset_input_t *input)
-{
- if (!hb_object_destroy (input)) return;
-
- hb_free (input);
-}
-
-/**
- * hb_subset_input_unicode_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of Unicode code points to retain, the caller should modify the
- * set as needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of Unicode code
- * points.
- *
- * Since: 1.8.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_unicode_set (hb_subset_input_t *input)
-{
- return input->sets.unicodes;
-}
-
-/**
- * hb_subset_input_glyph_set:
- * @input: a #hb_subset_input_t object.
- *
- * Gets the set of glyph IDs to retain, the caller should modify the set as
- * needed.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of glyph IDs.
- *
- * Since: 1.8.0
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_glyph_set (hb_subset_input_t *input)
-{
- return input->sets.glyphs;
-}
-
-/**
- * hb_subset_input_set:
- * @input: a #hb_subset_input_t object.
- * @set_type: a #hb_subset_sets_t set type.
- *
- * Gets the set of the specified type.
- *
- * Return value: (transfer none): pointer to the #hb_set_t of the specified type.
- *
- * Since: 2.9.1
- **/
-HB_EXTERN hb_set_t *
-hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type)
-{
- return input->sets_iter () [set_type];
-}
-
-/**
- * hb_subset_input_get_flags:
- * @input: a #hb_subset_input_t object.
- *
- * Gets all of the subsetting flags in the input object.
- *
- * Return value: the subsetting flags bit field.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN hb_subset_flags_t
-hb_subset_input_get_flags (hb_subset_input_t *input)
-{
- return (hb_subset_flags_t) input->flags;
-}
-
-/**
- * hb_subset_input_set_flags:
- * @input: a #hb_subset_input_t object.
- * @value: bit field of flags
- *
- * Sets all of the flags in the input object to the values specified by the bit
- * field.
- *
- * Since: 2.9.0
- **/
-HB_EXTERN void
-hb_subset_input_set_flags (hb_subset_input_t *input,
- unsigned value)
-{
- input->flags = (hb_subset_flags_t) value;
-}
-
-/**
- * hb_subset_input_set_user_data: (skip)
- * @input: a #hb_subset_input_t object.
- * @key: The user-data key to set
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the given subset input object.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 2.9.0
- **/
-hb_bool_t
-hb_subset_input_set_user_data (hb_subset_input_t *input,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- return hb_object_set_user_data (input, key, data, destroy, replace);
-}
-
-/**
- * hb_subset_input_get_user_data: (skip)
- * @input: a #hb_subset_input_t object.
- * @key: The user-data key to query
- *
- * Fetches the user data associated with the specified key,
- * attached to the specified subset input object.
- *
- * Return value: (transfer none): A pointer to the user data
- *
- * Since: 2.9.0
- **/
-void *
-hb_subset_input_get_user_data (const hb_subset_input_t *input,
- hb_user_data_key_t *key)
-{
- return hb_object_get_user_data (input, key);
-}
-
-/**
- * hb_subset_input_keep_everything:
- * @input: a #hb_subset_input_t object
- *
- * Configure input object to keep everything in the font face.
- * That is, all Unicodes, glyphs, names, layout items,
- * glyph names, etc.
- *
- * The input can be tailored afterwards by the caller.
- *
- * Since: 7.0.0
- */
-void
-hb_subset_input_keep_everything (hb_subset_input_t *input)
-{
- const hb_subset_sets_t indices[] = {HB_SUBSET_SETS_UNICODE,
- HB_SUBSET_SETS_GLYPH_INDEX,
- HB_SUBSET_SETS_NAME_ID,
- HB_SUBSET_SETS_NAME_LANG_ID,
- HB_SUBSET_SETS_LAYOUT_FEATURE_TAG,
- HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG};
-
- for (auto idx : hb_iter (indices))
- {
- hb_set_t *set = hb_subset_input_set (input, idx);
- hb_set_clear (set);
- hb_set_invert (set);
- }
-
- // Don't drop any tables
- hb_set_clear (hb_subset_input_set (input, HB_SUBSET_SETS_DROP_TABLE_TAG));
-
- hb_subset_input_set_flags (input,
- HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
- HB_SUBSET_FLAGS_GLYPH_NAMES |
- HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES |
- HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED);
-}
-
-#ifndef HB_NO_VAR
-/**
- * hb_subset_input_pin_axis_to_default: (skip)
- * @input: a #hb_subset_input_t object.
- * @face: a #hb_face_t object.
- * @axis_tag: Tag of the axis to be pinned
- *
- * Pin an axis to its default location in the given subset input object.
- *
- * All axes in a font must be pinned. Additionally, `CFF2` table, if present,
- * will be de-subroutinized.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 6.0.0
- **/
-HB_EXTERN hb_bool_t
-hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
- hb_face_t *face,
- hb_tag_t axis_tag)
-{
- hb_ot_var_axis_info_t axis_info;
- if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
- return false;
-
- return input->axes_location.set (axis_tag, axis_info.default_value);
-}
-
-/**
- * hb_subset_input_pin_axis_location: (skip)
- * @input: a #hb_subset_input_t object.
- * @face: a #hb_face_t object.
- * @axis_tag: Tag of the axis to be pinned
- * @axis_value: Location on the axis to be pinned at
- *
- * Pin an axis to a fixed location in the given subset input object.
- *
- * All axes in a font must be pinned. Additionally, `CFF2` table, if present,
- * will be de-subroutinized.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 6.0.0
- **/
-HB_EXTERN hb_bool_t
-hb_subset_input_pin_axis_location (hb_subset_input_t *input,
- hb_face_t *face,
- hb_tag_t axis_tag,
- float axis_value)
-{
- hb_ot_var_axis_info_t axis_info;
- if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
- return false;
-
- float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value);
- return input->axes_location.set (axis_tag, val);
-}
-#endif
-
-/**
- * hb_subset_preprocess:
- * @source: a #hb_face_t object.
- *
- * Preprocesses the face and attaches data that will be needed by the
- * subsetter. Future subsetting operations can then use the precomputed data
- * to speed up the subsetting operation.
- *
- * See [subset-preprocessing](https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md)
- * for more information.
- *
- * Note: the preprocessed face may contain sub-blobs that reference the memory
- * backing the source #hb_face_t. Therefore in the case that this memory is not
- * owned by the source face you will need to ensure that memory lives
- * as long as the returned #hb_face_t.
- *
- * Returns: a new #hb_face_t.
- *
- * Since: 6.0.0
- **/
-
-HB_EXTERN hb_face_t *
-hb_subset_preprocess (hb_face_t *source)
-{
- hb_subset_input_t* input = hb_subset_input_create_or_fail ();
- if (!input)
- return hb_face_reference (source);
-
- hb_subset_input_keep_everything (input);
-
- input->attach_accelerator_data = true;
-
- // Always use long loca in the preprocessed version. This allows
- // us to store the glyph bytes unpadded which allows the future subset
- // operation to run faster by skipping the trim padding step.
- input->force_long_loca = true;
-
- hb_face_t* new_source = hb_subset_or_fail (source, input);
- hb_subset_input_destroy (input);
-
- if (!new_source) {
- DEBUG_MSG (SUBSET, nullptr, "Preprocessing failed due to subset failure.");
- return hb_face_reference (source);
- }
-
- return new_source;
-}
-
-#ifdef HB_EXPERIMENTAL_API
-/**
- * hb_subset_input_override_name_table:
- * @input: a #hb_subset_input_t object.
- * @name_id: name_id of a nameRecord
- * @platform_id: platform ID of a nameRecord
- * @encoding_id: encoding ID of a nameRecord
- * @language_id: language ID of a nameRecord
- * @name_str: pointer to name string new value or null to indicate should remove
- * @str_len: the size of @name_str, or -1 if it is `NULL`-terminated
- *
- * Override the name string of the NameRecord identified by name_id,
- * platform_id, encoding_id and language_id. If a record with that name_id
- * doesn't exist, create it and insert to the name table.
- *
- * Note: for mac platform, we only support name_str with all ascii characters,
- * name_str with non-ascii characters will be ignored.
- *
- * XSince: EXPERIMENTAL
- **/
-HB_EXTERN hb_bool_t
-hb_subset_input_override_name_table (hb_subset_input_t *input,
- hb_ot_name_id_t name_id,
- unsigned platform_id,
- unsigned encoding_id,
- unsigned language_id,
- const char *name_str,
- int str_len /* -1 means nul-terminated */)
-{
- if (!name_str)
- {
- str_len = 0;
- }
- else if (str_len == -1)
- {
- str_len = strlen (name_str);
- }
-
- hb_bytes_t name_bytes (nullptr, 0);
- if (str_len)
- {
- if (platform_id == 1)
- {
- const uint8_t *src = reinterpret_cast<const uint8_t*> (name_str);
- const uint8_t *src_end = src + str_len;
-
- hb_codepoint_t unicode;
- const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
- while (src < src_end)
- {
- src = hb_utf8_t::next (src, src_end, &unicode, replacement);
- if (unicode >= 0x0080u)
- {
- printf ("Non-ascii character detected, ignored...This API supports acsii characters only for mac platform\n");
- return false;
- }
- }
- }
- char *override_name = (char *) hb_malloc (str_len);
- if (unlikely (!override_name)) return false;
-
- hb_memcpy (override_name, name_str, str_len);
- name_bytes = hb_bytes_t (override_name, str_len);
- }
- input->name_table_overrides.set (hb_ot_name_record_ids_t (platform_id, encoding_id, language_id, name_id), name_bytes);
- return true;
-}
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh
deleted file mode 100644
index 1550e8b2c30..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Roderick Sheeter
- */
-
-#ifndef HB_SUBSET_INPUT_HH
-#define HB_SUBSET_INPUT_HH
-
-
-#include "hb.hh"
-
-#include "hb-subset.h"
-#include "hb-map.hh"
-#include "hb-set.hh"
-#include "hb-cplusplus.hh"
-#include "hb-font.hh"
-
-struct hb_ot_name_record_ids_t
-{
- hb_ot_name_record_ids_t () = default;
- hb_ot_name_record_ids_t (unsigned platform_id_,
- unsigned encoding_id_,
- unsigned language_id_,
- unsigned name_id_)
- :platform_id (platform_id_),
- encoding_id (encoding_id_),
- language_id (language_id_),
- name_id (name_id_) {}
-
- bool operator != (const hb_ot_name_record_ids_t o) const
- { return !(*this == o); }
-
- inline bool operator == (const hb_ot_name_record_ids_t& o) const
- {
- return platform_id == o.platform_id &&
- encoding_id == o.encoding_id &&
- language_id == o.language_id &&
- name_id == o.name_id;
- }
-
- inline uint32_t hash () const
- {
- uint32_t current = 0;
- current = current * 31 + hb_hash (platform_id);
- current = current * 31 + hb_hash (encoding_id);
- current = current * 31 + hb_hash (language_id);
- current = current * 31 + hb_hash (name_id);
- return current;
- }
-
- unsigned platform_id;
- unsigned encoding_id;
- unsigned language_id;
- unsigned name_id;
-};
-
-typedef struct hb_ot_name_record_ids_t hb_ot_name_record_ids_t;
-
-
-HB_MARK_AS_FLAG_T (hb_subset_flags_t);
-
-struct hb_subset_input_t
-{
- HB_INTERNAL hb_subset_input_t ();
-
- ~hb_subset_input_t ()
- {
- sets.~sets_t ();
-
-#ifdef HB_EXPERIMENTAL_API
- for (auto _ : name_table_overrides.values ())
- _.fini ();
-#endif
- }
-
- hb_object_header_t header;
-
- struct sets_t {
- hb::shared_ptr<hb_set_t> glyphs;
- hb::shared_ptr<hb_set_t> unicodes;
- hb::shared_ptr<hb_set_t> no_subset_tables;
- hb::shared_ptr<hb_set_t> drop_tables;
- hb::shared_ptr<hb_set_t> name_ids;
- hb::shared_ptr<hb_set_t> name_languages;
- hb::shared_ptr<hb_set_t> layout_features;
- hb::shared_ptr<hb_set_t> layout_scripts;
- };
-
- union {
- sets_t sets;
- hb::shared_ptr<hb_set_t> set_ptrs[sizeof (sets_t) / sizeof (hb_set_t*)];
- };
-
- unsigned flags;
- bool attach_accelerator_data = false;
-
- // If set loca format will always be the long version.
- bool force_long_loca = false;
-
- hb_hashmap_t<hb_tag_t, float> axes_location;
-#ifdef HB_EXPERIMENTAL_API
- hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
-#endif
-
- inline unsigned num_sets () const
- {
- return sizeof (set_ptrs) / sizeof (hb_set_t*);
- }
-
- inline hb_array_t<hb::shared_ptr<hb_set_t>> sets_iter ()
- {
- return hb_array (set_ptrs);
- }
-
- bool in_error () const
- {
- for (unsigned i = 0; i < num_sets (); i++)
- {
- if (unlikely (set_ptrs[i]->in_error ()))
- return true;
- }
-
- return axes_location.in_error ()
-#ifdef HB_EXPERIMENTAL_API
- || name_table_overrides.in_error ()
-#endif
- ;
- }
-};
-
-
-#endif /* HB_SUBSET_INPUT_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc
deleted file mode 100644
index 7a2735c529e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-instancer-solver.cc
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright © 2023 Behdad Esfahbod
- *
- * 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.
- */
-
-#include "hb.hh"
-
-/* This file is a straight port of the following:
- *
- * https://github.com/fonttools/fonttools/blob/f73220816264fc383b8a75f2146e8d69e455d398/Lib/fontTools/varLib/instancer/solver.py
- *
- * Where that file returns None for a triple, we return Triple{}.
- * This should be safe.
- */
-
-constexpr static float EPSILON = 1.f / (1 << 14);
-constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14);
-
-struct Triple {
-
- Triple () :
- minimum (0.f), middle (0.f), maximum (0.f) {}
-
- Triple (float minimum_, float middle_, float maximum_) :
- minimum (minimum_), middle (middle_), maximum (maximum_) {}
-
- bool operator == (const Triple &o) const
- {
- return minimum == o.minimum &&
- middle == o.middle &&
- maximum == o.maximum;
- }
-
- float minimum;
- float middle;
- float maximum;
-};
-
-static inline Triple _reverse_negate(const Triple &v)
-{ return {-v.maximum, -v.middle, -v.minimum}; }
-
-
-static inline float supportScalar (float coord, const Triple &tent)
-{
- /* Copied from VarRegionAxis::evaluate() */
- float start = tent.minimum, peak = tent.middle, end = tent.maximum;
-
- if (unlikely (start > peak || peak > end))
- return 1.;
- if (unlikely (start < 0 && end > 0 && peak != 0))
- return 1.;
-
- if (peak == 0 || coord == peak)
- return 1.;
-
- if (coord <= start || end <= coord)
- return 0.;
-
- /* Interpolate */
- if (coord < peak)
- return (coord - start) / (peak - start);
- else
- return (end - coord) / (end - peak);
-}
-
-
-using result_item_t = hb_pair_t<float, Triple>;
-using result_t = hb_vector_t<result_item_t>;
-
-static inline result_t
-_solve (Triple tent, Triple axisLimit, bool negative = false)
-{
- float axisMin = axisLimit.minimum;
- float axisDef = axisLimit.middle;
- float axisMax = axisLimit.maximum;
- float lower = tent.minimum;
- float peak = tent.middle;
- float upper = tent.maximum;
-
- // Mirror the problem such that axisDef <= peak
- if (axisDef > peak)
- {
- result_t vec = _solve (_reverse_negate (tent),
- _reverse_negate (axisLimit),
- !negative);
-
- for (auto &p : vec)
- p = hb_pair (p.first, _reverse_negate (p.second));
-
- return vec;
- }
- // axisDef <= peak
-
- /* case 1: The whole deltaset falls outside the new limit; we can drop it
- *
- * peak
- * 1.........................................o..........
- * / \
- * / \
- * / \
- * / \
- * 0---|-----------|----------|-------- o o----1
- * axisMin axisDef axisMax lower upper
- */
- if (axisMax <= lower && axisMax < peak)
- return result_t{}; // No overlap
-
- /* case 2: Only the peak and outermost bound fall outside the new limit;
- * we keep the deltaset, update peak and outermost bound and scale deltas
- * by the scalar value for the restricted axis at the new limit, and solve
- * recursively.
- *
- * |peak
- * 1...............................|.o..........
- * |/ \
- * / \
- * /| \
- * / | \
- * 0--------------------------- o | o----1
- * lower | upper
- * |
- * axisMax
- *
- * Convert to:
- *
- * 1............................................
- * |
- * o peak
- * /|
- * /x|
- * 0--------------------------- o o upper ----1
- * lower |
- * |
- * axisMax
- */
- if (axisMax < peak)
- {
- float mult = supportScalar (axisMax, tent);
- tent = Triple{lower, axisMax, axisMax};
-
- result_t vec = _solve (tent, axisLimit);
-
- for (auto &p : vec)
- p = hb_pair (p.first * mult, p.second);
-
- return vec;
- }
-
- // lower <= axisDef <= peak <= axisMax
-
- float gain = supportScalar (axisDef, tent);
- result_t out {hb_pair (gain, Triple{})};
-
- // First, the positive side
-
- // outGain is the scalar of axisMax at the tent.
- float outGain = supportScalar (axisMax, tent);
-
- /* Case 3a: Gain is more than outGain. The tent down-slope crosses
- * the axis into negative. We have to split it into multiples.
- *
- * | peak |
- * 1...................|.o.....|..............
- * |/x\_ |
- * gain................+....+_.|..............
- * /| |y\|
- * ................../.|....|..+_......outGain
- * / | | | \
- * 0---|-----------o | | | o----------1
- * axisMin lower | | | upper
- * | | |
- * axisDef | axisMax
- * |
- * crossing
- */
- if (gain > outGain)
- {
- // Crossing point on the axis.
- float crossing = peak + ((1 - gain) * (upper - peak) / (1 - outGain));
-
- Triple loc{peak, peak, crossing};
- float scalar = 1.f;
-
- // The part before the crossing point.
- out.push (hb_pair (scalar - gain, loc));
-
- /* The part after the crossing point may use one or two tents,
- * depending on whether upper is before axisMax or not, in one
- * case we need to keep it down to eternity.
- *
- * Case 3a1, similar to case 1neg; just one tent needed, as in
- * the drawing above.
- */
- if (upper >= axisMax)
- {
- Triple loc {crossing, axisMax, axisMax};
- float scalar = supportScalar (axisMax, tent);
-
- out.push (hb_pair (scalar - gain, loc));
- }
-
- /* Case 3a2: Similar to case 2neg; two tents needed, to keep
- * down to eternity.
- *
- * | peak |
- * 1...................|.o................|...
- * |/ \_ |
- * gain................+....+_............|...
- * /| | \xxxxxxxxxxy|
- * / | | \_xxxxxyyyy|
- * / | | \xxyyyyyy|
- * 0---|-----------o | | o-------|--1
- * axisMin lower | | upper |
- * | | |
- * axisDef | axisMax
- * |
- * crossing
- */
- else
- {
- // A tent's peak cannot fall on axis default. Nudge it.
- if (upper == axisDef)
- upper += EPSILON;
-
- // Downslope.
- Triple loc1 {crossing, upper, axisMax};
- float scalar1 = 0.f;
-
- // Eternity justify.
- Triple loc2 {upper, axisMax, axisMax};
- float scalar2 = 1.f; // supportScalar({"tag": axisMax}, {"tag": tent})
-
- out.push (hb_pair (scalar1 - gain, loc1));
- out.push (hb_pair (scalar2 - gain, loc2));
- }
- }
-
- /* Case 3: Outermost limit still fits within F2Dot14 bounds;
- * we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0
- * or +1.0 will never be applied as implementations must clamp to that range.
- *
- * A second tent is needed for cases when gain is positive, though we add it
- * unconditionally and it will be dropped because scalar ends up 0.
- *
- * TODO: See if we can just move upper closer to adjust the slope, instead of
- * second tent.
- *
- * | peak |
- * 1.........|............o...|..................
- * | /x\ |
- * | /xxx\ |
- * | /xxxxx\|
- * | /xxxxxxx+
- * | /xxxxxxxx|\
- * 0---|-----|------oxxxxxxxxx|xo---------------1
- * axisMin | lower | upper
- * | |
- * axisDef axisMax
- */
- else if (axisDef + (axisMax - axisDef) * 2 >= upper)
- {
- if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper)
- {
- // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
- upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14;
- assert (peak < upper);
- }
-
- // Special-case if peak is at axisMax.
- if (axisMax == peak)
- upper = peak;
-
- Triple loc1 {hb_max (axisDef, lower), peak, upper};
- float scalar1 = 1.f;
-
- Triple loc2 {peak, upper, upper};
- float scalar2 = 0.f;
-
- // Don't add a dirac delta!
- if (axisDef < upper)
- out.push (hb_pair (scalar1 - gain, loc1));
- if (peak < upper)
- out.push (hb_pair (scalar2 - gain, loc2));
- }
-
- /* Case 4: New limit doesn't fit; we need to chop into two tents,
- * because the shape of a triangle with part of one side cut off
- * cannot be represented as a triangle itself.
- *
- * | peak |
- * 1.........|......o.|...................
- * | /x\|
- * | |xxy|\_
- * | /xxxy| \_
- * | |xxxxy| \_
- * | /xxxxy| \_
- * 0---|-----|-oxxxxxx| o----------1
- * axisMin | lower | upper
- * | |
- * axisDef axisMax
- */
- else
- {
- Triple loc1 {hb_max (axisDef, lower), peak, axisMax};
- float scalar1 = 1.f;
-
- Triple loc2 {peak, axisMax, axisMax};
- float scalar2 = supportScalar (axisMax, tent);
-
- out.push (hb_pair (scalar1 - gain, loc1));
- // Don't add a dirac delta!
- if (peak < axisMax)
- out.push (hb_pair (scalar2 - gain, loc2));
- }
-
- /* Now, the negative side
- *
- * Case 1neg: Lower extends beyond axisMin: we chop. Simple.
- *
- * | |peak
- * 1..................|...|.o.................
- * | |/ \
- * gain...............|...+...\...............
- * |x_/| \
- * |/ | \
- * _/| | \
- * 0---------------o | | o----------1
- * lower | | upper
- * | |
- * axisMin axisDef
- */
- if (lower <= axisMin)
- {
- Triple loc {axisMin, axisMin, axisDef};
- float scalar = supportScalar (axisMin, tent);
-
- out.push (hb_pair (scalar - gain, loc));
- }
-
- /* Case 2neg: Lower is betwen axisMin and axisDef: we add two
- * tents to keep it down all the way to eternity.
- *
- * | |peak
- * 1...|...............|.o.................
- * | |/ \
- * gain|...............+...\...............
- * |yxxxxxxxxxxxxx/| \
- * |yyyyyyxxxxxxx/ | \
- * |yyyyyyyyyyyx/ | \
- * 0---|-----------o | o----------1
- * axisMin lower | upper
- * |
- * axisDef
- */
- else
- {
- // A tent's peak cannot fall on axis default. Nudge it.
- if (lower == axisDef)
- lower -= EPSILON;
-
- // Downslope.
- Triple loc1 {axisMin, lower, axisDef};
- float scalar1 = 0.f;
-
- // Eternity justify.
- Triple loc2 {axisMin, axisMin, lower};
- float scalar2 = 0.f;
-
- out.push (hb_pair (scalar1 - gain, loc1));
- out.push (hb_pair (scalar2 - gain, loc2));
- }
-
- return out;
-}
-
-/* Normalizes value based on a min/default/max triple. */
-static inline float normalizeValue (float v, const Triple &triple, bool extrapolate = false)
-{
- /*
- >>> normalizeValue(400, (100, 400, 900))
- 0.0
- >>> normalizeValue(100, (100, 400, 900))
- -1.0
- >>> normalizeValue(650, (100, 400, 900))
- 0.5
- */
- float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
- assert (lower <= def && def <= upper);
-
- if (!extrapolate)
- v = hb_max (hb_min (v, upper), lower);
-
- if ((v == def) || (lower == upper))
- return 0.f;
-
- if ((v < def && lower != def) || (v > def && upper == def))
- return (v - def) / (def - lower);
- else
- {
- assert ((v > def && upper != def) ||
- (v < def && lower == def));
- return (v - def) / (upper - def);
- }
-}
-
-/* Given a tuple (lower,peak,upper) "tent" and new axis limits
- * (axisMin,axisDefault,axisMax), solves how to represent the tent
- * under the new axis configuration. All values are in normalized
- * -1,0,+1 coordinate system. Tent values can be outside this range.
- *
- * Return value: a list of tuples. Each tuple is of the form
- * (scalar,tent), where scalar is a multipler to multiply any
- * delta-sets by, and tent is a new tent for that output delta-set.
- * If tent value is Triple{}, that is a special deltaset that should
- * be always-enabled (called "gain").
- */
-HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit);
-
-result_t
-rebase_tent (Triple tent, Triple axisLimit)
-{
- assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f);
- assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f);
- assert (tent.middle != 0.f);
-
- result_t sols = _solve (tent, axisLimit);
-
- auto n = [&axisLimit] (float v) { return normalizeValue (v, axisLimit, true); };
-
- result_t out;
- for (auto &p : sols)
- {
- if (!p.first) continue;
- if (p.second == Triple{})
- {
- out.push (p);
- continue;
- }
- Triple t = p.second;
- out.push (hb_pair (p.first,
- Triple{n (t.minimum), n (t.middle), n (t.maximum)}));
- }
-
- return sols;
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc
deleted file mode 100644
index aea886864d5..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc
+++ /dev/null
@@ -1,1226 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Roderick Sheeter
- */
-
-#include "hb-subset-plan.hh"
-#include "hb-subset-accelerator.hh"
-#include "hb-map.hh"
-#include "hb-multimap.hh"
-#include "hb-set.hh"
-
-#include "hb-ot-cmap-table.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-layout-gdef-table.hh"
-#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-layout-gsub-table.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "OT/Color/COLR/colrv1-closure.hh"
-#include "OT/Color/CPAL/CPAL.hh"
-#include "hb-ot-var-fvar-table.hh"
-#include "hb-ot-var-avar-table.hh"
-#include "hb-ot-stat-table.hh"
-#include "hb-ot-math-table.hh"
-
-using OT::Layout::GSUB;
-using OT::Layout::GPOS;
-
-typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
-#ifndef HB_NO_SUBSET_CFF
-static inline bool
-_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
- hb_codepoint_t gid,
- hb_set_t *gids_to_retain)
-{
- hb_codepoint_t base_gid, accent_gid;
- if (cff.get_seac_components (gid, &base_gid, &accent_gid))
- {
- gids_to_retain->add (base_gid);
- gids_to_retain->add (accent_gid);
- return true;
- }
- return false;
-}
-#endif
-
-static void
-_remap_palette_indexes (const hb_set_t *palette_indexes,
- hb_map_t *mapping /* OUT */)
-{
- unsigned new_idx = 0;
- for (unsigned palette_index : palette_indexes->iter ())
- {
- if (palette_index == 0xFFFF)
- {
- mapping->set (palette_index, palette_index);
- continue;
- }
- mapping->set (palette_index, new_idx);
- new_idx++;
- }
-}
-
-static void
-_remap_indexes (const hb_set_t *indexes,
- hb_map_t *mapping /* OUT */)
-{
- for (auto _ : + hb_enumerate (indexes->iter ()))
- mapping->set (_.second, _.first);
-
-}
-
-#ifndef HB_NO_SUBSET_LAYOUT
-
-/*
- * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates.
- * Returns true if anything was removed (not including duplicates).
- */
-static bool _filter_tag_list(hb_vector_t<hb_tag_t>* tags, /* IN/OUT */
- const hb_set_t* filter)
-{
- hb_vector_t<hb_tag_t> out;
- out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator.
-
- bool removed = false;
- hb_set_t visited;
-
- for (hb_tag_t tag : *tags)
- {
- if (!tag) continue;
- if (visited.has (tag)) continue;
-
- if (!filter->has (tag))
- {
- removed = true;
- continue;
- }
-
- visited.add (tag);
- out.push (tag);
- }
-
- // The collect function needs a null element to signal end of the array.
- out.push (HB_TAG_NONE);
-
- hb_swap (out, *tags);
- return removed;
-}
-
-template <typename T>
-static void _collect_layout_indices (hb_subset_plan_t *plan,
- const T& table,
- hb_set_t *lookup_indices, /* OUT */
- hb_set_t *feature_indices, /* OUT */
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* OUT */
- hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map /* OUT */)
-{
- unsigned num_features = table.get_feature_count ();
- hb_vector_t<hb_tag_t> features;
- if (!plan->check_success (features.resize (num_features))) return;
- table.get_feature_tags (0, &num_features, features.arrayZ);
- bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features);
-
- unsigned num_scripts = table.get_script_count ();
- hb_vector_t<hb_tag_t> scripts;
- if (!plan->check_success (scripts.resize (num_scripts))) return;
- table.get_script_tags (0, &num_scripts, scripts.arrayZ);
- bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts);
-
- if (!plan->check_success (!features.in_error ()) || !features
- || !plan->check_success (!scripts.in_error ()) || !scripts)
- return;
-
- hb_ot_layout_collect_features (plan->source,
- T::tableTag,
- retain_all_scripts ? nullptr : scripts.arrayZ,
- nullptr,
- retain_all_features ? nullptr : features.arrayZ,
- feature_indices);
-
-#ifndef HB_NO_VAR
- // collect feature substitutes with variations
- if (!plan->user_axes_location.is_empty ())
- {
- hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> conditionset_map;
- OT::hb_collect_feature_substitutes_with_var_context_t c =
- {
- &plan->axes_old_index_tag_map,
- &plan->axes_location,
- feature_record_cond_idx_map,
- feature_substitutes_map,
- feature_indices,
- true,
- 0,
- &conditionset_map
- };
- table.collect_feature_substitutes_with_variations (&c);
- }
-#endif
-
- for (unsigned feature_index : *feature_indices)
- {
- const OT::Feature* f = &(table.get_feature (feature_index));
- const OT::Feature **p = nullptr;
- if (feature_substitutes_map->has (feature_index, &p))
- f = *p;
-
- f->add_lookup_indexes_to (lookup_indices);
- }
-
- // If all axes are pinned then all feature variations will be dropped so there's no need
- // to collect lookups from them.
- if (!plan->all_axes_pinned)
- {
- // TODO(qxliu76): this collection doesn't work correctly for feature variations that are dropped
- // but not applied. The collection will collect and retain the lookup indices
- // associated with those dropped but not activated rules. Since partial instancing
- // isn't yet supported this isn't an issue yet but will need to be fixed for
- // partial instancing.
- table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices);
- }
-}
-
-
-static inline void
-_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g,
- const hb_map_t *lookup_indices,
- const hb_set_t *feature_indices,
- const hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map,
- hb_map_t *duplicate_feature_map /* OUT */)
-{
- if (feature_indices->is_empty ()) return;
- hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features;
- //find out duplicate features after subset
- for (unsigned i : feature_indices->iter ())
- {
- hb_tag_t t = g.get_feature_tag (i);
- if (t == HB_MAP_VALUE_INVALID) continue;
- if (!unique_features.has (t))
- {
- if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
- return;
- if (unique_features.has (t))
- unique_features.get (t)->add (i);
- duplicate_feature_map->set (i, i);
- continue;
- }
-
- bool found = false;
-
- hb_set_t* same_tag_features = unique_features.get (t);
- for (unsigned other_f_index : same_tag_features->iter ())
- {
- const OT::Feature* f = &(g.get_feature (i));
- const OT::Feature **p = nullptr;
- if (feature_substitutes_map->has (i, &p))
- f = *p;
-
- const OT::Feature* other_f = &(g.get_feature (other_f_index));
- if (feature_substitutes_map->has (other_f_index, &p))
- other_f = *p;
-
- auto f_iter =
- + hb_iter (f->lookupIndex)
- | hb_filter (lookup_indices)
- ;
-
- auto other_f_iter =
- + hb_iter (other_f->lookupIndex)
- | hb_filter (lookup_indices)
- ;
-
- bool is_equal = true;
- for (; f_iter && other_f_iter; f_iter++, other_f_iter++)
- {
- unsigned a = *f_iter;
- unsigned b = *other_f_iter;
- if (a != b) { is_equal = false; break; }
- }
-
- if (is_equal == false || f_iter || other_f_iter) continue;
-
- found = true;
- duplicate_feature_map->set (i, other_f_index);
- break;
- }
-
- if (found == false)
- {
- same_tag_features->add (i);
- duplicate_feature_map->set (i, i);
- }
- }
-}
-
-template <typename T>
-static inline void
-_closure_glyphs_lookups_features (hb_subset_plan_t *plan,
- hb_set_t *gids_to_retain,
- hb_map_t *lookups,
- hb_map_t *features,
- script_langsys_map *langsys_map,
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
- hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map)
-{
- hb_blob_ptr_t<T> table = plan->source_table<T> ();
- hb_tag_t table_tag = table->tableTag;
- hb_set_t lookup_indices, feature_indices;
- _collect_layout_indices<T> (plan,
- *table,
- &lookup_indices,
- &feature_indices,
- feature_record_cond_idx_map,
- feature_substitutes_map);
-
- if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
- hb_ot_layout_lookups_substitute_closure (plan->source,
- &lookup_indices,
- gids_to_retain);
- table->closure_lookups (plan->source,
- gids_to_retain,
- &lookup_indices);
- _remap_indexes (&lookup_indices, lookups);
-
- // prune features
- table->prune_features (lookups,
- plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map,
- feature_substitutes_map,
- &feature_indices);
- hb_map_t duplicate_feature_map;
- _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map);
-
- feature_indices.clear ();
- table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices);
- _remap_indexes (&feature_indices, features);
-
- table.destroy ();
-}
-
-#endif
-
-#ifndef HB_NO_VAR
-static inline void
-_generate_varstore_inner_maps (const hb_set_t& varidx_set,
- unsigned subtable_count,
- hb_vector_t<hb_inc_bimap_t> &inner_maps /* OUT */)
-{
- if (varidx_set.is_empty () || subtable_count == 0) return;
-
- inner_maps.resize (subtable_count);
- for (unsigned idx : varidx_set)
- {
- uint16_t major = idx >> 16;
- uint16_t minor = idx & 0xFFFF;
-
- if (major >= subtable_count)
- continue;
- inner_maps[major].add (minor);
- }
-}
-
-static inline hb_font_t*
-_get_hb_font_with_variations (const hb_subset_plan_t *plan)
-{
- hb_font_t *font = hb_font_create (plan->source);
-
- hb_vector_t<hb_variation_t> vars;
- if (!vars.alloc (plan->user_axes_location.get_population ())) {
- hb_font_destroy (font);
- return nullptr;
- }
-
- for (auto _ : plan->user_axes_location)
- {
- hb_variation_t var;
- var.tag = _.first;
- var.value = _.second;
- vars.push (var);
- }
-
-#ifndef HB_NO_VAR
- hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ());
-#endif
- return font;
-}
-
-static inline void
-_collect_layout_variation_indices (hb_subset_plan_t* plan)
-{
- hb_blob_ptr_t<OT::GDEF> gdef = plan->source_table<OT::GDEF> ();
- hb_blob_ptr_t<GPOS> gpos = plan->source_table<GPOS> ();
-
- if (!gdef->has_data ())
- {
- gdef.destroy ();
- gpos.destroy ();
- return;
- }
-
- const OT::VariationStore *var_store = nullptr;
- hb_set_t varidx_set;
- hb_font_t *font = nullptr;
- float *store_cache = nullptr;
- bool collect_delta = plan->pinned_at_default ? false : true;
- if (collect_delta)
- {
- if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
- hb_font_destroy (font);
- gdef.destroy ();
- gpos.destroy ();
- return;
- }
-
- if (gdef->has_var_store ())
- {
- var_store = &(gdef->get_var_store ());
- store_cache = var_store->create_cache ();
- }
- }
-
- OT::hb_collect_variation_indices_context_t c (&varidx_set,
- &plan->layout_variation_idx_delta_map,
- font, var_store,
- &plan->_glyphset_gsub,
- &plan->gpos_lookups,
- store_cache);
- gdef->collect_variation_indices (&c);
-
- if (hb_ot_layout_has_positioning (plan->source))
- gpos->collect_variation_indices (&c);
-
- hb_font_destroy (font);
- var_store->destroy_cache (store_cache);
-
- gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map);
-
- unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0;
- _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps);
-
- gdef.destroy ();
- gpos.destroy ();
-}
-#endif
-
-static inline void
-_cmap_closure (hb_face_t *face,
- const hb_set_t *unicodes,
- hb_set_t *glyphset)
-{
- OT::cmap::accelerator_t cmap (face);
- cmap.table->closure_glyphs (unicodes, glyphset);
-}
-
-static void _colr_closure (hb_face_t *face,
- hb_map_t *layers_map,
- hb_map_t *palettes_map,
- hb_set_t *glyphs_colred)
-{
- OT::COLR::accelerator_t colr (face);
- if (!colr.is_valid ()) return;
-
- hb_set_t palette_indices, layer_indices;
- // Collect all glyphs referenced by COLRv0
- hb_set_t glyphset_colrv0;
- for (hb_codepoint_t gid : *glyphs_colred)
- colr.closure_glyphs (gid, &glyphset_colrv0);
-
- glyphs_colred->union_ (glyphset_colrv0);
-
- //closure for COLRv1
- colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices);
-
- colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
- _remap_indexes (&layer_indices, layers_map);
- _remap_palette_indexes (&palette_indices, palettes_map);
-}
-
-static inline void
-_math_closure (hb_subset_plan_t *plan,
- hb_set_t *glyphset)
-{
- hb_blob_ptr_t<OT::MATH> math = plan->source_table<OT::MATH> ();
- if (math->has_data ())
- math->closure_glyphs (glyphset);
- math.destroy ();
-}
-
-
-static inline void
-_remove_invalid_gids (hb_set_t *glyphs,
- unsigned int num_glyphs)
-{
- glyphs->del_range (num_glyphs, HB_SET_VALUE_INVALID);
-}
-
-static void
-_populate_unicodes_to_retain (const hb_set_t *unicodes,
- const hb_set_t *glyphs,
- hb_subset_plan_t *plan)
-{
- OT::cmap::accelerator_t cmap (plan->source);
- unsigned size_threshold = plan->source->get_num_glyphs ();
- if (glyphs->is_empty () && unicodes->get_population () < size_threshold)
- {
-
- const hb_map_t* unicode_to_gid = nullptr;
- if (plan->accelerator)
- unicode_to_gid = &plan->accelerator->unicode_to_gid;
-
- // This is approach to collection is faster, but can only be used if glyphs
- // are not being explicitly added to the subset and the input unicodes set is
- // not excessively large (eg. an inverted set).
- plan->unicode_to_new_gid_list.alloc (unicodes->get_population ());
- if (!unicode_to_gid) {
- for (hb_codepoint_t cp : *unicodes)
- {
- hb_codepoint_t gid;
- if (!cmap.get_nominal_glyph (cp, &gid))
- {
- DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
- continue;
- }
-
- plan->codepoint_to_glyph->set (cp, gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
- }
- } else {
- // Use in memory unicode to gid map it's faster then looking up from
- // the map. This code is mostly duplicated from above to avoid doing
- // conditionals on the presence of the unicode_to_gid map each
- // iteration.
- for (hb_codepoint_t cp : *unicodes)
- {
- hb_codepoint_t gid = unicode_to_gid->get (cp);
- if (gid == HB_MAP_VALUE_INVALID)
- {
- DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
- continue;
- }
-
- plan->codepoint_to_glyph->set (cp, gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
- }
- }
- }
- else
- {
- // This approach is slower, but can handle adding in glyphs to the subset and will match
- // them with cmap entries.
-
- hb_map_t unicode_glyphid_map_storage;
- hb_set_t cmap_unicodes_storage;
- const hb_map_t* unicode_glyphid_map = &unicode_glyphid_map_storage;
- const hb_set_t* cmap_unicodes = &cmap_unicodes_storage;
-
- if (!plan->accelerator) {
- cmap.collect_mapping (&cmap_unicodes_storage, &unicode_glyphid_map_storage);
- plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population ()
- + glyphs->get_population (),
- cmap_unicodes->get_population ()));
- } else {
- unicode_glyphid_map = &plan->accelerator->unicode_to_gid;
- cmap_unicodes = &plan->accelerator->unicodes;
- }
-
- if (plan->accelerator &&
- unicodes->get_population () < cmap_unicodes->get_population () &&
- glyphs->get_population () < cmap_unicodes->get_population ())
- {
- auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes;
- for (hb_codepoint_t gid : *glyphs)
- {
- auto unicodes = gid_to_unicodes.get (gid);
-
- for (hb_codepoint_t cp : unicodes)
- {
- plan->codepoint_to_glyph->set (cp, gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
- }
- }
- for (hb_codepoint_t cp : *unicodes)
- {
- /* Don't double-add entry. */
- if (plan->codepoint_to_glyph->has (cp))
- continue;
-
- hb_codepoint_t *gid;
- if (!unicode_glyphid_map->has(cp, &gid))
- continue;
-
- plan->codepoint_to_glyph->set (cp, *gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, *gid));
- }
- plan->unicode_to_new_gid_list.qsort ();
- }
- else
- {
- for (hb_codepoint_t cp : *cmap_unicodes)
- {
- hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
- if (!unicodes->has (cp) && !glyphs->has (gid))
- continue;
-
- plan->codepoint_to_glyph->set (cp, gid);
- plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
- }
- }
-
- /* Add gids which where requested, but not mapped in cmap */
- for (hb_codepoint_t gid : *glyphs)
- {
- if (gid >= plan->source->get_num_glyphs ())
- break;
- plan->_glyphset_gsub.add (gid);
- }
- }
-
- auto &arr = plan->unicode_to_new_gid_list;
- if (arr.length)
- {
- plan->unicodes.add_sorted_array (&arr.arrayZ->first, arr.length, sizeof (*arr.arrayZ));
- plan->_glyphset_gsub.add_array (&arr.arrayZ->second, arr.length, sizeof (*arr.arrayZ));
- }
-}
-
-#ifndef HB_COMPOSITE_OPERATIONS_PER_GLYPH
-#define HB_COMPOSITE_OPERATIONS_PER_GLYPH 64
-#endif
-
-static unsigned
-_glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
- hb_codepoint_t gid,
- hb_set_t *gids_to_retain,
- int operation_count,
- unsigned depth = 0)
-{
- if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
- if (unlikely (--operation_count < 0)) return operation_count;
- /* Check if is already visited */
- if (gids_to_retain->has (gid)) return operation_count;
-
- gids_to_retain->add (gid);
-
- for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
- operation_count =
- _glyf_add_gid_and_children (glyf,
- item.get_gid (),
- gids_to_retain,
- operation_count,
- depth);
-
-#ifndef HB_NO_VAR_COMPOSITES
- for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ())
- {
- operation_count =
- _glyf_add_gid_and_children (glyf,
- item.get_gid (),
- gids_to_retain,
- operation_count,
- depth);
- }
-#endif
-
- return operation_count;
-}
-
-static void
-_nameid_closure (hb_subset_plan_t* plan,
- hb_set_t* drop_tables)
-{
-#ifndef HB_NO_STYLE
- plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
-#endif
-#ifndef HB_NO_VAR
- if (!plan->all_axes_pinned)
- plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
-#endif
-#ifndef HB_NO_COLOR
- if (!drop_tables->has (HB_OT_TAG_CPAL))
- plan->source->table.CPAL->collect_name_ids (&plan->colr_palettes, &plan->name_ids);
-#endif
-
-#ifndef HB_NO_SUBSET_LAYOUT
- if (!drop_tables->has (HB_OT_TAG_GPOS))
- {
- hb_blob_ptr_t<GPOS> gpos = plan->source_table<GPOS> ();
- gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids);
- gpos.destroy ();
- }
- if (!drop_tables->has (HB_OT_TAG_GSUB))
- {
- hb_blob_ptr_t<GSUB> gsub = plan->source_table<GSUB> ();
- gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids);
- gsub.destroy ();
- }
-#endif
-}
-
-static void
-_populate_gids_to_retain (hb_subset_plan_t* plan,
- hb_set_t* drop_tables)
-{
- OT::glyf_accelerator_t glyf (plan->source);
-#ifndef HB_NO_SUBSET_CFF
- OT::cff1::accelerator_t cff (plan->source);
-#endif
-
- plan->_glyphset_gsub.add (0); // Not-def
-
- _cmap_closure (plan->source, &plan->unicodes, &plan->_glyphset_gsub);
-
-#ifndef HB_NO_SUBSET_LAYOUT
- if (!drop_tables->has (HB_OT_TAG_GSUB))
- // closure all glyphs/lookups/features needed for GSUB substitutions.
- _closure_glyphs_lookups_features<GSUB> (
- plan,
- &plan->_glyphset_gsub,
- &plan->gsub_lookups,
- &plan->gsub_features,
- &plan->gsub_langsys,
- &plan->gsub_feature_record_cond_idx_map,
- &plan->gsub_feature_substitutes_map);
-
- if (!drop_tables->has (HB_OT_TAG_GPOS))
- _closure_glyphs_lookups_features<GPOS> (
- plan,
- &plan->_glyphset_gsub,
- &plan->gpos_lookups,
- &plan->gpos_features,
- &plan->gpos_langsys,
- &plan->gpos_feature_record_cond_idx_map,
- &plan->gpos_feature_substitutes_map);
-#endif
- _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ());
-
- plan->_glyphset_mathed = plan->_glyphset_gsub;
- if (!drop_tables->has (HB_OT_TAG_MATH))
- {
- _math_closure (plan, &plan->_glyphset_mathed);
- _remove_invalid_gids (&plan->_glyphset_mathed, plan->source->get_num_glyphs ());
- }
-
- hb_set_t cur_glyphset = plan->_glyphset_mathed;
- if (!drop_tables->has (HB_OT_TAG_COLR))
- {
- _colr_closure (plan->source, &plan->colrv1_layers, &plan->colr_palettes, &cur_glyphset);
- _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
- }
-
- plan->_glyphset_colred = cur_glyphset;
-
- _nameid_closure (plan, drop_tables);
- /* Populate a full set of glyphs to retain by adding all referenced
- * composite glyphs. */
- if (glyf.has_data ())
- for (hb_codepoint_t gid : cur_glyphset)
- _glyf_add_gid_and_children (glyf, gid, &plan->_glyphset,
- cur_glyphset.get_population () * HB_COMPOSITE_OPERATIONS_PER_GLYPH);
- else
- plan->_glyphset.union_ (cur_glyphset);
-#ifndef HB_NO_SUBSET_CFF
- if (!plan->accelerator || plan->accelerator->has_seac)
- {
- bool has_seac = false;
- if (cff.is_valid ())
- for (hb_codepoint_t gid : cur_glyphset)
- if (_add_cff_seac_components (cff, gid, &plan->_glyphset))
- has_seac = true;
- plan->has_seac = has_seac;
- }
-#endif
-
- _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ());
-
-
-#ifndef HB_NO_VAR
- if (!drop_tables->has (HB_OT_TAG_GDEF))
- _collect_layout_variation_indices (plan);
-#endif
-}
-
-static void
-_create_glyph_map_gsub (const hb_set_t* glyph_set_gsub,
- const hb_map_t* glyph_map,
- hb_map_t* out)
-{
- + hb_iter (glyph_set_gsub)
- | hb_map ([&] (hb_codepoint_t gid) {
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid,
- glyph_map->get (gid));
- })
- | hb_sink (out)
- ;
-}
-
-static void
-_create_old_gid_to_new_gid_map (const hb_face_t *face,
- bool retain_gids,
- const hb_set_t *all_gids_to_retain,
- hb_map_t *glyph_map, /* OUT */
- hb_map_t *reverse_glyph_map, /* OUT */
- unsigned int *num_glyphs /* OUT */)
-{
- unsigned pop = all_gids_to_retain->get_population ();
- reverse_glyph_map->resize (pop);
- glyph_map->resize (pop);
-
- if (!retain_gids)
- {
- + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
- | hb_sink (reverse_glyph_map)
- ;
- *num_glyphs = reverse_glyph_map->get_population ();
- }
- else
- {
- + hb_iter (all_gids_to_retain)
- | hb_map ([] (hb_codepoint_t _) {
- return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _);
- })
- | hb_sink (reverse_glyph_map)
- ;
-
- hb_codepoint_t max_glyph = HB_SET_VALUE_INVALID;
- hb_set_previous (all_gids_to_retain, &max_glyph);
-
- *num_glyphs = max_glyph + 1;
- }
-
- + reverse_glyph_map->iter ()
- | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse)
- | hb_sink (glyph_map)
- ;
-}
-
-#ifndef HB_NO_VAR
-static void
-_normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
-{
- if (plan->user_axes_location.is_empty ())
- return;
-
- hb_array_t<const OT::AxisRecord> axes = face->table.fvar->get_axes ();
- plan->normalized_coords.resize (axes.length);
-
- bool has_avar = face->table.avar->has_data ();
- const OT::SegmentMaps *seg_maps = nullptr;
- unsigned avar_axis_count = 0;
- if (has_avar)
- {
- seg_maps = face->table.avar->get_segment_maps ();
- avar_axis_count = face->table.avar->get_axis_count();
- }
-
- bool axis_not_pinned = false;
- unsigned old_axis_idx = 0, new_axis_idx = 0;
- for (const auto& axis : axes)
- {
- hb_tag_t axis_tag = axis.get_axis_tag ();
- plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag);
-
- if (!plan->user_axes_location.has (axis_tag))
- {
- axis_not_pinned = true;
- plan->axes_index_map.set (old_axis_idx, new_axis_idx);
- new_axis_idx++;
- }
- else
- {
- int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag));
- if (has_avar && old_axis_idx < avar_axis_count)
- {
- normalized_v = seg_maps->map (normalized_v);
- }
- plan->axes_location.set (axis_tag, normalized_v);
- if (normalized_v != 0)
- plan->pinned_at_default = false;
-
- plan->normalized_coords[old_axis_idx] = normalized_v;
- }
-
- old_axis_idx++;
-
- if (has_avar && old_axis_idx < avar_axis_count)
- seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
- }
- plan->all_axes_pinned = !axis_not_pinned;
-}
-
-static void
-_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan)
-{
- if (!plan->normalized_coords) return;
- OT::cff2::accelerator_t cff2 (plan->source);
- if (!cff2.is_valid ()) return;
-
- hb_font_t *font = nullptr;
- if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan))))
- {
- hb_font_destroy (font);
- return;
- }
-
- hb_glyph_extents_t extents = {0x7FFF, -0x7FFF};
- OT::hmtx_accelerator_t _hmtx (plan->source);
- float *hvar_store_cache = nullptr;
- if (_hmtx.has_data () && _hmtx.var_table.get_length ())
- hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache ();
-
- OT::vmtx_accelerator_t _vmtx (plan->source);
- float *vvar_store_cache = nullptr;
- if (_vmtx.has_data () && _vmtx.var_table.get_length ())
- vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache ();
-
- for (auto p : *plan->glyph_map)
- {
- hb_codepoint_t old_gid = p.first;
- hb_codepoint_t new_gid = p.second;
- if (!cff2.get_extents (font, old_gid, &extents)) continue;
- bool has_bounds_info = true;
- if (extents.x_bearing == 0 && extents.width == 0 &&
- extents.height == 0 && extents.y_bearing == 0)
- has_bounds_info = false;
-
- if (has_bounds_info)
- {
- plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing);
- plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width);
- plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing);
- plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height);
- }
-
- if (_hmtx.has_data ())
- {
- int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid);
- if (_hmtx.var_table.get_length ())
- hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
- hvar_store_cache));
- int lsb = extents.x_bearing;
- if (!has_bounds_info)
- {
- if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
- continue;
- }
- plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
- plan->bounds_width_map.set (new_gid, extents.width);
- }
-
- if (_vmtx.has_data ())
- {
- int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid);
- if (_vmtx.var_table.get_length ())
- vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
- vvar_store_cache));
-
- int tsb = extents.y_bearing;
- if (!has_bounds_info)
- {
- if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb))
- continue;
- }
- plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
- plan->bounds_height_map.set (new_gid, extents.height);
- }
- }
- hb_font_destroy (font);
- if (hvar_store_cache)
- _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache);
- if (vvar_store_cache)
- _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
-}
-#endif
-
-hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
- const hb_subset_input_t *input)
-{
- successful = true;
- flags = input->flags;
-
- unicode_to_new_gid_list.init ();
-
- name_ids = *input->sets.name_ids;
- name_languages = *input->sets.name_languages;
- layout_features = *input->sets.layout_features;
- layout_scripts = *input->sets.layout_scripts;
- glyphs_requested = *input->sets.glyphs;
- drop_tables = *input->sets.drop_tables;
- no_subset_tables = *input->sets.no_subset_tables;
- source = hb_face_reference (face);
- dest = hb_face_builder_create ();
-
- codepoint_to_glyph = hb_map_create ();
- glyph_map = hb_map_create ();
- reverse_glyph_map = hb_map_create ();
-
- gdef_varstore_inner_maps.init ();
-
- user_axes_location = input->axes_location;
- all_axes_pinned = false;
- pinned_at_default = true;
-
-#ifdef HB_EXPERIMENTAL_API
- for (auto _ : input->name_table_overrides)
- {
- hb_bytes_t name_bytes = _.second;
- unsigned len = name_bytes.length;
- char *name_str = (char *) hb_malloc (len);
- if (unlikely (!check_success (name_str)))
- break;
-
- hb_memcpy (name_str, name_bytes.arrayZ, len);
- name_table_overrides.set (_.first, hb_bytes_t (name_str, len));
- }
-#endif
-
- void* accel = hb_face_get_user_data(face, hb_subset_accelerator_t::user_data_key());
-
- attach_accelerator_data = input->attach_accelerator_data;
- force_long_loca = input->force_long_loca;
- if (accel)
- accelerator = (hb_subset_accelerator_t*) accel;
-
-
- if (unlikely (in_error ()))
- return;
-
-#ifndef HB_NO_VAR
- _normalize_axes_location (face, this);
-#endif
-
- _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this);
-
- _populate_gids_to_retain (this, input->sets.drop_tables);
- if (unlikely (in_error ()))
- return;
-
- _create_old_gid_to_new_gid_map (face,
- input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
- &_glyphset,
- glyph_map,
- reverse_glyph_map,
- &_num_output_glyphs);
-
- _create_glyph_map_gsub (
- &_glyphset_gsub,
- glyph_map,
- &glyph_map_gsub);
-
- // Now that we have old to new gid map update the unicode to new gid list.
- for (unsigned i = 0; i < unicode_to_new_gid_list.length; i++)
- {
- // Use raw array access for performance.
- unicode_to_new_gid_list.arrayZ[i].second =
- glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second);
- }
-
- if (unlikely (in_error ()))
- return;
-
-#ifndef HB_NO_VAR
- _update_instance_metrics_map_from_cff2 (this);
-#endif
-
- if (attach_accelerator_data)
- {
- hb_multimap_t gid_to_unicodes;
-
- hb_map_t &unicode_to_gid = *codepoint_to_glyph;
-
- for (auto unicode : unicodes)
- {
- auto gid = unicode_to_gid[unicode];
- gid_to_unicodes.add (gid, unicode);
- }
-
- inprogress_accelerator =
- hb_subset_accelerator_t::create (*codepoint_to_glyph,
- gid_to_unicodes,
- unicodes,
- has_seac);
- }
-}
-
-/**
- * hb_subset_plan_create_or_fail:
- * @face: font face to create the plan for.
- * @input: a #hb_subset_input_t input.
- *
- * Computes a plan for subsetting the supplied face according
- * to a provided input. The plan describes
- * which tables and glyphs should be retained.
- *
- * Return value: (transfer full): New subset plan. Destroy with
- * hb_subset_plan_destroy(). If there is a failure creating the plan
- * nullptr will be returned.
- *
- * Since: 4.0.0
- **/
-hb_subset_plan_t *
-hb_subset_plan_create_or_fail (hb_face_t *face,
- const hb_subset_input_t *input)
-{
- hb_subset_plan_t *plan;
- if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> (face, input))))
- return nullptr;
-
- if (unlikely (plan->in_error ()))
- {
- hb_subset_plan_destroy (plan);
- return nullptr;
- }
-
- return plan;
-}
-
-/**
- * hb_subset_plan_destroy:
- * @plan: a #hb_subset_plan_t
- *
- * Decreases the reference count on @plan, and if it reaches zero, destroys
- * @plan, freeing all memory.
- *
- * Since: 4.0.0
- **/
-void
-hb_subset_plan_destroy (hb_subset_plan_t *plan)
-{
- if (!hb_object_destroy (plan)) return;
-
- hb_free (plan);
-}
-
-/**
- * hb_subset_plan_old_to_new_glyph_mapping:
- * @plan: a subsetting plan.
- *
- * Returns the mapping between glyphs in the original font to glyphs in the
- * subset that will be produced by @plan
- *
- * Return value: (transfer none):
- * A pointer to the #hb_map_t of the mapping.
- *
- * Since: 4.0.0
- **/
-hb_map_t *
-hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan)
-{
- return plan->glyph_map;
-}
-
-/**
- * hb_subset_plan_new_to_old_glyph_mapping:
- * @plan: a subsetting plan.
- *
- * Returns the mapping between glyphs in the subset that will be produced by
- * @plan and the glyph in the original font.
- *
- * Return value: (transfer none):
- * A pointer to the #hb_map_t of the mapping.
- *
- * Since: 4.0.0
- **/
-hb_map_t *
-hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan)
-{
- return plan->reverse_glyph_map;
-}
-
-/**
- * hb_subset_plan_unicode_to_old_glyph_mapping:
- * @plan: a subsetting plan.
- *
- * Returns the mapping between codepoints in the original font and the
- * associated glyph id in the original font.
- *
- * Return value: (transfer none):
- * A pointer to the #hb_map_t of the mapping.
- *
- * Since: 4.0.0
- **/
-hb_map_t *
-hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan)
-{
- return plan->codepoint_to_glyph;
-}
-
-/**
- * hb_subset_plan_reference: (skip)
- * @plan: a #hb_subset_plan_t object.
- *
- * Increases the reference count on @plan.
- *
- * Return value: @plan.
- *
- * Since: 4.0.0
- **/
-hb_subset_plan_t *
-hb_subset_plan_reference (hb_subset_plan_t *plan)
-{
- return hb_object_reference (plan);
-}
-
-/**
- * hb_subset_plan_set_user_data: (skip)
- * @plan: a #hb_subset_plan_t object.
- * @key: The user-data key to set
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
- *
- * Attaches a user-data key/data pair to the given subset plan object.
- *
- * Return value: `true` if success, `false` otherwise
- *
- * Since: 4.0.0
- **/
-hb_bool_t
-hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
- hb_user_data_key_t *key,
- void *data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
-{
- return hb_object_set_user_data (plan, key, data, destroy, replace);
-}
-
-/**
- * hb_subset_plan_get_user_data: (skip)
- * @plan: a #hb_subset_plan_t object.
- * @key: The user-data key to query
- *
- * Fetches the user data associated with the specified key,
- * attached to the specified subset plan object.
- *
- * Return value: (transfer none): A pointer to the user data
- *
- * Since: 4.0.0
- **/
-void *
-hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
- hb_user_data_key_t *key)
-{
- return hb_object_get_user_data (plan, key);
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
deleted file mode 100644
index e34eeb89ae8..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Roderick Sheeter
- */
-
-#ifndef HB_SUBSET_PLAN_HH
-#define HB_SUBSET_PLAN_HH
-
-#include "hb.hh"
-
-#include "hb-subset.h"
-#include "hb-subset-input.hh"
-#include "hb-subset-accelerator.hh"
-
-#include "hb-map.hh"
-#include "hb-bimap.hh"
-#include "hb-set.hh"
-
-namespace OT {
-struct Feature;
-}
-
-struct head_maxp_info_t
-{
- head_maxp_info_t ()
- :xMin (0x7FFF), xMax (-0x7FFF), yMin (0x7FFF), yMax (-0x7FFF),
- maxPoints (0), maxContours (0),
- maxCompositePoints (0),
- maxCompositeContours (0),
- maxComponentElements (0),
- maxComponentDepth (0),
- allXMinIsLsb (true) {}
-
- int xMin;
- int xMax;
- int yMin;
- int yMax;
- unsigned maxPoints;
- unsigned maxContours;
- unsigned maxCompositePoints;
- unsigned maxCompositeContours;
- unsigned maxComponentElements;
- unsigned maxComponentDepth;
- bool allXMinIsLsb;
-};
-
-typedef struct head_maxp_info_t head_maxp_info_t;
-
-struct hb_subset_plan_t
-{
- HB_INTERNAL hb_subset_plan_t (hb_face_t *,
- const hb_subset_input_t *input);
-
- ~hb_subset_plan_t()
- {
- hb_face_destroy (source);
- hb_face_destroy (dest);
-
- hb_map_destroy (codepoint_to_glyph);
- hb_map_destroy (glyph_map);
- hb_map_destroy (reverse_glyph_map);
-
-#ifdef HB_EXPERIMENTAL_API
- for (auto _ : name_table_overrides)
- _.second.fini ();
-#endif
-
- if (inprogress_accelerator)
- hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
- }
-
- hb_object_header_t header;
-
- bool successful;
- unsigned flags;
- bool attach_accelerator_data = false;
- bool force_long_loca = false;
-
- // For each cp that we'd like to retain maps to the corresponding gid.
- hb_set_t unicodes;
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
-
- // name_ids we would like to retain
- hb_set_t name_ids;
-
- // name_languages we would like to retain
- hb_set_t name_languages;
-
- //layout features which will be preserved
- hb_set_t layout_features;
-
- // layout scripts which will be preserved.
- hb_set_t layout_scripts;
-
- //glyph ids requested to retain
- hb_set_t glyphs_requested;
-
- // Tables which should not be processed, just pass them through.
- hb_set_t no_subset_tables;
-
- // Tables which should be dropped.
- hb_set_t drop_tables;
-
- // The glyph subset
- hb_map_t *codepoint_to_glyph; // Needs to be heap-allocated
-
- // Old -> New glyph id mapping
- hb_map_t *glyph_map; // Needs to be heap-allocated
- hb_map_t *reverse_glyph_map; // Needs to be heap-allocated
- hb_map_t glyph_map_gsub;
-
- // Plan is only good for a specific source/dest so keep them with it
- hb_face_t *source;
- hb_face_t *dest;
-
- unsigned int _num_output_glyphs;
- hb_set_t _glyphset;
- hb_set_t _glyphset_gsub;
- hb_set_t _glyphset_mathed;
- hb_set_t _glyphset_colred;
-
- //active lookups we'd like to retain
- hb_map_t gsub_lookups;
- hb_map_t gpos_lookups;
-
- //active langsys we'd like to retain
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gsub_langsys;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gpos_langsys;
-
- //active features after removing redundant langsys and prune_features
- hb_map_t gsub_features;
- hb_map_t gpos_features;
-
- //active feature variation records/condition index with variations
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gsub_feature_record_cond_idx_map;
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gpos_feature_record_cond_idx_map;
-
- //feature index-> address of substituation feature table mapping with
- //variations
- hb_hashmap_t<unsigned, const OT::Feature*> gsub_feature_substitutes_map;
- hb_hashmap_t<unsigned, const OT::Feature*> gpos_feature_substitutes_map;
-
- //active layers/palettes we'd like to retain
- hb_map_t colrv1_layers;
- hb_map_t colr_palettes;
-
- //Old layout item variation index -> (New varidx, delta) mapping
- hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> layout_variation_idx_delta_map;
-
- //gdef varstore retained varidx mapping
- hb_vector_t<hb_inc_bimap_t> gdef_varstore_inner_maps;
-
- hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
- //normalized axes location map
- hb_hashmap_t<hb_tag_t, int> axes_location;
- hb_vector_t<int> normalized_coords;
- //user specified axes location map
- hb_hashmap_t<hb_tag_t, float> user_axes_location;
- //retained old axis index -> new axis index mapping in fvar axis array
- hb_map_t axes_index_map;
- //axis_index->axis_tag mapping in fvar axis array
- hb_map_t axes_old_index_tag_map;
- bool all_axes_pinned;
- bool pinned_at_default;
- bool has_seac;
-
- //hmtx metrics map: new gid->(advance, lsb)
- mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> hmtx_map;
- //vmtx metrics map: new gid->(advance, lsb)
- mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> vmtx_map;
- //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
- mutable hb_map_t bounds_width_map;
- //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
- mutable hb_map_t bounds_height_map;
-
- //recalculated head/maxp table info after instancing
- mutable head_maxp_info_t head_maxp_info;
-
-#ifdef HB_EXPERIMENTAL_API
- // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
- // None to indicate should remove
- hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
-#endif
-
- const hb_subset_accelerator_t* accelerator;
- hb_subset_accelerator_t* inprogress_accelerator;
-
- public:
-
- template<typename T>
- hb_blob_ptr_t<T> source_table()
- {
- hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
-
- auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache;
- if (cache
- && !cache->in_error ()
- && cache->has (+T::tableTag)) {
- return hb_blob_reference (cache->get (+T::tableTag).get ());
- }
-
- hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)};
- hb_blob_t* ret = hb_blob_reference (table_blob.get ());
-
- if (likely (cache))
- cache->set (+T::tableTag, std::move (table_blob));
-
- return ret;
- }
-
- bool in_error () const { return !successful; }
-
- bool check_success(bool success)
- {
- successful = (successful && success);
- return successful;
- }
-
- /*
- * The set of input glyph ids which will be retained in the subset.
- * Does NOT include ids kept due to retain_gids. You probably want to use
- * glyph_map/reverse_glyph_map.
- */
- inline const hb_set_t *
- glyphset () const
- {
- return &_glyphset;
- }
-
- /*
- * The set of input glyph ids which will be retained in the subset.
- */
- inline const hb_set_t *
- glyphset_gsub () const
- {
- return &_glyphset_gsub;
- }
-
- /*
- * The total number of output glyphs in the final subset.
- */
- inline unsigned int
- num_output_glyphs () const
- {
- return _num_output_glyphs;
- }
-
- /*
- * Given an output gid , returns true if that glyph id is an empty
- * glyph (ie. it's a gid that we are dropping all data for).
- */
- inline bool is_empty_glyph (hb_codepoint_t gid) const
- {
- return !_glyphset.has (gid);
- }
-
- inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
- hb_codepoint_t *new_gid) const
- {
- hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
- if (old_gid == HB_MAP_VALUE_INVALID)
- return false;
-
- return new_gid_for_old_gid (old_gid, new_gid);
- }
-
- inline bool new_gid_for_old_gid (hb_codepoint_t old_gid,
- hb_codepoint_t *new_gid) const
- {
- hb_codepoint_t gid = glyph_map->get (old_gid);
- if (gid == HB_MAP_VALUE_INVALID)
- return false;
-
- *new_gid = gid;
- return true;
- }
-
- inline bool old_gid_for_new_gid (hb_codepoint_t new_gid,
- hb_codepoint_t *old_gid) const
- {
- hb_codepoint_t gid = reverse_glyph_map->get (new_gid);
- if (gid == HB_MAP_VALUE_INVALID)
- return false;
-
- *old_gid = gid;
- return true;
- }
-
- inline bool
- add_table (hb_tag_t tag,
- hb_blob_t *contents)
- {
- if (HB_DEBUG_SUBSET)
- {
- hb_blob_t *source_blob = source->reference_table (tag);
- DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %u bytes, source %u bytes",
- HB_UNTAG(tag),
- hb_blob_get_length (contents),
- hb_blob_get_length (source_blob));
- hb_blob_destroy (source_blob);
- }
- return hb_face_builder_add_table (dest, tag, contents);
- }
-};
-
-#endif /* HB_SUBSET_PLAN_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.cc
deleted file mode 100644
index 6a29b35be7e..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright © 2022 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.
- *
- */
-#include "hb-repacker.hh"
-
-#ifdef HB_EXPERIMENTAL_API
-
-/**
- * hb_subset_repack_or_fail:
- * @table_tag: tag of the table being packed, needed to allow table specific optimizations.
- * @hb_objects: raw array of struct hb_object_t, which provides
- * object graph info
- * @num_hb_objs: number of hb_object_t in the hb_objects array.
- *
- * Given the input object graph info, repack a table to eliminate
- * offset overflows. A nullptr is returned if the repacking attempt fails.
- * Table specific optimizations (eg. extension promotion in GSUB/GPOS) may be performed.
- * Passing HB_TAG_NONE will disable table specific optimizations.
- *
- * XSince: EXPERIMENTAL
- **/
-hb_blob_t* hb_subset_repack_or_fail (hb_tag_t table_tag,
- hb_object_t* hb_objects,
- unsigned num_hb_objs)
-{
- hb_vector_t<const hb_object_t *> packed;
- packed.alloc (num_hb_objs + 1);
- packed.push (nullptr);
- for (unsigned i = 0 ; i < num_hb_objs ; i++)
- packed.push (&(hb_objects[i]));
-
- return hb_resolve_overflows (packed,
- table_tag,
- 20,
- true);
-}
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.h b/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.h
deleted file mode 100644
index 245cf607657..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-repacker.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright © 2022 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.
- *
- */
-
-#ifndef HB_SUBSET_REPACKER_H
-#define HB_SUBSET_REPACKER_H
-
-#include "hb.h"
-
-HB_BEGIN_DECLS
-
-#ifdef HB_EXPERIMENTAL_API
-/*
- * struct hb_link_t
- * width: offsetSize in bytes
- * position: position of the offset field in bytes
- * from beginning of subtable
- * objidx: index of subtable
- */
-struct hb_link_t
-{
- unsigned width;
- unsigned position;
- unsigned objidx;
-};
-
-typedef struct hb_link_t hb_link_t;
-
-/*
- * struct hb_object_t
- * head: start of object data
- * tail: end of object data
- * num_real_links: num of offset field in the object
- * real_links: pointer to array of offset info
- * num_virtual_links: num of objects that must be packed
- * after current object in the final serialized order
- * virtual_links: array of virtual link info
- */
-struct hb_object_t
-{
- char *head;
- char *tail;
- unsigned num_real_links;
- hb_link_t *real_links;
- unsigned num_virtual_links;
- hb_link_t *virtual_links;
-};
-
-typedef struct hb_object_t hb_object_t;
-
-HB_EXTERN hb_blob_t*
-hb_subset_repack_or_fail (hb_tag_t table_tag,
- hb_object_t* hb_objects,
- unsigned num_hb_objs);
-
-#endif
-
-HB_END_DECLS
-
-#endif /* HB_SUBSET_REPACKER_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
deleted file mode 100644
index 5ea422983c5..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Rod Sheeter, Behdad Esfahbod
- */
-
-#include "hb.hh"
-#include "hb-open-type.hh"
-
-#include "hb-subset.hh"
-
-#include "hb-open-file.hh"
-#include "hb-ot-cmap-table.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-hdmx-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hhea-table.hh"
-#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-maxp-table.hh"
-#include "OT/Color/CBDT/CBDT.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "OT/Color/CPAL/CPAL.hh"
-#include "OT/Color/sbix/sbix.hh"
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-post-table.hh"
-#include "hb-ot-post-table-v2subset.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
-#include "hb-ot-vorg-table.hh"
-#include "hb-ot-name-table.hh"
-#include "hb-ot-layout-gsub-table.hh"
-#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-var-cvar-table.hh"
-#include "hb-ot-var-fvar-table.hh"
-#include "hb-ot-var-gvar-table.hh"
-#include "hb-ot-var-hvar-table.hh"
-#include "hb-ot-math-table.hh"
-#include "hb-ot-stat-table.hh"
-#include "hb-repacker.hh"
-#include "hb-subset-accelerator.hh"
-
-using OT::Layout::GSUB;
-using OT::Layout::GPOS;
-
-/**
- * SECTION:hb-subset
- * @title: hb-subset
- * @short_description: Subsets font files.
- * @include: hb-subset.h
- *
- * Subsetting reduces the codepoint coverage of font files and removes all data
- * that is no longer needed. A subset input describes the desired subset. The input is
- * provided along with a font to the subsetting operation. Output is a new font file
- * containing only the data specified in the input.
- *
- * Currently most outline and bitmap tables are supported: glyf, CFF, CFF2, sbix,
- * COLR, and CBDT/CBLC. This also includes fonts with variable outlines via OpenType
- * variations. Notably EBDT/EBLC and SVG are not supported. Layout subsetting is supported
- * only for OpenType Layout tables (GSUB, GPOS, GDEF). Notably subsetting of graphite or AAT tables
- * is not yet supported.
- *
- * Fonts with graphite or AAT tables may still be subsetted but will likely need to use the
- * retain glyph ids option and configure the subset to pass through the layout tables untouched.
- */
-
-
-hb_user_data_key_t _hb_subset_accelerator_user_data_key = {};
-
-
-/*
- * The list of tables in the open type spec. Used to check for tables that may need handling
- * if we are unable to list the tables in a face.
- */
-static hb_tag_t known_tables[] {
- HB_TAG ('a', 'v', 'a', 'r'),
- HB_OT_TAG_BASE,
- HB_OT_TAG_CBDT,
- HB_OT_TAG_CBLC,
- HB_OT_TAG_cff1,
- HB_OT_TAG_cff2,
- HB_OT_TAG_cmap,
- HB_OT_TAG_COLR,
- HB_OT_TAG_CPAL,
- HB_TAG ('c', 'v', 'a', 'r'),
- HB_TAG ('c', 'v', 't', ' '),
- HB_TAG ('D', 'S', 'I', 'G'),
- HB_TAG ('E', 'B', 'D', 'T'),
- HB_TAG ('E', 'B', 'L', 'C'),
- HB_TAG ('E', 'B', 'S', 'C'),
- HB_TAG ('f', 'p', 'g', 'm'),
- HB_TAG ('f', 'v', 'a', 'r'),
- HB_TAG ('g', 'a', 's', 'p'),
- HB_OT_TAG_GDEF,
- HB_OT_TAG_glyf,
- HB_OT_TAG_GPOS,
- HB_OT_TAG_GSUB,
- HB_OT_TAG_gvar,
- HB_OT_TAG_hdmx,
- HB_OT_TAG_head,
- HB_OT_TAG_hhea,
- HB_OT_TAG_hmtx,
- HB_OT_TAG_HVAR,
- HB_OT_TAG_JSTF,
- HB_TAG ('k', 'e', 'r', 'n'),
- HB_OT_TAG_loca,
- HB_TAG ('L', 'T', 'S', 'H'),
- HB_OT_TAG_MATH,
- HB_OT_TAG_maxp,
- HB_TAG ('M', 'E', 'R', 'G'),
- HB_TAG ('m', 'e', 't', 'a'),
- HB_TAG ('M', 'V', 'A', 'R'),
- HB_TAG ('P', 'C', 'L', 'T'),
- HB_OT_TAG_post,
- HB_TAG ('p', 'r', 'e', 'p'),
- HB_OT_TAG_sbix,
- HB_TAG ('S', 'T', 'A', 'T'),
- HB_TAG ('S', 'V', 'G', ' '),
- HB_TAG ('V', 'D', 'M', 'X'),
- HB_OT_TAG_vhea,
- HB_OT_TAG_vmtx,
- HB_OT_TAG_VORG,
- HB_OT_TAG_VVAR,
- HB_OT_TAG_name,
- HB_OT_TAG_OS2
-};
-
-static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag)
-{
- hb_blob_t* blob = hb_face_reference_table (face, tag);
- bool result = (blob == hb_blob_get_empty ());
- hb_blob_destroy (blob);
- return result;
-}
-
-static unsigned int
-_get_table_tags (const hb_subset_plan_t* plan,
- unsigned int start_offset,
- unsigned int *table_count, /* IN/OUT */
- hb_tag_t *table_tags /* OUT */)
-{
- unsigned num_tables = hb_face_get_table_tags (plan->source, 0, nullptr, nullptr);
- if (num_tables)
- return hb_face_get_table_tags (plan->source, start_offset, table_count, table_tags);
-
- // If face has 0 tables associated with it, assume that it was built from
- // hb_face_create_tables and thus is unable to list its tables. Fallback to
- // checking each table type we can handle for existence instead.
- auto it =
- hb_concat (
- + hb_array (known_tables)
- | hb_filter ([&] (hb_tag_t tag) {
- return !_table_is_empty (plan->source, tag) && !plan->no_subset_tables.has (tag);
- })
- | hb_map ([] (hb_tag_t tag) -> hb_tag_t { return tag; }),
-
- plan->no_subset_tables.iter ()
- | hb_filter([&] (hb_tag_t tag) {
- return !_table_is_empty (plan->source, tag);
- }));
-
- it += start_offset;
-
- unsigned num_written = 0;
- while (bool (it) && num_written < *table_count)
- table_tags[num_written++] = *it++;
-
- *table_count = num_written;
- return num_written;
-}
-
-
-static unsigned
-_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
- unsigned table_len,
- bool same_size)
-{
- unsigned src_glyphs = plan->source->get_num_glyphs ();
- unsigned dst_glyphs = plan->glyphset ()->get_population ();
-
- if (unlikely (!src_glyphs) || same_size)
- return 512 + table_len;
-
- return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
-}
-
-/*
- * Repack the serialization buffer if any offset overflows exist.
- */
-static hb_blob_t*
-_repack (hb_tag_t tag, const hb_serialize_context_t& c)
-{
- if (!c.offset_overflow ())
- return c.copy_blob ();
-
- hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag);
-
- if (unlikely (!result))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.",
- HB_UNTAG (tag));
- return nullptr;
- }
-
- return result;
-}
-
-template<typename TableType>
-static
-bool
-_try_subset (const TableType *table,
- hb_vector_t<char>* buf,
- hb_subset_context_t* c /* OUT */)
-{
- c->serializer->start_serialize<TableType> ();
- if (c->serializer->in_error ()) return false;
-
- bool needed = table->subset (c);
- if (!c->serializer->ran_out_of_room ())
- {
- c->serializer->end_serialize ();
- return needed;
- }
-
- unsigned buf_size = buf->allocated;
- buf_size = buf_size * 2 + 16;
-
-
-
-
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.",
- HB_UNTAG (c->table_tag), buf_size);
-
- if (unlikely (buf_size > c->source_blob->length * 16 ||
- !buf->alloc (buf_size, true)))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.",
- HB_UNTAG (c->table_tag), buf_size);
- return needed;
- }
-
- c->serializer->reset (buf->arrayZ, buf->allocated);
- return _try_subset (table, buf, c);
-}
-
-template<typename TableType>
-static bool
-_subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf)
-{
- hb_blob_ptr_t<TableType> source_blob = plan->source_table<TableType> ();
- const TableType *table = source_blob.get ();
-
- hb_tag_t tag = TableType::tableTag;
- if (!source_blob.get_blob()->data)
- {
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
- source_blob.destroy ();
- return false;
- }
-
- /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
- * because those are expensive to subset, so giving them more room is fine. */
- bool same_size_table = TableType::tableTag == HB_OT_TAG_GSUB ||
- TableType::tableTag == HB_OT_TAG_GPOS ||
- TableType::tableTag == HB_OT_TAG_name;
-
- unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table);
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
- if (unlikely (!buf.alloc (buf_size)))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
- source_blob.destroy ();
- return false;
- }
-
- bool needed = false;
- hb_serialize_context_t serializer (buf.arrayZ, buf.allocated);
- {
- hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag);
- needed = _try_subset (table, &buf, &c);
- }
- source_blob.destroy ();
-
- if (serializer.in_error () && !serializer.only_offset_overflow ())
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag));
- return false;
- }
-
- if (!needed)
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
- return true;
- }
-
- bool result = false;
- hb_blob_t *dest_blob = _repack (tag, serializer);
- if (dest_blob)
- {
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c final subset table size: %u bytes.",
- HB_UNTAG (tag), dest_blob->length);
- result = plan->add_table (tag, dest_blob);
- hb_blob_destroy (dest_blob);
- }
-
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s",
- HB_UNTAG (tag), result ? "success" : "FAILED!");
- return result;
-}
-
-static bool
-_is_table_present (hb_face_t *source, hb_tag_t tag)
-{
-
- if (!hb_face_get_table_tags (source, 0, nullptr, nullptr)) {
- // If face has 0 tables associated with it, assume that it was built from
- // hb_face_create_tables and thus is unable to list its tables. Fallback to
- // checking if the blob associated with tag is empty.
- return !_table_is_empty (source, tag);
- }
-
- hb_tag_t table_tags[32];
- unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
- while (((void) hb_face_get_table_tags (source, offset, &num_tables, table_tags), num_tables))
- {
- for (unsigned i = 0; i < num_tables; ++i)
- if (table_tags[i] == tag)
- return true;
- offset += num_tables;
- }
- return false;
-}
-
-static bool
-_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
-{
- if (plan->drop_tables.has (tag))
- return true;
-
- switch (tag)
- {
- case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */
- return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-
- case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */
- case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */
- case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */
- case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */
- case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */
- return plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
-
-#ifdef HB_NO_SUBSET_LAYOUT
- // Drop Layout Tables if requested.
- case HB_OT_TAG_GDEF:
- case HB_OT_TAG_GPOS:
- case HB_OT_TAG_GSUB:
- case HB_TAG ('m','o','r','x'):
- case HB_TAG ('m','o','r','t'):
- case HB_TAG ('k','e','r','x'):
- case HB_TAG ('k','e','r','n'):
- return true;
-#endif
-
- case HB_TAG ('a','v','a','r'):
- case HB_TAG ('f','v','a','r'):
- case HB_TAG ('g','v','a','r'):
- case HB_OT_TAG_HVAR:
- case HB_OT_TAG_VVAR:
- case HB_TAG ('M','V','A','R'):
- return plan->all_axes_pinned;
-
- default:
- return false;
- }
-}
-
-static bool
-_passthrough (hb_subset_plan_t *plan, hb_tag_t tag)
-{
- hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
- bool result = plan->add_table (tag, source_table);
- hb_blob_destroy (source_table);
- return result;
-}
-
-static bool
-_dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag,
- const hb_set_t &subsetted_tags,
- const hb_set_t &pending_subset_tags)
-{
- switch (tag)
- {
- case HB_OT_TAG_hmtx:
- case HB_OT_TAG_vmtx:
- case HB_OT_TAG_maxp:
- return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf);
- default:
- return true;
- }
-}
-
-static bool
-_subset_table (hb_subset_plan_t *plan,
- hb_vector_t<char> &buf,
- hb_tag_t tag)
-{
- if (plan->no_subset_tables.has (tag)) {
- return _passthrough (plan, tag);
- }
-
- DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag));
- switch (tag)
- {
- case HB_OT_TAG_glyf: return _subset<const OT::glyf> (plan, buf);
- case HB_OT_TAG_hdmx: return _subset<const OT::hdmx> (plan, buf);
- case HB_OT_TAG_name: return _subset<const OT::name> (plan, buf);
- case HB_OT_TAG_head:
- if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf))
- return true; /* skip head, handled by glyf */
- return _subset<const OT::head> (plan, buf);
- case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */
- case HB_OT_TAG_hmtx: return _subset<const OT::hmtx> (plan, buf);
- case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */
- case HB_OT_TAG_vmtx: return _subset<const OT::vmtx> (plan, buf);
- case HB_OT_TAG_maxp: return _subset<const OT::maxp> (plan, buf);
- case HB_OT_TAG_sbix: return _subset<const OT::sbix> (plan, buf);
- case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */
- case HB_OT_TAG_cmap: return _subset<const OT::cmap> (plan, buf);
- case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan, buf);
- case HB_OT_TAG_post: return _subset<const OT::post> (plan, buf);
- case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan, buf);
- case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan, buf);
- case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan, buf);
- case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
- case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan, buf);
-
-#ifndef HB_NO_SUBSET_CFF
- case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan, buf);
- case HB_OT_TAG_cff2: return _subset<const OT::cff2> (plan, buf);
- case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan, buf);
-#endif
-
-#ifndef HB_NO_SUBSET_LAYOUT
- case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan, buf);
- case HB_OT_TAG_GSUB: return _subset<const GSUB> (plan, buf);
- case HB_OT_TAG_GPOS: return _subset<const GPOS> (plan, buf);
- case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan, buf);
- case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
- case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
-#endif
- case HB_OT_TAG_fvar:
- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
- return _subset<const OT::fvar> (plan, buf);
- case HB_OT_TAG_STAT:
- /*TODO(qxliu): change the condition as we support more complex
- * instancing operation*/
- if (plan->all_axes_pinned) return _subset<const OT::STAT> (plan, buf);
- else return _passthrough (plan, tag);
-
- case HB_TAG ('c', 'v', 't', ' '):
-#ifndef HB_NO_VAR
- if (_is_table_present (plan->source, HB_OT_TAG_cvar) &&
- plan->normalized_coords && !plan->pinned_at_default)
- {
- auto &cvar = *plan->source->table.cvar;
- return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar);
- }
-#endif
- return _passthrough (plan, tag);
- default:
- if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED)
- return _passthrough (plan, tag);
-
- // Drop table
- return true;
- }
-}
-
-static void _attach_accelerator_data (hb_subset_plan_t* plan,
- hb_face_t* face /* IN/OUT */)
-{
- if (!plan->inprogress_accelerator) return;
-
- // Transfer the accelerator from the plan to us.
- hb_subset_accelerator_t* accel = plan->inprogress_accelerator;
- plan->inprogress_accelerator = nullptr;
-
- if (accel->in_error ())
- {
- hb_subset_accelerator_t::destroy (accel);
- return;
- }
-
- // Populate caches that need access to the final tables.
- hb_blob_ptr_t<OT::cmap> cmap_ptr (hb_sanitize_context_t ().reference_table<OT::cmap> (face));
- accel->cmap_cache = OT::cmap::create_filled_cache (cmap_ptr);
- accel->destroy_cmap_cache = OT::SubtableUnicodesCache::destroy;
-
- if (!hb_face_set_user_data(face,
- hb_subset_accelerator_t::user_data_key(),
- accel,
- hb_subset_accelerator_t::destroy,
- true))
- hb_subset_accelerator_t::destroy (accel);
-}
-
-/**
- * hb_subset_or_fail:
- * @source: font face data to be subset.
- * @input: input to use for the subsetting.
- *
- * Subsets a font according to provided input. Returns nullptr
- * if the subset operation fails.
- *
- * Since: 2.9.0
- **/
-hb_face_t *
-hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input)
-{
- if (unlikely (!input || !source)) return hb_face_get_empty ();
-
- hb_subset_plan_t *plan = hb_subset_plan_create_or_fail (source, input);
- if (unlikely (!plan)) {
- return nullptr;
- }
-
- hb_face_t * result = hb_subset_plan_execute_or_fail (plan);
- hb_subset_plan_destroy (plan);
- return result;
-}
-
-
-/**
- * hb_subset_plan_execute_or_fail:
- * @plan: a subsetting plan.
- *
- * Executes the provided subsetting @plan.
- *
- * Return value:
- * on success returns a reference to generated font subset. If the subsetting operation fails
- * returns nullptr.
- *
- * Since: 4.0.0
- **/
-hb_face_t *
-hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
-{
- if (unlikely (!plan || plan->in_error ())) {
- return nullptr;
- }
-
- hb_tag_t table_tags[32];
- unsigned offset = 0, num_tables = ARRAY_LENGTH (table_tags);
-
- hb_set_t subsetted_tags, pending_subset_tags;
- while (((void) _get_table_tags (plan, offset, &num_tables, table_tags), num_tables))
- {
- for (unsigned i = 0; i < num_tables; ++i)
- {
- hb_tag_t tag = table_tags[i];
- if (_should_drop_table (plan, tag)) continue;
- pending_subset_tags.add (tag);
- }
-
- offset += num_tables;
- }
-
- hb_vector_t<char> buf;
- buf.alloc (4096 - 16);
-
-
- bool success = true;
-
- while (!pending_subset_tags.is_empty ())
- {
- if (subsetted_tags.in_error ()
- || pending_subset_tags.in_error ()) {
- success = false;
- goto end;
- }
-
- bool made_changes = false;
- for (hb_tag_t tag : pending_subset_tags)
- {
- if (!_dependencies_satisfied (plan, tag,
- subsetted_tags,
- pending_subset_tags))
- {
- // delayed subsetting for some tables since they might have dependency on other tables
- // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
- // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
- continue;
- }
-
- pending_subset_tags.del (tag);
- subsetted_tags.add (tag);
- made_changes = true;
-
- success = _subset_table (plan, buf, tag);
- if (unlikely (!success)) goto end;
- }
-
- if (!made_changes)
- {
- DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
- success = false;
- goto end;
- }
- }
-
- if (success && plan->attach_accelerator_data) {
- _attach_accelerator_data (plan, plan->dest);
- }
-
-end:
- return success ? hb_face_reference (plan->dest) : nullptr;
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h
deleted file mode 100644
index 41d9587052a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright © 2018 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): Rod Sheeter
- */
-
-#ifndef HB_SUBSET_H
-#define HB_SUBSET_H
-
-#include "hb.h"
-#include "hb-ot.h"
-
-HB_BEGIN_DECLS
-
-/**
- * hb_subset_input_t:
- *
- * Things that change based on the input. Characters to keep, etc.
- */
-
-typedef struct hb_subset_input_t hb_subset_input_t;
-
-/**
- * hb_subset_plan_t:
- *
- * Contains information about how the subset operation will be executed.
- * Such as mappings from the old glyph ids to the new ones in the subset.
- */
-
-typedef struct hb_subset_plan_t hb_subset_plan_t;
-
-/**
- * hb_subset_flags_t:
- * @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false.
- * @HB_SUBSET_FLAGS_NO_HINTING: If set hinting instructions will be dropped in
- * the produced subset. Otherwise hinting instructions will be retained.
- * @HB_SUBSET_FLAGS_RETAIN_GIDS: If set glyph indices will not be modified in
- * the produced subset. If glyphs are dropped their indices will be retained
- * as an empty glyph.
- * @HB_SUBSET_FLAGS_DESUBROUTINIZE: If set and subsetting a CFF font the
- * subsetter will attempt to remove subroutines from the CFF glyphs.
- * @HB_SUBSET_FLAGS_NAME_LEGACY: If set non-unicode name records will be
- * retained in the subset.
- * @HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG: If set the subsetter will set the
- * OVERLAP_SIMPLE flag on each simple glyph.
- * @HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED: If set the subsetter will not
- * drop unrecognized tables and instead pass them through untouched.
- * @HB_SUBSET_FLAGS_NOTDEF_OUTLINE: If set the notdef glyph outline will be
- * retained in the final subset.
- * @HB_SUBSET_FLAGS_GLYPH_NAMES: If set the PS glyph names will be retained
- * in the final subset.
- * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
- * OS/2 will not be recalculated.
- * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout
- * substitution rules (GSUB). Since: 7.2.0.
- *
- * List of boolean properties that can be configured on the subset input.
- *
- * Since: 2.9.0
- **/
-typedef enum { /*< flags >*/
- HB_SUBSET_FLAGS_DEFAULT = 0x00000000u,
- HB_SUBSET_FLAGS_NO_HINTING = 0x00000001u,
- HB_SUBSET_FLAGS_RETAIN_GIDS = 0x00000002u,
- HB_SUBSET_FLAGS_DESUBROUTINIZE = 0x00000004u,
- HB_SUBSET_FLAGS_NAME_LEGACY = 0x00000008u,
- HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG = 0x00000010u,
- HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED = 0x00000020u,
- HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u,
- HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u,
- HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u,
- HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u,
-} hb_subset_flags_t;
-
-/**
- * hb_subset_sets_t:
- * @HB_SUBSET_SETS_GLYPH_INDEX: the set of glyph indexes to retain in the subset.
- * @HB_SUBSET_SETS_UNICODE: the set of unicode codepoints to retain in the subset.
- * @HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG: the set of table tags which specifies tables that should not be
- * subsetted.
- * @HB_SUBSET_SETS_DROP_TABLE_TAG: the set of table tags which specifies tables which will be dropped
- * in the subset.
- * @HB_SUBSET_SETS_NAME_ID: the set of name ids that will be retained.
- * @HB_SUBSET_SETS_NAME_LANG_ID: the set of name lang ids that will be retained.
- * @HB_SUBSET_SETS_LAYOUT_FEATURE_TAG: the set of layout feature tags that will be retained
- * in the subset.
- * @HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG: the set of layout script tags that will be retained
- * in the subset. Defaults to all tags. Since: 5.0.0
- *
- * List of sets that can be configured on the subset input.
- *
- * Since: 2.9.1
- **/
-typedef enum {
- HB_SUBSET_SETS_GLYPH_INDEX = 0,
- HB_SUBSET_SETS_UNICODE,
- HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG,
- HB_SUBSET_SETS_DROP_TABLE_TAG,
- HB_SUBSET_SETS_NAME_ID,
- HB_SUBSET_SETS_NAME_LANG_ID,
- HB_SUBSET_SETS_LAYOUT_FEATURE_TAG,
- HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG,
-} hb_subset_sets_t;
-
-HB_EXTERN hb_subset_input_t *
-hb_subset_input_create_or_fail (void);
-
-HB_EXTERN hb_subset_input_t *
-hb_subset_input_reference (hb_subset_input_t *input);
-
-HB_EXTERN void
-hb_subset_input_destroy (hb_subset_input_t *input);
-
-HB_EXTERN hb_bool_t
-hb_subset_input_set_user_data (hb_subset_input_t *input,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace);
-
-HB_EXTERN void *
-hb_subset_input_get_user_data (const hb_subset_input_t *input,
- hb_user_data_key_t *key);
-
-HB_EXTERN void
-hb_subset_input_keep_everything (hb_subset_input_t *input);
-
-HB_EXTERN hb_set_t *
-hb_subset_input_unicode_set (hb_subset_input_t *input);
-
-HB_EXTERN hb_set_t *
-hb_subset_input_glyph_set (hb_subset_input_t *input);
-
-HB_EXTERN hb_set_t *
-hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type);
-
-HB_EXTERN hb_subset_flags_t
-hb_subset_input_get_flags (hb_subset_input_t *input);
-
-HB_EXTERN void
-hb_subset_input_set_flags (hb_subset_input_t *input,
- unsigned value);
-
-HB_EXTERN hb_bool_t
-hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
- hb_face_t *face,
- hb_tag_t axis_tag);
-
-HB_EXTERN hb_bool_t
-hb_subset_input_pin_axis_location (hb_subset_input_t *input,
- hb_face_t *face,
- hb_tag_t axis_tag,
- float axis_value);
-
-#ifdef HB_EXPERIMENTAL_API
-HB_EXTERN hb_bool_t
-hb_subset_input_override_name_table (hb_subset_input_t *input,
- hb_ot_name_id_t name_id,
- unsigned platform_id,
- unsigned encoding_id,
- unsigned language_id,
- const char *name_str,
- int str_len);
-
-#endif
-
-HB_EXTERN hb_face_t *
-hb_subset_preprocess (hb_face_t *source);
-
-HB_EXTERN hb_face_t *
-hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
-
-HB_EXTERN hb_face_t *
-hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan);
-
-HB_EXTERN hb_subset_plan_t *
-hb_subset_plan_create_or_fail (hb_face_t *face,
- const hb_subset_input_t *input);
-
-HB_EXTERN void
-hb_subset_plan_destroy (hb_subset_plan_t *plan);
-
-HB_EXTERN hb_map_t *
-hb_subset_plan_old_to_new_glyph_mapping (const hb_subset_plan_t *plan);
-
-HB_EXTERN hb_map_t *
-hb_subset_plan_new_to_old_glyph_mapping (const hb_subset_plan_t *plan);
-
-HB_EXTERN hb_map_t *
-hb_subset_plan_unicode_to_old_glyph_mapping (const hb_subset_plan_t *plan);
-
-
-HB_EXTERN hb_subset_plan_t *
-hb_subset_plan_reference (hb_subset_plan_t *plan);
-
-HB_EXTERN hb_bool_t
-hb_subset_plan_set_user_data (hb_subset_plan_t *plan,
- hb_user_data_key_t *key,
- void *data,
- hb_destroy_func_t destroy,
- hb_bool_t replace);
-
-HB_EXTERN void *
-hb_subset_plan_get_user_data (const hb_subset_plan_t *plan,
- hb_user_data_key_t *key);
-
-
-HB_END_DECLS
-
-#endif /* HB_SUBSET_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset.hh
deleted file mode 100644
index 4f192aae406..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright © 2018 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): Garret Rieger, Roderick Sheeter
- */
-
-#ifndef HB_SUBSET_HH
-#define HB_SUBSET_HH
-
-
-#include "hb.hh"
-
-#include "hb-subset.h"
-
-#include "hb-machinery.hh"
-#include "hb-serialize.hh"
-#include "hb-subset-input.hh"
-#include "hb-subset-plan.hh"
-
-struct hb_subset_context_t :
- hb_dispatch_context_t<hb_subset_context_t, bool, HB_DEBUG_SUBSET>
-{
- const char *get_name () { return "SUBSET"; }
- static return_t default_return_value () { return true; }
-
- private:
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.subset (this, std::forward<Ts> (ds)...) )
- template <typename T, typename ...Ts> auto
- _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
- ( obj.dispatch (this, std::forward<Ts> (ds)...) )
- public:
- template <typename T, typename ...Ts> auto
- dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
- ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
-
- hb_blob_t *source_blob;
- hb_subset_plan_t *plan;
- hb_serialize_context_t *serializer;
- hb_tag_t table_tag;
-
- hb_subset_context_t (hb_blob_t *source_blob_,
- hb_subset_plan_t *plan_,
- hb_serialize_context_t *serializer_,
- hb_tag_t table_tag_) :
- source_blob (source_blob_),
- plan (plan_),
- serializer (serializer_),
- table_tag (table_tag_) {}
-};
-
-
-#endif /* HB_SUBSET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh
deleted file mode 100644
index f7d76eee18a..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ucd-table.hh
+++ /dev/null
@@ -1,5633 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-ucd-table.py ucd.nounihan.grouped.xml
- *
- * on file with this description: Unicode 15.0.0
- */
-
-#ifndef HB_UCD_TABLE_HH
-#define HB_UCD_TABLE_HH
-
-#include "hb.hh"
-
-static const hb_script_t
-_hb_ucd_sc_map[165] =
-{
- HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED,
- HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC,
- HB_SCRIPT_ARMENIAN, HB_SCRIPT_BENGALI,
- HB_SCRIPT_CYRILLIC, HB_SCRIPT_DEVANAGARI,
- HB_SCRIPT_GEORGIAN, HB_SCRIPT_GREEK,
- HB_SCRIPT_GUJARATI, HB_SCRIPT_GURMUKHI,
- HB_SCRIPT_HANGUL, HB_SCRIPT_HAN,
- HB_SCRIPT_HEBREW, HB_SCRIPT_HIRAGANA,
- HB_SCRIPT_KANNADA, HB_SCRIPT_KATAKANA,
- HB_SCRIPT_LAO, HB_SCRIPT_LATIN,
- HB_SCRIPT_MALAYALAM, HB_SCRIPT_ORIYA,
- HB_SCRIPT_TAMIL, HB_SCRIPT_TELUGU,
- HB_SCRIPT_THAI, HB_SCRIPT_TIBETAN,
- HB_SCRIPT_BOPOMOFO, HB_SCRIPT_BRAILLE,
- HB_SCRIPT_CANADIAN_SYLLABICS, HB_SCRIPT_CHEROKEE,
- HB_SCRIPT_ETHIOPIC, HB_SCRIPT_KHMER,
- HB_SCRIPT_MONGOLIAN, HB_SCRIPT_MYANMAR,
- HB_SCRIPT_OGHAM, HB_SCRIPT_RUNIC,
- HB_SCRIPT_SINHALA, HB_SCRIPT_SYRIAC,
- HB_SCRIPT_THAANA, HB_SCRIPT_YI,
- HB_SCRIPT_DESERET, HB_SCRIPT_GOTHIC,
- HB_SCRIPT_OLD_ITALIC, HB_SCRIPT_BUHID,
- HB_SCRIPT_HANUNOO, HB_SCRIPT_TAGALOG,
- HB_SCRIPT_TAGBANWA, HB_SCRIPT_CYPRIOT,
- HB_SCRIPT_LIMBU, HB_SCRIPT_LINEAR_B,
- HB_SCRIPT_OSMANYA, HB_SCRIPT_SHAVIAN,
- HB_SCRIPT_TAI_LE, HB_SCRIPT_UGARITIC,
- HB_SCRIPT_BUGINESE, HB_SCRIPT_COPTIC,
- HB_SCRIPT_GLAGOLITIC, HB_SCRIPT_KHAROSHTHI,
- HB_SCRIPT_NEW_TAI_LUE, HB_SCRIPT_OLD_PERSIAN,
- HB_SCRIPT_SYLOTI_NAGRI, HB_SCRIPT_TIFINAGH,
- HB_SCRIPT_BALINESE, HB_SCRIPT_CUNEIFORM,
- HB_SCRIPT_NKO, HB_SCRIPT_PHAGS_PA,
- HB_SCRIPT_PHOENICIAN, HB_SCRIPT_CARIAN,
- HB_SCRIPT_CHAM, HB_SCRIPT_KAYAH_LI,
- HB_SCRIPT_LEPCHA, HB_SCRIPT_LYCIAN,
- HB_SCRIPT_LYDIAN, HB_SCRIPT_OL_CHIKI,
- HB_SCRIPT_REJANG, HB_SCRIPT_SAURASHTRA,
- HB_SCRIPT_SUNDANESE, HB_SCRIPT_VAI,
- HB_SCRIPT_AVESTAN, HB_SCRIPT_BAMUM,
- HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, HB_SCRIPT_IMPERIAL_ARAMAIC,
- HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
- HB_SCRIPT_JAVANESE, HB_SCRIPT_KAITHI,
- HB_SCRIPT_LISU, HB_SCRIPT_MEETEI_MAYEK,
- HB_SCRIPT_OLD_SOUTH_ARABIAN, HB_SCRIPT_OLD_TURKIC,
- HB_SCRIPT_SAMARITAN, HB_SCRIPT_TAI_THAM,
- HB_SCRIPT_TAI_VIET, HB_SCRIPT_BATAK,
- HB_SCRIPT_BRAHMI, HB_SCRIPT_MANDAIC,
- HB_SCRIPT_CHAKMA, HB_SCRIPT_MEROITIC_CURSIVE,
- HB_SCRIPT_MEROITIC_HIEROGLYPHS, HB_SCRIPT_MIAO,
- HB_SCRIPT_SHARADA, HB_SCRIPT_SORA_SOMPENG,
- HB_SCRIPT_TAKRI, HB_SCRIPT_BASSA_VAH,
- HB_SCRIPT_CAUCASIAN_ALBANIAN, HB_SCRIPT_DUPLOYAN,
- HB_SCRIPT_ELBASAN, HB_SCRIPT_GRANTHA,
- HB_SCRIPT_KHOJKI, HB_SCRIPT_KHUDAWADI,
- HB_SCRIPT_LINEAR_A, HB_SCRIPT_MAHAJANI,
- HB_SCRIPT_MANICHAEAN, HB_SCRIPT_MENDE_KIKAKUI,
- HB_SCRIPT_MODI, HB_SCRIPT_MRO,
- HB_SCRIPT_NABATAEAN, HB_SCRIPT_OLD_NORTH_ARABIAN,
- HB_SCRIPT_OLD_PERMIC, HB_SCRIPT_PAHAWH_HMONG,
- HB_SCRIPT_PALMYRENE, HB_SCRIPT_PAU_CIN_HAU,
- HB_SCRIPT_PSALTER_PAHLAVI, HB_SCRIPT_SIDDHAM,
- HB_SCRIPT_TIRHUTA, HB_SCRIPT_WARANG_CITI,
- HB_SCRIPT_AHOM, HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
- HB_SCRIPT_HATRAN, HB_SCRIPT_MULTANI,
- HB_SCRIPT_OLD_HUNGARIAN, HB_SCRIPT_SIGNWRITING,
- HB_SCRIPT_ADLAM, HB_SCRIPT_BHAIKSUKI,
- HB_SCRIPT_MARCHEN, HB_SCRIPT_OSAGE,
- HB_SCRIPT_TANGUT, HB_SCRIPT_NEWA,
- HB_SCRIPT_MASARAM_GONDI, HB_SCRIPT_NUSHU,
- HB_SCRIPT_SOYOMBO, HB_SCRIPT_ZANABAZAR_SQUARE,
- HB_SCRIPT_DOGRA, HB_SCRIPT_GUNJALA_GONDI,
- HB_SCRIPT_HANIFI_ROHINGYA, HB_SCRIPT_MAKASAR,
- HB_SCRIPT_MEDEFAIDRIN, HB_SCRIPT_OLD_SOGDIAN,
- HB_SCRIPT_SOGDIAN, HB_SCRIPT_ELYMAIC,
- HB_SCRIPT_NANDINAGARI, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG,
- HB_SCRIPT_WANCHO, HB_SCRIPT_CHORASMIAN,
- HB_SCRIPT_DIVES_AKURU, HB_SCRIPT_KHITAN_SMALL_SCRIPT,
- HB_SCRIPT_YEZIDI, HB_SCRIPT_CYPRO_MINOAN,
- HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA,
- HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI,
- HB_SCRIPT_MATH, HB_SCRIPT_KAWI,
- HB_SCRIPT_NAG_MUNDARI,
-};
-static const uint16_t
-_hb_ucd_dm1_p0_map[825] =
-{
- 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u,
- 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu,
- 0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu,
- 0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u,
- 0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu,
- 0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au,
- 0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u,
- 0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u,
- 0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u,
- 0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu,
- 0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu,
- 0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu,
- 0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u,
- 0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu,
- 0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu,
- 0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u,
- 0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du,
- 0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu,
- 0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u,
- 0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u,
- 0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu,
- 0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u,
- 0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu,
- 0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u,
- 0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u,
- 0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu,
- 0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u,
- 0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u,
- 0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u,
- 0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u,
- 0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu,
- 0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u,
- 0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u,
- 0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u,
- 0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu,
- 0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u,
- 0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u,
- 0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu,
- 0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u,
- 0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u,
- 0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au,
- 0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u,
- 0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u,
- 0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u,
- 0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu,
- 0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u,
- 0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u,
- 0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u,
- 0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u,
- 0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u,
- 0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u,
- 0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u,
- 0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu,
- 0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u,
- 0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au,
- 0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au,
- 0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu,
- 0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu,
- 0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu,
- 0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u,
- 0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u,
- 0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u,
- 0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u,
- 0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u,
- 0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u,
- 0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u,
- 0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu,
- 0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu,
- 0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u,
- 0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu,
- 0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u,
- 0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu,
- 0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u,
- 0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u,
- 0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au,
- 0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u,
- 0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u,
- 0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu,
- 0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u,
- 0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu,
- 0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u,
- 0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u,
- 0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u,
- 0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u,
- 0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu,
- 0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u,
- 0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u,
- 0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu,
- 0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu,
- 0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu,
- 0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u,
- 0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u,
- 0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u,
- 0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u,
- 0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u,
- 0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u,
- 0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u,
- 0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu,
- 0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u,
- 0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu,
- 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u,
- 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u,
- 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu,
- 0x9F9Cu,
-};
-static const uint16_t
-_hb_ucd_dm1_p2_map[110] =
-{
- 0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu,
- 0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u,
- 0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu,
- 0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u,
- 0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u,
- 0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u,
- 0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u,
- 0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u,
- 0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u,
- 0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u,
- 0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu,
- 0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu,
- 0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u,
- 0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u,
-};
-static const uint32_t
-_hb_ucd_dm2_u32_map[638] =
-{
- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu),
- HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu),
-};
-static const uint64_t
-_hb_ucd_dm2_u64_map[388] =
-{
- HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u), HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u),
- HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u), HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u),
- HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u), HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u),
- HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u), HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u),
- HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u), HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u),
- HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u), HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu), HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu),
- HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu), HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u),
- HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu), HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u),
- HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu), HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu),
- HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu), HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u),
- HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu),
- HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u),
- HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu), HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au),
- HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu), HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu),
- HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu), HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu),
- HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu), HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu),
- HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u),
- HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u), HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u),
- HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au), HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu),
- HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu), HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u),
- HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu), HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du),
- HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u), HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u),
- HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u), HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u),
- HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u), HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu),
- HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du), HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u),
- HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u), HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu),
- HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u), HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu),
- HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u), HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u),
- HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u), HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u),
- HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u),
- HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u),
- HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u),
- HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u),
- HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u), HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u),
- HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u), HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u),
- HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u), HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u),
- HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au),
- HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu),
- HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu),
- HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu),
- HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u), HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au),
- HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu), HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu),
- HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du), HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu),
- HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu), HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u),
- HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u), HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u),
- HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u), HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au),
- HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu), HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu),
- HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u),
- HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u),
- HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u),
- HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u),
- HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u), HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u),
- HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u), HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u),
- HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u), HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u),
- HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au),
- HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu),
- HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu),
- HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu),
- HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u), HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au),
- HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu), HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu),
- HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du), HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu),
- HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u),
- HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u),
- HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u), HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u),
- HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au),
- HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu),
- HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu), HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du),
- HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu), HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u),
- HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u), HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u),
- HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u), HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au),
- HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu), HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu),
- HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u),
- HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u),
- HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u), HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u),
- HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu),
- HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu),
- HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u),
- HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u),
- HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u),
- HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u),
- HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u), HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u),
- HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u), HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u),
- HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u), HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u),
- HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu),
- HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u),
- HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du),
- HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u),
- HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu), HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu),
- HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu), HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu),
- HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu), HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu),
- HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u), HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u),
- HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u), HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u),
- HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu), HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu),
- HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu), HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u),
- HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu),
- HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu),
- HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au), HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu),
- HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu), HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu),
- HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu), HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu),
- HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u), HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u),
- HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu), HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u),
- HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u), HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u),
- HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u), HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u),
- HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u), HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du),
- HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u), HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u),
- HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u), HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u),
- HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u), HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u),
- HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u), HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u),
- HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u), HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u),
- HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u), HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u),
- HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u), HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u),
- HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u), HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u),
- HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u), HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu),
- HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu), HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu),
- HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu), HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu),
- HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu), HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu),
- HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu), HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u), HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu),
- HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu), HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u),
- HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u), HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u),
- HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u), HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u),
- HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au), HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu),
- HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu), HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u),
- HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u), HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u),
- HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u), HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u),
- HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u), HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u),
- HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u), HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u),
- HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u), HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u),
- HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u), HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au),
- HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu), HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du),
- HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu), HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u),
- HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu), HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu),
- HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u), HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u),
- HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u), HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u),
- HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u), HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu),
- HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu), HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu),
- HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u), HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u),
- HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u), HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u),
- HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u), HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u),
- HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u), HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u),
- HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u), HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u),
- HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u), HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u),
- HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu), HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu),
- HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu), HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u),
- HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u),
- HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu),
- HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu),
- HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu),
- HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu),
- HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),
- HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),
- HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu),HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),
- HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u),
- HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u),
-};
-
-#ifndef HB_OPTIMIZE_SIZE
-
-static const uint8_t
-_hb_ucd_u8[17868] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7,
- 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42,
- 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73,
- 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83,
- 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34,
- 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96,
- 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105,
- 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
- 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117,
- 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131,
- 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146,
- 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122,
- 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173,
- 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177,
- 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122,
- 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188,
- 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191,
- 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197,
- 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211,
- 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122,
- 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220,
- 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122,
- 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236,
- 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
- 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
- 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2,
- 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25,
- 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
- 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
- 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
- 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
- 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
- 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10,
- 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11,
- 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11,
- 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
- 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2,
- 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62,
- 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67,
- 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43,
- 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36,
- 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79,
- 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36,
- 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43,
- 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43,
- 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64,
- 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44,
- 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43,
- 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43,
- 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86,
- 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36,
- 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36,
- 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86,
- 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62,
- 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80,
- 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86,
- 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61,
- 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44,
- 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36,
- 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44,
- 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43,
- 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87,
- 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62,
- 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36,
- 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36,
- 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44,
- 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44,
- 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44,
- 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91,
- 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87,
- 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61,
- 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36,
- 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77,
- 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36,
- 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36,
- 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89,
- 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44,
- 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96,
- 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36,
- 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44,
- 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36,
- 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67,
- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86,
- 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44,
- 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43,
- 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67,
- 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44,
- 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71,
- 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43,
- 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36,
- 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67,
- 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16,
- 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44,
- 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36,
- 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43,
- 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44,
- 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44,
- 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72,
- 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44,
- 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44,
- 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44,
- 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36,
- 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86,
- 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44,
- 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44,
- 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36,
- 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44,
- 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7,
- 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44,
- 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67,
- 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80,
- 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57,
- 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109,
- 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36,
- 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44,
- 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64,
- 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36,
- 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2,
- 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2,
- 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2,
- 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11,
- 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43,
- 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44,
- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16,
- 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40,
- 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11,
- 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48,
- 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112,
- 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41,
- 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41,
- 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65,
- 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124,
- 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2,
- 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65,
- 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104,
- 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20,
- 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51,
- 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44,
- 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67,
- 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11,
- 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27,
- 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44,
- 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144,
- 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67,
- 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67,
- 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8,
- 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8,
- 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67,
- 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67,
- 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8,
- 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4,
- 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67,
- 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4,
- 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8,
- 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8,
- 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67,
- 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11,
- 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149,
- 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44,
- 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57,
- 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61,
- 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2,
- 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2,
- 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44,
- 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
- 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157,
- 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
- 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
- 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
- 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
- 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2,
- 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70,
- 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43,
- 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44,
- 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32,
- 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32,
- 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32,
- 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44,
- 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36,
- 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44,
- 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2,
- 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2,
- 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93,
- 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52,
- 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36,
- 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85,
- 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44,
- 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36,
- 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86,
- 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61,
- 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40,
- 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44,
- 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36,
- 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,
- 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71,
- 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61,
- 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
- 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67,
- 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148,
- 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130,
- 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2,
- 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36,
- 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40,
- 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44,
- 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44,
- 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62,
- 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67,
- 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92,
- 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36,
- 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36,
- 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16,
- 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44,
- 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93,
- 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16,
- 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44,
- 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44,
- 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62,
- 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27,
- 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27,
- 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93,
- 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27,
- 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36,
- 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44,
- 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30,
- 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36,
- 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44,
- 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27,
- 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44,
- 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44,
- 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44,
- 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44,
- 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43,
- 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44,
- 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44,
- 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43,
- 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7,
- 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2,
- 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7,
- 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44,
- 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87,
- 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27,
- 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87,
- 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44,
- 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62,
- 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70,
- 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62,
- 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44,
- 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44,
- 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43,
- 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71,
- 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87,
- 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44,
- 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44,
- 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86,
- 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44,
- 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44,
- 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36,
- 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71,
- 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36,
- 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44,
- 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60,
- 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36,
- 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2,
- 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44,
- 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44,
- 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44,
- 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57,
- 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36,
- 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44,
- 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2,
- 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67,
- 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181,
- 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44,
- 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43,
- 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44,
- 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44,
- 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57,
- 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44,
- 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81,
- 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44,
- 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44,
- 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44,
- 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86,
- 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67,
- 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44,
- 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16,
- 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
- 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11,
- 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16,
- 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16,
- 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11,
- 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
- 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11,
- 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16,
- 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16,
- 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16,
- 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43,
- 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67,
- 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43,
- 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110,
- 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43,
- 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44,
- 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57,
- 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77,
- 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43,
- 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43,
- 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27,
- 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27,
- 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163,
- 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36,
- 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44,
- 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
- 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
- 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
- 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
- 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
- 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
- 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
- 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
- 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0,
- 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
- 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5,
- 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20,
- 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25,
- 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5,
- 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2,
- 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26,
- 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21,
- 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7,
- 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1,
- 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12,
- 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7,
- 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22,
- 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6,
- 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1,
- 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16,
- 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2,
- 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15,
- 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21,
- 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6,
- 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9,
- 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16,
- 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15,
- 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0,
- 15, 0, 16, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19,
- 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, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 0, 0, 35,
- 0, 36, 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, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
- 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11,
- 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19,
- 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48,
- 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52,
- 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0,
- 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66,
- 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0,
- 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0,
- 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82,
- 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89,
- 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94,
- 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0,
- 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0,
- 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0,
- 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0,
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0,
- 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16,
- 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23,
- 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31,
- 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0,
- 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39,
- 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44,
- 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48,
- 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0,
- 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58,
- 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63,
- 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70,
- 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79,
- 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82,
- 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78,
- 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0,
- 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0,
- 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94,
- 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0,
- 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103,
- 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108,
- 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0,
- 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0,
- 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,
- 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0,
- 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125,
- 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0,
- 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0,
- 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10,
- 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0,
- 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0,
- 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0,
- 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45,
- 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1,
- 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14,
- 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55,
- 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0,
- 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0,
- 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0,
- 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0,
- 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0,
- 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0,
- 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87,
- 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0,
- 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4,
- 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1,
- 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0,
- 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102,
- 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0,
- 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0,
- 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12,
- 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61,
- 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51,
- 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0,
- 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0,
- 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0,
- 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0,
- 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0,
- 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,
- 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,
- 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1,
- 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123,
- 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,
- 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
- 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,
- 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0,
- 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
- 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,
- 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,
- 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31,
- 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0,
- 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0,
- 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,
- 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,
- 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220,
- 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,
- 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9,
- 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,
- 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220,
- 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,
- 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0,
- 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0,
- 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,
- 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,
- 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,
- 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1,
- 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,
- 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,
- 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0,
- 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0,
- 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0,
- 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,
- 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17,
- 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
- 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2,
- 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8,
- 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0,
- 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0,
- 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41,
- 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0,
- 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0,
- 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10,
- 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0,
- 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7,
- 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0,
- 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1,
- 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0,
- 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4,
- 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35,
- 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8,
- 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21,
- 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0,
- 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20,
- 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13,
- 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
- 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
- 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7,
- 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
- 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
- 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
- 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
- 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
- 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
- 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
- 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
- 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
- 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
- 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
- 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
- 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
- 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
- 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
- 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
- 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
- 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
- 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
- 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
- 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96,
- 96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96,
- 96, 96, 96, 96, 96, 96,245, 96,246,247, 0, 1, 2, 2, 0, 1,
- 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19,
- 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19,
- 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2,
- 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9,
- 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4,
- 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14,
- 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3,
- 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37,
- 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
- 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
- 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37,
- 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3,
- 2, 2, 2, 2, 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7,
- 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5,
- 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2,
- 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2,
- 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2,
- 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11,
- 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2,
- 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2,
- 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11,
- 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2,
- 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10,
- 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10,
- 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10,
- 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21,
- 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2,
- 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2,
- 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2,
- 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2,
- 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2,
- 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2,
- 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2,
- 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2,
- 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2,
- 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23,
- 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2,
- 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2,
- 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16,
- 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2,
- 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20,
- 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,
- 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36,
- 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2,
- 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24,
- 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18,
- 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18,
- 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18,
- 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25,
- 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25,
- 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2,
- 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12,
- 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2,
- 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30,
- 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30,
- 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2,
- 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2,
- 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32,
- 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32,
- 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48,
- 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52,
- 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58,
- 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
- 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91,
- 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1,
- 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 2, 76, 76,
- 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
- 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70,
- 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70,
- 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2,
- 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1,
- 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
- 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9,
- 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9,
- 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9,
- 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9,
- 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9,
- 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19,
- 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2,
- 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
- 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0,
- 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27,
- 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0,
- 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
- 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
- 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2,
- 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0,
- 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13,
- 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1,
- 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2,
- 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12,
- 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39,
- 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79,
- 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0,
- 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 19, 19,
- 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 2, 2, 2,
- 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 65, 65,
- 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
- 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75,
- 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
- 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12,
- 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33,
- 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
- 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68,
- 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87,
- 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30,
- 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87,
- 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12,
- 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13,
- 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2,
- 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14,
- 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
- 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2,
- 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1,
- 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3,
- 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17,
- 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2,
- 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49,
- 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0,
- 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0,
- 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0,
- 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2,
- 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118,
- 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40,
- 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50,
- 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135,
- 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104,
- 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161,
- 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161,
- 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,110,110,
- 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110,
- 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2,
- 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120,
- 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116,
- 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128,
- 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2,
- 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
- 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97,
- 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2,
- 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2,
- 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2,
- 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117,
- 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112,
- 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78,
- 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122,
- 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122,
- 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2,
- 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130,
- 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144,
- 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,156,156,
- 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,147,147,
- 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148,
- 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158,
- 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153,
- 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149,
- 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2,
- 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
- 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101,
- 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101,
- 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111,
- 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108,
- 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108,
- 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2,
- 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129,
- 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109,
- 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109,
- 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107,
- 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107,
- 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2,
- 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2,
- 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2,
- 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107,
- 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137,
- 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124,
- 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123,
- 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114,
- 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114,
- 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102,
- 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126,
- 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126,
- 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142,
- 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125,
- 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154,
- 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154,
- 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2,
- 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150,
- 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150,
- 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140,
- 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121,
- 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7,
- 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2,
- 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133,
- 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134,
- 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134,
- 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138,
- 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138,
- 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138,
- 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2,
- 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
- 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2,
- 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145,
- 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163,
- 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163,
- 163, 2, 2, 2,163,163,163,163, 2, 2, 2, 2, 2, 2, 86, 2,
- 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
- 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63,
- 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157,
- 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2,127,127,
- 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2,
- 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115,
- 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159,
- 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159,
- 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103,
- 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119,
- 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2,
- 2, 2, 2,119,119,119,146,146,146,146,146,146,146,146,146,146,
- 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139,
- 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155,
- 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2,136, 2,
- 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17,
- 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17,
- 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15,
- 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139,
- 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105,
- 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105,
- 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105,
- 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0,
- 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2,
- 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0,
- 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
- 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131,
- 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131,
- 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56,
- 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56,
- 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6,
- 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151,
- 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151,
- 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,
- 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152,
- 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164,
- 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2, 30, 30,
- 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113,
- 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132,
- 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132,
- 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3,
- 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2,
- 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3,
- 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3,
- 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3,
- 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0,
- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2,
- 2, 0, 0, 0, 0, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13,
- 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1,
- 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13,
- 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33,
- 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 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, 0, 43, 44,
- 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48,
- 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0,
- 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0,
- 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 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, 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, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69,
- 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0,
- 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,
- 110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 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,117, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 118,119,120,121, 0,122,123,124,125,126, 0,127, 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,128,129,130,131,
- 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,
- 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,
- 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 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,
- 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,
- 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,169,170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,
- 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
- 193,194,195,196,197,198,199,200,201,202,203,204,205,206, 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, 1, 2, 3, 4,
-};
-static const uint16_t
-_hb_ucd_u16[9320] =
-{
- 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12,
- 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23,
- 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31,
- 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39,
- 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13,
- 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50,
- 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58,
- 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66,
- 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32,
- 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101,
- 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113,
- 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124,
- 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135,
- 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140,
- 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140,
- 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167,
- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48,
- 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175,
- 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183,
- 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193,
- 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199,
- 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209,
- 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140,
- 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225,
- 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235,
- 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13,
- 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250,
- 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265,
- 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278,
- 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282,
- 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271,
- 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209,
- 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279,
- 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305,
- 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308,
- 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313,
- 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140,
- 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
- 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331,
- 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48,
- 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
- 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48,
- 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342,
- 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349,
- 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360,
- 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151,
- 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377,
- 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11,
- 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206,
- 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391,
- 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140,
- 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48,
- 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403,
- 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410,
- 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419,
- 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71,
- 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428,
- 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430,
- 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140,
- 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439,
- 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140,
- 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140,
- 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453,
- 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271,
- 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467,
- 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474,
- 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476,
- 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48,
- 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488,
- 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495,
- 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140,
- 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514,
- 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140,
- 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140,
- 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140,
- 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532,
- 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140,
- 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196,
- 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550,
- 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48,
- 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560,
- 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566,
- 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568,
- 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569,
- 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140,
- 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573,
- 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586,
- 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140,
- 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587,
- 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206,
- 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140,
- 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140,
- 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598,
- 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140,
- 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461,
- 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11,
- 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11,
- 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623,
- 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632,
- 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140,
- 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140,
- 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140,
- 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192,
- 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140,
- 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
- 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
- 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
- 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
- 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
- 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
- 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
- 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
- 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
- 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
- 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48,
- 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140,
- 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
- 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4,
- 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,
- 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14,
- 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21,
- 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25,
- 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31,
- 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37,
- 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26,
- 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46,
- 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62,
- 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74,
- 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86,
- 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98,
- 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109,
- 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116,
- 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126,
- 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131,
- 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141,
- 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148,
- 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154,
- 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158,
- 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161,
- 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164,
- 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165,
- 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172,
- 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170,
- 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176,
- 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178,
- 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181,
- 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26,
- 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178,
- 178, 178, 178, 178, 178, 178, 202, 26, 203, 203, 203, 204, 203, 205, 203, 205,
- 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210,
- 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216,
- 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9,
- 9, 221, 26, 26, 26, 26, 26, 26, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225,
- 226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230,
- 229, 231, 232, 232, 232, 232, 232, 232, 18, 233, 165, 165, 165, 165, 165, 234,
- 225, 26, 235, 9, 236, 237, 238, 239, 2, 2, 2, 2, 240, 241, 2, 2,
- 2, 2, 2, 242, 243, 244, 2, 245, 2, 2, 2, 2, 2, 2, 2, 246,
- 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 247, 247, 14, 14, 14, 14,
- 247, 247, 14, 248, 14, 14, 14, 247, 14, 14, 14, 14, 14, 14, 249, 14,
- 249, 14, 250, 251, 14, 14, 252, 253, 0, 254, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 255, 0, 256, 257, 0, 258, 2, 259, 0, 0, 0, 0,
- 260, 26, 9, 9, 9, 9, 261, 26, 0, 0, 0, 0, 262, 263, 4, 0,
- 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 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, 258, 26, 26, 26,
- 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267,
- 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270,
- 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273,
- 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172,
- 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285,
- 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291,
- 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294,
- 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0,
- 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291,
- 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277,
- 0, 0, 0, 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, 299, 299, 299,
- 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299,
- 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, 26, 26,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 305, 305, 305, 305,
- 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 307, 2, 2, 2, 2, 2, 2,
- 2, 308, 309, 310, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314,
- 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316,
- 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322,
- 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326,
- 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26,
- 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334,
- 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2,
- 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
- 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169,
- 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352,
- 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 354, 26, 355, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 356,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31,
- 31, 358, 26, 26, 26, 26, 31, 31, 9, 9, 0, 314, 9, 359, 0, 0,
- 0, 0, 360, 0, 258, 281, 361, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 362, 363, 0, 0, 0, 1, 2, 2, 3,
- 1, 2, 2, 3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296,
- 366, 366, 366, 367, 258, 258, 26, 368, 369, 370, 369, 369, 371, 369, 369, 372,
- 369, 373, 369, 373, 26, 26, 26, 26, 369, 369, 369, 369, 369, 369, 369, 369,
- 369, 369, 369, 369, 369, 369, 369, 374, 375, 0, 0, 0, 0, 0, 376, 0,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 253, 0, 377, 378, 26, 26, 26,
- 26, 26, 0, 0, 0, 0, 0, 379, 380, 380, 380, 381, 382, 382, 382, 382,
- 382, 382, 383, 26, 384, 0, 0, 281, 385, 385, 385, 385, 386, 387, 388, 388,
- 388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394,
- 395, 394, 396, 26, 26, 26, 26, 26, 397, 397, 397, 397, 397, 397, 397, 397,
- 397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402,
- 402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404, 26, 405, 405,
- 405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412,
- 26, 26, 26, 26, 26, 26, 26, 26, 413, 413, 413, 413, 413, 413, 413, 413,
- 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414, 26,
- 413, 413, 415, 26, 413, 26, 26, 26, 416, 2, 2, 2, 2, 2, 417, 308,
- 26, 26, 26, 26, 26, 26, 26, 26, 418, 419, 420, 420, 420, 420, 421, 422,
- 423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426, 26, 26,
- 26, 26, 26, 26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435,
- 26, 26, 26, 26, 26, 26, 26, 26, 436, 436, 436, 436, 437, 437, 437, 438,
- 437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446,
- 444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449, 26, 26, 26, 26,
- 450, 450, 450, 450, 451, 452, 451, 26, 453, 453, 453, 453, 453, 453, 454, 455,
- 456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462, 26, 463, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 464, 464, 464, 464, 464, 464, 464, 464,
- 464, 465, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 466, 467, 26,
- 466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469, 26, 469, 470,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 31, 31, 31, 50, 471, 471, 471, 471, 471, 472, 473, 26,
- 26, 26, 26, 26, 26, 26, 26, 474, 475, 475, 475, 475, 475, 26, 476, 476,
- 476, 476, 476, 477, 26, 26, 478, 478, 478, 479, 26, 26, 26, 26, 480, 480,
- 480, 481, 26, 26, 482, 482, 483, 26, 484, 484, 484, 484, 484, 484, 484, 484,
- 484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488,
- 489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494,
- 494, 26, 496, 496, 496, 496, 497, 26, 498, 498, 498, 498, 498, 498, 498, 498,
- 498, 498, 498, 498, 499, 137, 500, 26, 501, 501, 502, 501, 501, 501, 501, 501,
- 503, 26, 26, 26, 26, 26, 26, 26, 504, 505, 506, 507, 506, 508, 509, 509,
- 509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518,
- 513, 519, 520, 521, 522, 523, 523, 26, 524, 524, 524, 524, 524, 524, 524, 524,
- 524, 524, 524, 525, 526, 26, 26, 26, 527, 527, 527, 527, 527, 527, 527, 527,
- 527, 26, 527, 528, 26, 26, 26, 26, 529, 529, 529, 529, 529, 529, 530, 529,
- 529, 529, 529, 530, 26, 26, 26, 26, 531, 531, 531, 531, 531, 531, 531, 531,
- 532, 26, 531, 533, 198, 534, 26, 26, 535, 535, 535, 535, 535, 535, 535, 536,
- 535, 536, 26, 26, 26, 26, 26, 26, 537, 537, 537, 538, 537, 539, 537, 537,
- 540, 26, 26, 26, 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 542,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 543, 543, 543, 543,
- 543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551,
- 546, 26, 549, 552, 26, 26, 26, 26, 26, 26, 26, 26, 553, 554, 553, 553,
- 553, 553, 553, 554, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 556,
- 556, 26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 26, 178, 178,
- 559, 559, 559, 559, 559, 559, 559, 560, 53, 561, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 562, 563, 562, 562, 562, 562, 564, 562,
- 565, 26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 571, 572, 573, 573, 573, 573, 571, 574,
- 573, 26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587,
- 585, 585, 585, 588, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 589, 26,
- 108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592,
- 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 592, 592, 592, 592, 592, 592, 592, 592,
- 592, 592, 592, 592, 592, 594, 595, 26, 592, 592, 592, 592, 592, 592, 592, 592,
- 596, 26, 26, 26, 26, 26, 26, 26, 26, 26, 597, 597, 597, 597, 597, 597,
- 597, 597, 597, 597, 597, 597, 598, 26, 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
- 599, 599, 600, 26, 26, 26, 26, 26, 601, 601, 601, 601, 601, 601, 601, 601,
- 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601,
- 602, 26, 26, 26, 26, 26, 26, 26, 305, 305, 305, 305, 305, 305, 305, 305,
- 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603,
- 604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608,
- 607, 609, 610, 610, 610, 611, 611, 26, 612, 612, 612, 612, 612, 612, 612, 612,
- 613, 26, 612, 614, 614, 612, 612, 615, 612, 612, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 618, 618, 618, 618, 618, 618, 618, 618,
- 618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618, 26, 26, 26, 26,
- 26, 26, 26, 26, 621, 26, 347, 26, 622, 622, 622, 622, 622, 622, 622, 622,
- 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622,
- 622, 622, 622, 622, 622, 622, 622, 26, 623, 623, 623, 623, 623, 623, 623, 623,
- 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
- 623, 623, 624, 26, 26, 26, 26, 26, 622, 625, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629, 26, 630, 26,
- 26, 26, 631, 26, 632, 26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
- 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
- 633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635,
- 635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 9, 9, 9, 9, 9, 640, 9, 9,
- 221, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 281, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 276, 26, 0, 0, 0, 0, 258, 363, 0, 0,
- 0, 0, 0, 0, 641, 642, 0, 643, 644, 645, 0, 0, 0, 646, 0, 0,
- 0, 0, 0, 0, 0, 266, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14,
- 247, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 0, 0, 281, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 258, 26, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 647, 648, 0, 649,
- 650, 0, 0, 0, 0, 0, 0, 0, 269, 651, 255, 255, 0, 0, 0, 652,
- 653, 654, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 268, 0, 0, 0, 0, 0, 0, 656, 656, 656, 656, 656, 656, 656, 656,
- 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, 26, 658, 659, 656, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 348, 660, 308, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 661, 270, 270, 662, 663, 664, 18, 18,
- 18, 18, 18, 18, 18, 665, 26, 26, 26, 666, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 667, 667, 667, 667, 667, 668, 667, 669,
- 667, 670, 26, 26, 26, 26, 26, 26, 26, 26, 671, 671, 671, 672, 26, 26,
- 673, 673, 673, 673, 673, 673, 673, 674, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 675, 675, 675, 675, 675, 676, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678,
- 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678,
- 679, 678, 680, 26, 26, 26, 26, 26, 681, 681, 681, 681, 681, 681, 681, 681,
- 681, 682, 681, 683, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 0, 377, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 276,
- 26, 26, 26, 26, 26, 26, 26, 26, 684, 31, 31, 31, 685, 686, 687, 688,
- 689, 690, 685, 691, 685, 687, 687, 692, 31, 693, 31, 694, 695, 693, 31, 694,
- 26, 26, 26, 26, 26, 26, 51, 26, 0, 0, 0, 0, 0, 281, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 258, 363, 0,
- 363, 0, 363, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26,
- 26, 26, 26, 26, 696, 0, 0, 0, 697, 26, 0, 0, 0, 0, 0, 281,
- 0, 260, 314, 26, 276, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 698, 0, 377, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 258, 699, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 314, 0, 281, 260, 26, 0, 281, 0, 0, 0, 0, 0, 0,
- 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 276, 314, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 281, 26, 0, 276, 0, 377, 0, 260, 0, 0, 0, 0, 0, 269,
- 276, 696, 0, 281, 0, 260, 0, 260, 0, 0, 360, 0, 0, 0, 0, 0,
- 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 347,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 700, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 702, 26, 26, 26, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962,
- 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0,
- 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,
- 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0,
- 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
- 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160,
- 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,
- 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206,
- 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,
- 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,
- 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,
- 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
- 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
- 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,
- 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,
- 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
- 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
- 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130,
- 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,
- 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522,
- 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567,
- 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549,
- 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559,
- 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,
- 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,
- 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662,
- 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,
- 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671,
- 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,
- 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,
- 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
- 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
- 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
- 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
- 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
- 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
- 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
- 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
- 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
- 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,
- 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
- 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
- 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
- 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
- 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
- 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,
- 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,
- 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,
- 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
- 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,
- 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790,
- 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
- 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,
- 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,
- 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
- 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
- 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,
- 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,
- 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,
- 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,
- 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,
- 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0,
- 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0,
- 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847,
- 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,
- 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,
- 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0,
- 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,
- 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890,
- 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897,
- 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,
- 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917,
- 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924,
- 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,
- 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825,
- 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
- 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
- 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
- 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
- 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
- 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
- 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
- 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
- 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
- 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
- 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
- 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
- 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
- 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
- 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
- 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
- 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525,
- 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0,
- 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
- 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
- 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
- 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
- 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171,
- 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
- 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
- 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
- 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
- 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
- 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916,
- 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,
- 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,
- 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121,
- 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142,
- 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169,
- 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
- 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
- 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
- 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39,
- 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266,
- 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286,
- 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852,
- 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324,
- 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
- 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50,
- 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78,
- 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55,
- 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861,
- 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
- 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467,
- 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
- 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875,
- 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531,
- 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559,
- 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73,
- 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898,
- 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902,
- 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
- 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81,
- 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669,
- 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686,
- 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
- 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
- 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925,
- 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800,
- 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816,
- 817, 818, 819, 820, 821, 935, 0, 0,
-};
-static const int16_t
-_hb_ucd_i16[196] =
-{
- 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2,
- 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1,
- 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3,
- -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0,
- 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0,
- 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0,
- 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0,
- 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0,
- 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1,
- -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0,
- 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106,
- -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1,
- -1, 0, 1, -1,
-};
-
-static inline uint_fast8_t
-_hb_ucd_gc (unsigned u)
-{
- return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
-}
-static inline uint_fast8_t
-_hb_ucd_ccc (unsigned u)
-{
- return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
-}
-static inline unsigned
-_hb_ucd_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline int_fast16_t
-_hb_ucd_bmg (unsigned u)
-{
- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
-}
-static inline uint_fast8_t
-_hb_ucd_sc (unsigned u)
-{
- return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
-}
-static inline uint_fast16_t
-_hb_ucd_dm (unsigned u)
-{
- return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
-}
-
-
-#elif !defined(HB_NO_UCD_UNASSIGNED)
-
-static const uint8_t
-_hb_ucd_u8[14744] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7,
- 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42,
- 7, 7, 43, 7, 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 45, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 47,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73,
- 69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83,
- 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34,
- 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96,
- 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105,
- 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
- 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117,
- 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131,
- 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146,
- 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122,
- 160,161,162,163,164,165,166,122,167,168,169,170,122,171,172,173,
- 34, 34, 34, 34, 34, 34, 34,174,175, 34,176,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,177,
- 34, 34, 34, 34, 34, 34, 34, 34,178,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122, 34, 34, 34, 34,179,122,122,122,
- 34, 34, 34, 34,180,181,182,183,122,122,122,122,184,185,186,187,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,188,
- 34, 34, 34, 34, 34, 34, 34, 34, 34,189,190,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,191,
- 34, 34,192, 34, 34,193,122,122,122,122,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,194,195,122,122,122,122,122,122,
- 122,122,122,122,122,122,122,122,122,122,122,122,122,122,196,197,
- 69,198,199,200,201,202,203,122,204,205,206,207,208,209,210,211,
- 69, 69, 69, 69,212,213,122,122,122,122,122,122,122,122,214,122,
- 215,216,217,122,122,218,122,122,122,219,122,122,122,122,122,220,
- 34,221,222,122,122,122,122,122,223,224,225,122,226,227,122,122,
- 228,229,230,231,232,122, 69,233, 69, 69, 69, 69, 69,234,235,236,
- 237,238, 69, 69,239,240, 69,241,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,242, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
- 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
- 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
- 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
- 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2,
- 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25,
- 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
- 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
- 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
- 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
- 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
- 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10,
- 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11,
- 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11,
- 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
- 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2,
- 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62,
- 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67,
- 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43,
- 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36,
- 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79,
- 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36,
- 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43,
- 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43,
- 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64,
- 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44,
- 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43,
- 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43,
- 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86,
- 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36,
- 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36,
- 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86,
- 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62,
- 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80,
- 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86,
- 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61,
- 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44,
- 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36,
- 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44,
- 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43,
- 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87,
- 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62,
- 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36,
- 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36,
- 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44,
- 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44,
- 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44,
- 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91,
- 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87,
- 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61,
- 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36,
- 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77,
- 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36,
- 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36,
- 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89,
- 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44,
- 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96,
- 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36,
- 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44,
- 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36,
- 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67,
- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86,
- 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44,
- 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43,
- 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67,
- 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44,
- 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71,
- 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43,
- 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36,
- 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67,
- 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16,
- 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44,
- 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36,
- 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43,
- 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44,
- 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44,
- 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72,
- 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44,
- 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44,
- 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44,
- 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36,
- 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86,
- 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44,
- 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44,
- 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36,
- 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44,
- 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7,
- 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44,
- 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67,
- 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80,
- 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57,
- 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109,
- 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36,
- 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44,
- 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64,
- 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36,
- 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2,
- 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2,
- 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2,
- 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11,
- 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43,
- 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44,
- 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16,
- 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40,
- 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11,
- 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48,
- 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112,
- 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41,
- 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41,
- 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65,
- 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124,
- 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2,
- 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65,
- 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104,
- 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20,
- 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51,
- 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44,
- 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67,
- 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11,
- 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27,
- 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44,
- 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144,
- 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67,
- 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67,
- 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8,
- 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8,
- 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67,
- 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67,
- 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8,
- 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4,
- 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67,
- 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4,
- 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8,
- 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8,
- 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67,
- 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11,
- 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149,
- 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44,
- 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57,
- 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61,
- 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2,
- 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2,
- 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44,
- 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
- 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157,
- 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
- 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
- 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
- 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
- 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2,
- 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70,
- 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43,
- 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44,
- 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32,
- 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32,
- 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32,
- 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44,
- 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36,
- 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44,
- 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2,
- 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2,
- 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93,
- 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52,
- 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36,
- 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85,
- 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44,
- 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36,
- 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86,
- 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61,
- 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40,
- 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44,
- 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36,
- 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171,
- 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71,
- 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61,
- 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
- 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67,
- 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148,
- 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130,
- 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2,
- 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36,
- 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40,
- 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44,
- 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44,
- 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62,
- 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67,
- 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92,
- 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36,
- 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36,
- 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16,
- 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44,
- 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93,
- 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16,
- 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44,
- 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44,
- 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62,
- 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27,
- 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27,
- 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93,
- 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27,
- 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36,
- 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44,
- 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30,
- 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36,
- 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44,
- 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27,
- 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44,
- 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44,
- 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44,
- 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44,
- 36, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 43,
- 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44,
- 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44,
- 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43,
- 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7,
- 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2,
- 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7,
- 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44,
- 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87,
- 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27,
- 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87,
- 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44,
- 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62,
- 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70,
- 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62,
- 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44,
- 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44,
- 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43,
- 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71,
- 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87,
- 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44,
- 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44,
- 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86,
- 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44,
- 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44,
- 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36,
- 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71,
- 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36,
- 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44,
- 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60,
- 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36,
- 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2,
- 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44,
- 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44,
- 2, 36, 36, 36, 36, 36, 36, 36, 44, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 89, 43, 43, 43, 85, 43, 87, 80, 44, 44, 44, 44,
- 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57,
- 43, 43, 43, 70, 44, 44, 44, 44, 36, 36, 36, 62, 61, 36, 36, 36,
- 36, 36, 36, 36, 36, 86, 86, 90, 43, 89, 87, 87, 61, 44, 44, 44,
- 36, 70, 85,107, 64, 44, 44, 44, 43, 94, 36, 36, 36, 36, 36, 36,
- 36, 36, 86, 43, 43, 80, 44, 86, 85, 60, 2, 2, 2, 2, 2, 2,
- 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67,
- 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181,
- 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44,
- 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43,
- 43, 43, 43, 44, 44, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44,
- 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44,
- 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44,
- 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57,
- 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44,
- 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81,
- 36, 61, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44,
- 36, 61, 62, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44,
- 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44,
- 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44,
- 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86,
- 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67,
- 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44,
- 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16,
- 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
- 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11,
- 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16,
- 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16,
- 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11,
- 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
- 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11,
- 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16,
- 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16,
- 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16,
- 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43,
- 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67,
- 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43,
- 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110,
- 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43,
- 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44,
- 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57,
- 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77,
- 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43,
- 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43,
- 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27,
- 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27,
- 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163,
- 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36,
- 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44,
- 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
- 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
- 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
- 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
- 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
- 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
- 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
- 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
- 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
- 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0,
- 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
- 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5,
- 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20,
- 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25,
- 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5,
- 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2,
- 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26,
- 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21,
- 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7,
- 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1,
- 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12,
- 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7,
- 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22,
- 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6,
- 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1,
- 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16,
- 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2,
- 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15,
- 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21,
- 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6,
- 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9,
- 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16,
- 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15,
- 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0,
- 15, 0, 16, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19,
- 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, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 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, 0, 0, 35,
- 0, 36, 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, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0,
- 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11,
- 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19,
- 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0,
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48,
- 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52,
- 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0,
- 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66,
- 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0,
- 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0,
- 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82,
- 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89,
- 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94,
- 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0,
- 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0,
- 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0,
- 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0,
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0,
- 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16,
- 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23,
- 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31,
- 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0,
- 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39,
- 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44,
- 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48,
- 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0,
- 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58,
- 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63,
- 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70,
- 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79,
- 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82,
- 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78,
- 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0,
- 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0,
- 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94,
- 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0,
- 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103,
- 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108,
- 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0,
- 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0,
- 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,
- 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0,
- 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125,
- 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0,
- 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0,
- 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10,
- 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0,
- 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0,
- 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0,
- 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45,
- 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1,
- 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14,
- 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55,
- 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0,
- 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0,
- 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0,
- 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0,
- 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0,
- 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0,
- 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87,
- 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0,
- 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4,
- 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1,
- 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0,
- 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102,
- 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0,
- 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0,
- 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12,
- 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61,
- 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51,
- 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0,
- 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0,
- 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0,
- 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0,
- 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0,
- 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,
- 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,
- 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1,
- 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123,
- 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,
- 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
- 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,
- 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0,
- 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
- 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,
- 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,
- 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31,
- 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0,
- 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0,
- 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,
- 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,
- 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220,
- 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,
- 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9,
- 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,
- 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220,
- 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,
- 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0,
- 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0,
- 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,
- 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,
- 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,
- 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1,
- 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,
- 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,
- 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0,
- 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0,
- 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0,
- 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,
- 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33,
- 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3,
- 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3,
- 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21,
- 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3,
- 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0,
- 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0,
- 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0,
- 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0,
- 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19,
- 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
- 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39,
- 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0,
- 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47,
- 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0,
- 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57,
- 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59,
- 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60,
- 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3,
- 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0,
- 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0,
- 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0,
- 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0,
- 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0,
- 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20,
- 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9,
- 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21,
- 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0,
- 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21,
- 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9,
- 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45,
- 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1,
- 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3,
- 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
- 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7,
- 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1,
- 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
- 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56,
- 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
- 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
- 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
- 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
- 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
- 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
- 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
- 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
- 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
- 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
- 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
- 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
- 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
- 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
- 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
- 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
- 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
- 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
- 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
- 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
- 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
- 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
- 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0,
- 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0,
- 19, 0, 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9,
- 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2,
- 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9,
- 2, 9, 9, 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 1,
- 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, 2,
- 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3,
- 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 3, 37, 37,
- 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38,
- 38, 38, 38, 38, 2, 2, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64,
- 64, 64, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 2, 95, 95,
- 95, 95, 2, 2, 95, 2, 3, 3, 3, 2, 3, 3, 2, 2, 3, 3,
- 0, 3, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0,
- 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 2, 2, 5, 5, 2,
- 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5,
- 5, 2, 2, 2, 2, 5, 5, 5, 2, 5, 2, 11, 11, 11, 11, 11,
- 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 2,
- 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 2, 11, 2, 2, 11, 2,
- 11, 2, 2, 2, 11, 11, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 2, 10, 10, 2, 10, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2,
- 10, 10, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2,
- 21, 21, 21, 21, 2, 2, 21, 21, 2, 21, 2, 2, 21, 21, 2, 2,
- 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 22, 2, 22, 22, 22, 22,
- 2, 2, 2, 22, 22, 2, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22,
- 22, 22, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 23,
- 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 2, 2, 23, 23, 2, 2,
- 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, 16, 16, 16, 16,
- 2, 2, 2, 16, 16, 2, 2, 2, 16, 16, 20, 20, 20, 20, 20, 2,
- 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 2, 2, 2, 36, 36, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2,
- 36, 2, 2, 2, 2, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, 24,
- 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 2, 18,
- 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 2, 18,
- 2, 18, 18, 18, 2, 2, 18, 2, 18, 2, 25, 25, 25, 25, 2, 25,
- 25, 25, 25, 2, 2, 2, 25, 2, 25, 25, 25, 0, 0, 0, 0, 25,
- 25, 2, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 2, 8, 2, 8,
- 2, 2, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 30, 2,
- 30, 30, 30, 30, 2, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 2,
- 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 34, 34,
- 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0,
- 35, 35, 35, 2, 2, 2, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2,
- 2, 45, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 46, 46,
- 46, 46, 46, 2, 46, 46, 31, 31, 31, 31, 31, 31, 2, 2, 32, 32,
- 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 32, 2,
- 2, 2, 32, 32, 32, 2, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48,
- 48, 2, 48, 2, 2, 2, 52, 52, 52, 52, 52, 52, 2, 2, 52, 2,
- 2, 2, 58, 58, 58, 58, 58, 58, 2, 2, 58, 58, 58, 2, 2, 2,
- 58, 58, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91,
- 91, 2, 91, 2, 2, 91, 91, 91, 2, 2, 1, 1, 1, 2, 62, 62,
- 62, 62, 62, 2, 2, 2, 62, 62, 62, 2, 76, 76, 76, 76, 93, 93,
- 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 2, 2, 2, 70,
- 70, 70, 73, 73, 73, 73, 6, 2, 2, 2, 8, 8, 8, 2, 2, 8,
- 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1,
- 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9,
- 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19,
- 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 9, 9, 1, 1,
- 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 19, 0, 0,
- 0, 2, 19, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 0, 0,
- 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, 0, 0, 0, 0,
- 2, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2,
- 2, 61, 61, 2, 2, 2, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13,
- 2, 13, 13, 13, 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13,
- 1, 1, 1, 1, 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12,
- 12, 12, 12, 12, 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2,
- 2, 2, 39, 39, 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79,
- 79, 79, 19, 19, 19, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19,
- 2, 2, 2, 2, 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65,
- 65, 65, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69,
- 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2,
- 2, 2, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2,
- 84, 84, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68,
- 2, 2, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87,
- 87, 87, 87, 87, 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87,
- 2, 2, 2, 2, 2, 12, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14,
- 2, 14, 14, 2, 14, 14, 2, 2, 2, 3, 3, 3, 0, 0, 2, 2,
- 3, 3, 1, 1, 6, 6, 3, 2, 3, 3, 3, 2, 2, 0, 2, 0,
- 0, 0, 0, 0, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 49, 49,
- 49, 49, 2, 49, 49, 49, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49,
- 2, 2, 9, 2, 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2,
- 2, 2, 67, 67, 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42,
- 42, 42, 41, 41, 41, 41, 41, 41, 41, 2,118,118,118,118,118,118,
- 118, 2, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59,
- 2, 2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
- 2, 2,135,135,135,135,106,106,106,106,104,104,104,104, 2, 2,
- 2,104,161,161,161,161,161,161,161, 2,161,161, 2,161,161, 2,
- 2, 2,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 2,
- 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47,
- 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81,
- 2, 81,120,120,120,120,116,116,116,116,116,116,116, 2, 2, 2,
- 2,116,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2,
- 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72,
- 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2,
- 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57,
- 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88,
- 88, 88,117,117,117,117,112,112,112,112,112,112,112, 2, 2, 2,
- 2,112, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83,
- 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122,
- 122,122,122,122, 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89,
- 89, 89, 89, 2, 2, 2,130,130,130,130,130,130,130, 2, 2, 2,
- 130,130,144,144,144,144,144,144, 2, 2,156,156,156,156,156,156,
- 2,156,156,156, 2, 2, 2, 3, 3, 3,147,147,147,147,148,148,
- 148,148,148,148, 2, 2,158,158,158,158,158,158, 2, 2,153,153,
- 153,153,149,149,149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94,
- 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85,
- 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, 2, 2,101,101,
- 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,
- 111, 2,100,100,100,100,108,108,108,108,108,108, 2,108,108,108,
- 2, 2,129,129,129,129,129,129,129, 2,129, 2,129,129,129,129,
- 2,129,129,129, 2, 2,109,109,109,109,109,109,109, 2,109,109,
- 2, 2,107,107,107,107, 2,107,107,107,107, 2, 2,107,107, 2,
- 107,107,107,107, 2, 1,107,107, 2, 2,107, 2, 2, 2, 2, 2,
- 2,107, 2, 2,107,107,137,137,137,137, 2,137,137,137,137,137,
- 2, 2,124,124,124,124,124,124, 2, 2,123,123,123,123,123,123,
- 2, 2,114,114,114,114,114, 2, 2, 2,114,114, 2, 2,102,102,
- 102,102,102,102, 2, 2,126,126,126,126,126,126,126, 2, 2,126,
- 126,126,142,142,142,142,125,125,125,125,125,125,125, 2, 2, 2,
- 2,125,154,154,154,154,154,154,154, 2, 2,154, 2, 2, 2,154,
- 154, 2,154,154, 2,154,154, 2, 2,154,154,154, 2, 2,150,150,
- 150,150, 2, 2,150,150,150, 2, 2, 2,141,141,141,141,140,140,
- 140,140,140,140,140, 2,121,121,121,121,121, 2, 2, 2, 7, 7,
- 2, 2,133,133,133,133,133, 2,133,133,133,133,133, 2,133,133,
- 2, 2,133, 2, 2, 2,134,134,134,134, 2, 2,134,134, 2,134,
- 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138,
- 2,138, 2, 2,138, 2,138,138, 2, 2,143,143,143,143,143,143,
- 2,143,143, 2,143,143,143,143,143, 2,143, 2, 2, 2,143,143,
- 2, 2,145,145,145,145,145, 2, 2, 2,163,163,163,163,163, 2,
- 163,163,163,163,163, 2, 2, 2,163,163,163,163, 2, 2, 86, 2,
- 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2,
- 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80,
- 2, 2,127,127,127,127,127,127,127, 2, 79, 2, 2, 2,115,115,
- 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159,
- 159,159,159,159,159, 2,159,159, 2, 2,103,103,103,103,103,103,
- 2, 2,119,119,119,119,119,119, 2, 2,119,119, 2,119, 2,119,
- 119,119,146,146,146,146,146,146,146, 2, 99, 99, 99, 99, 99, 99,
- 99, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136,
- 136,136,155,155,155,155,155,155, 2, 2,136, 2, 2, 2, 2, 17,
- 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, 17, 2, 2, 2,
- 15, 2, 2, 17, 2, 2,139,139,139,139,105,105,105,105,105,105,
- 105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, 2, 2, 0, 0,
- 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, 0, 2, 2, 0,
- 0, 2, 0, 2, 0, 2,131,131,131,131, 2, 2, 2,131, 2,131,
- 131,131, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 2, 56, 56, 2,
- 56, 56, 6, 6, 2, 2, 2, 2, 2, 6,151,151,151,151,151, 2,
- 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,160,160,160,160,
- 160, 2,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164,
- 164,164,164,164, 2, 2, 2, 30, 30, 2,113,113,113,113,113, 2,
- 2,113,113,113,113, 2,132,132,132,132,132,132, 2, 2, 2, 2,
- 132,132, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 2,
- 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 15, 0, 0, 2, 13, 2,
- 2, 2, 13, 13, 13, 2, 2, 0, 2, 2, 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14,
- 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24,
- 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35,
- 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 41, 42, 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, 0, 43, 44, 0, 45, 0, 0,
- 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0,
- 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0,
- 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,
- 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61,
- 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 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, 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, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0,
- 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,
- 113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 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,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121,
- 0,122,123,124,125,126, 0,127, 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,128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 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,165, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 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,169,170, 0,
- 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178,179,180,
- 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,
- 197,198,199,200,201,202,203,204,205,206, 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, 1, 2, 3, 4,
-};
-static const uint16_t
-_hb_ucd_u16[10040] =
-{
- 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12,
- 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23,
- 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31,
- 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39,
- 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13,
- 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50,
- 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58,
- 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66,
- 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32,
- 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101,
- 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113,
- 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124,
- 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135,
- 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140,
- 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140,
- 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167,
- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48,
- 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175,
- 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183,
- 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193,
- 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199,
- 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209,
- 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140,
- 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225,
- 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235,
- 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13,
- 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250,
- 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265,
- 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278,
- 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282,
- 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271,
- 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209,
- 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279,
- 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305,
- 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308,
- 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313,
- 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140,
- 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
- 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331,
- 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48,
- 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
- 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48,
- 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342,
- 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349,
- 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360,
- 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151,
- 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377,
- 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11,
- 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206,
- 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391,
- 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140,
- 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48,
- 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403,
- 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410,
- 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419,
- 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71,
- 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428,
- 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430,
- 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140,
- 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439,
- 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140,
- 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140,
- 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453,
- 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271,
- 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467,
- 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474,
- 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476,
- 48, 48, 477, 478, 140, 140, 140, 479, 48, 464, 480, 48, 62, 481, 140, 48,
- 482, 140, 140, 48, 483, 140, 48, 314, 484, 48, 48, 485, 486, 457, 487, 488,
- 222, 48, 48, 489, 490, 48, 196, 192, 491, 48, 492, 493, 494, 48, 48, 495,
- 222, 48, 48, 496, 497, 498, 499, 500, 48, 97, 501, 502, 503, 140, 140, 140,
- 504, 505, 506, 48, 48, 507, 508, 192, 509, 83, 84, 510, 511, 512, 513, 514,
- 48, 48, 48, 515, 516, 517, 478, 140, 48, 48, 48, 518, 519, 192, 140, 140,
- 48, 48, 520, 521, 522, 523, 140, 140, 48, 48, 48, 524, 525, 192, 526, 140,
- 48, 48, 527, 528, 192, 140, 140, 140, 48, 173, 529, 530, 314, 140, 140, 140,
- 48, 48, 501, 531, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 532,
- 533, 534, 48, 535, 536, 192, 140, 140, 140, 140, 537, 48, 48, 538, 539, 140,
- 540, 48, 48, 541, 542, 543, 48, 48, 544, 545, 546, 48, 48, 48, 48, 196,
- 547, 140, 140, 140, 140, 140, 140, 140, 84, 48, 520, 548, 549, 148, 175, 550,
- 48, 551, 552, 553, 140, 140, 140, 140, 554, 48, 48, 555, 556, 192, 557, 48,
- 558, 559, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 560,
- 561, 115, 48, 562, 563, 192, 140, 140, 140, 140, 140, 100, 271, 564, 565, 566,
- 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 567, 568,
- 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 569,
- 48, 48, 48, 570, 571, 572, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140,
- 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 573,
- 48, 48, 48, 574, 575, 576, 577, 578, 48, 140, 140, 140, 140, 140, 140, 140,
- 140, 140, 140, 140, 9, 9, 11, 11, 271, 579, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 580, 581, 582, 582, 583, 584, 140, 140, 140, 140, 585, 586,
- 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140,
- 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 587,
- 48, 48, 588, 589, 140, 590, 591, 48, 48, 48, 48, 48, 48, 48, 48, 206,
- 48, 48, 48, 48, 48, 48, 71, 151, 196, 592, 593, 140, 140, 140, 140, 140,
- 32, 32, 594, 32, 595, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140,
- 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 596, 209, 209, 209, 597, 598,
- 599, 209, 600, 209, 209, 209, 288, 140, 209, 209, 209, 209, 601, 140, 140, 140,
- 140, 140, 140, 140, 271, 602, 271, 602, 209, 209, 209, 209, 209, 287, 271, 461,
- 9, 603, 11, 604, 605, 606, 241, 9, 607, 608, 609, 610, 611, 9, 603, 11,
- 612, 613, 11, 614, 615, 616, 617, 9, 618, 11, 9, 603, 11, 604, 605, 11,
- 241, 9, 607, 617, 9, 618, 11, 9, 603, 11, 619, 9, 620, 621, 622, 623,
- 11, 624, 9, 625, 626, 627, 628, 11, 629, 9, 630, 11, 631, 632, 632, 632,
- 32, 32, 32, 633, 32, 32, 634, 635, 636, 637, 45, 140, 140, 140, 140, 140,
- 638, 639, 640, 140, 140, 140, 140, 140, 641, 642, 643, 27, 27, 27, 644, 140,
- 645, 140, 140, 140, 140, 140, 140, 140, 48, 48, 151, 646, 647, 140, 140, 140,
- 140, 48, 648, 140, 48, 48, 649, 650, 140, 140, 140, 140, 140, 48, 651, 192,
- 140, 140, 140, 140, 140, 140, 652, 200, 48, 48, 48, 48, 653, 595, 140, 140,
- 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
- 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
- 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
- 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
- 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
- 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
- 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
- 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
- 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
- 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
- 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48,
- 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140,
- 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140,
- 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
- 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 1, 2, 1, 2,
- 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9,
- 10, 11, 12, 11, 11, 11, 13, 11, 14, 14, 14, 14, 14, 14, 14, 14,
- 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 17, 18, 17, 17,
- 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30,
- 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27,
- 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 40, 41, 42, 43, 44, 27,
- 45, 46, 27, 27, 27, 27, 47, 27, 48, 48, 48, 48, 48, 49, 50, 48,
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
- 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109,
- 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125,
- 126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135,
- 132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142,
- 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
- 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
- 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
- 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
- 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
- 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125,
- 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
- 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
- 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8,
- 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222,
- 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229,
- 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 125, 235, 125, 0, 0,
- 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 237,
- 0, 238, 0, 0, 0, 0, 0, 0, 239, 239, 239, 239, 239, 239, 4, 4,
- 240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244,
- 143, 245, 246, 246, 246, 246, 14, 14, 0, 0, 0, 0, 0, 247, 125, 125,
- 248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248,
- 248, 248, 248, 248, 248, 251, 125, 252, 253, 0, 254, 255, 256, 257, 257, 257,
- 257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142,
- 265, 0, 263, 263, 0, 0, 266, 260, 142, 265, 0, 0, 0, 0, 142, 267,
- 0, 0, 0, 0, 0, 260, 260, 268, 260, 260, 260, 260, 260, 269, 0, 0,
- 248, 248, 248, 248, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270,
- 271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277,
- 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282,
- 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48,
- 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
- 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
- 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
- 142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125,
- 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125,
- 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 326, 27, 27, 27, 27,
- 27, 327, 27, 27, 328, 125, 125, 27, 8, 285, 329, 0, 0, 330, 331, 332,
- 27, 27, 27, 27, 27, 27, 27, 333, 334, 0, 1, 2, 1, 2, 335, 259,
- 260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125,
- 342, 342, 342, 342, 342, 342, 342, 346, 347, 0, 0, 348, 11, 11, 11, 11,
- 349, 350, 351, 125, 125, 0, 0, 352, 353, 354, 355, 355, 355, 356, 357, 252,
- 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125,
- 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376,
- 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125,
- 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125,
- 389, 4, 4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396,
- 397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125,
- 406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415,
- 416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425,
- 426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125,
- 431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125,
- 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 440,
- 441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450,
- 451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459,
- 460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467,
- 468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476,
- 477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125,
- 488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125,
- 494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125,
- 500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125,
- 125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125,
- 125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519,
- 519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125,
- 524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125,
- 533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125,
- 125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125,
- 125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552,
- 552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555,
- 552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558,
- 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125,
- 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125,
- 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567,
- 567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577,
- 573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578,
- 578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580,
- 582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585,
- 585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587,
- 587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125,
- 125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596,
- 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597,
- 598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125,
- 8, 8, 603, 8, 604, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125,
- 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 606, 0, 0, 0, 607, 608,
- 609, 0, 610, 0, 0, 0, 235, 125, 11, 11, 11, 11, 611, 125, 125, 125,
- 125, 125, 125, 125, 0, 266, 0, 266, 0, 0, 0, 0, 0, 234, 0, 612,
- 0, 0, 0, 0, 0, 224, 0, 0, 0, 613, 614, 615, 616, 0, 0, 0,
- 617, 618, 0, 619, 620, 621, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 623, 0, 0, 0, 624, 624, 624, 624, 624, 624, 624, 624,
- 625, 626, 627, 125, 125, 125, 125, 125, 4, 628, 629, 125, 125, 125, 125, 125,
- 630, 631, 632, 14, 14, 14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125,
- 635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642,
- 125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646,
- 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125,
- 650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334,
- 0, 0, 0, 653, 125, 125, 125, 125, 334, 0, 0, 247, 125, 125, 125, 125,
- 654, 27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664,
- 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 605,
- 0, 0, 247, 125, 125, 125, 665, 0, 666, 0, 0, 252, 612, 667, 605, 125,
- 0, 0, 0, 0, 0, 668, 350, 350, 0, 0, 0, 0, 0, 0, 0, 669,
- 0, 0, 0, 0, 0, 285, 252, 228, 252, 0, 0, 0, 670, 285, 0, 0,
- 670, 0, 247, 667, 125, 125, 125, 125, 0, 0, 0, 0, 0, 266, 247, 350,
- 612, 0, 0, 671, 672, 252, 612, 612, 0, 330, 0, 0, 235, 125, 125, 285,
- 248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248,
- 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248,
- 248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125,
- 248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
- 675, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2,
- 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2,
- 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 8, 8, 8, 8, 16, 8, 8, 8, 17, 18, 18, 18,
- 19, 19, 19, 19, 19, 20, 19, 19, 21, 22, 22, 22, 22, 22, 22, 22,
- 22, 23, 21, 22, 22, 22, 23, 21, 24, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 12, 12, 25, 25, 26, 27, 25, 28, 12, 12, 29, 30, 29, 31,
- 29, 29, 32, 32, 29, 29, 29, 29, 31, 29, 33, 7, 7, 34, 29, 29,
- 35, 29, 29, 29, 29, 29, 29, 30, 36, 36, 36, 37, 36, 36, 36, 36,
- 36, 36, 38, 39, 40, 40, 40, 40, 41, 12, 12, 12, 42, 42, 42, 42,
- 42, 42, 43, 44, 45, 45, 45, 45, 45, 45, 45, 46, 45, 45, 45, 47,
- 48, 48, 48, 48, 48, 48, 48, 49, 36, 36, 38, 12, 29, 29, 29, 50,
- 51, 12, 29, 29, 52, 29, 29, 29, 53, 53, 53, 53, 54, 55, 53, 53,
- 53, 56, 53, 53, 57, 58, 57, 59, 59, 57, 57, 57, 57, 57, 60, 57,
- 61, 62, 63, 57, 57, 59, 59, 64, 12, 65, 12, 66, 57, 62, 57, 57,
- 57, 57, 57, 64, 67, 67, 68, 69, 70, 71, 71, 71, 71, 71, 72, 71,
- 72, 73, 74, 72, 68, 69, 70, 74, 75, 12, 67, 76, 12, 77, 71, 71,
- 71, 68, 12, 12, 78, 78, 79, 80, 80, 79, 79, 79, 79, 79, 81, 79,
- 81, 78, 82, 79, 79, 80, 80, 82, 83, 12, 12, 12, 79, 84, 79, 79,
- 82, 12, 78, 79, 85, 85, 86, 87, 87, 86, 86, 86, 86, 86, 88, 86,
- 88, 85, 89, 86, 86, 87, 87, 89, 12, 85, 12, 90, 86, 91, 86, 86,
- 86, 86, 12, 12, 92, 93, 94, 92, 95, 96, 97, 95, 98, 99, 94, 92,
- 100, 100, 96, 92, 94, 92, 95, 96, 99, 98, 12, 12, 12, 92, 100, 100,
- 100, 100, 94, 12, 101, 101, 101, 102, 102, 101, 101, 101, 101, 101, 102, 101,
- 101, 101, 103, 101, 101, 102, 102, 103, 12, 104, 105, 106, 101, 107, 101, 101,
- 12, 108, 101, 101, 109, 109, 109, 110, 110, 109, 109, 109, 109, 109, 110, 109,
- 109, 111, 112, 109, 109, 110, 110, 112, 12, 113, 12, 113, 109, 114, 109, 109,
- 111, 12, 12, 12, 115, 115, 115, 116, 116, 115, 115, 115, 115, 115, 115, 115,
- 115, 116, 116, 115, 12, 115, 115, 115, 115, 117, 115, 115, 118, 118, 119, 119,
- 119, 120, 121, 119, 119, 119, 119, 119, 122, 119, 119, 123, 119, 120, 124, 125,
- 119, 126, 119, 119, 12, 121, 119, 119, 121, 127, 12, 12, 128, 129, 129, 129,
- 129, 129, 129, 129, 129, 129, 130, 131, 129, 129, 129, 12, 12, 12, 12, 12,
- 132, 133, 134, 135, 135, 135, 135, 135, 135, 136, 135, 135, 135, 135, 135, 137,
- 135, 138, 135, 134, 135, 135, 137, 135, 139, 139, 139, 139, 139, 139, 140, 139,
- 139, 139, 139, 141, 140, 139, 139, 139, 139, 139, 139, 142, 139, 143, 144, 12,
- 145, 145, 145, 145, 146, 146, 146, 146, 146, 147, 12, 148, 146, 146, 149, 146,
- 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 152, 153, 151, 154, 152, 153,
- 152, 153, 151, 154, 152, 153, 151, 151, 151, 154, 151, 151, 151, 151, 154, 155,
- 151, 151, 151, 156, 151, 151, 153, 12, 157, 157, 157, 157, 157, 158, 157, 158,
- 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 161, 162, 162, 162, 162,
- 162, 162, 163, 164, 162, 162, 165, 12, 166, 166, 166, 166, 166, 167, 12, 168,
- 169, 169, 169, 169, 169, 170, 12, 12, 171, 171, 171, 171, 171, 12, 12, 12,
- 172, 172, 172, 173, 173, 12, 12, 12, 174, 174, 174, 174, 174, 174, 174, 175,
- 174, 174, 175, 12, 176, 177, 178, 178, 178, 178, 179, 12, 178, 178, 178, 178,
- 178, 178, 180, 12, 178, 178, 181, 12, 159, 182, 12, 12, 183, 183, 183, 183,
- 183, 183, 183, 184, 183, 183, 183, 12, 185, 183, 183, 183, 186, 186, 186, 186,
- 186, 186, 186, 187, 186, 188, 12, 12, 189, 189, 189, 189, 189, 189, 189, 12,
- 189, 189, 190, 12, 189, 189, 191, 192, 193, 193, 193, 193, 193, 193, 193, 194,
- 195, 195, 195, 195, 195, 195, 195, 196, 195, 195, 195, 197, 195, 195, 198, 12,
- 195, 195, 195, 198, 7, 7, 7, 199, 200, 200, 200, 200, 200, 200, 200, 201,
- 200, 200, 200, 202, 203, 203, 203, 203, 204, 204, 204, 204, 204, 12, 12, 204,
- 205, 205, 205, 205, 205, 205, 206, 205, 205, 205, 207, 208, 209, 209, 209, 209,
- 19, 19, 210, 12, 146, 146, 211, 212, 203, 203, 12, 12, 213, 7, 7, 7,
- 214, 7, 215, 216, 0, 215, 217, 12, 2, 218, 219, 2, 2, 2, 2, 220,
- 221, 218, 222, 2, 2, 2, 223, 2, 2, 2, 2, 224, 8, 225, 8, 225,
- 8, 8, 226, 226, 8, 8, 8, 225, 8, 15, 8, 8, 8, 10, 8, 227,
- 10, 15, 8, 14, 0, 0, 0, 228, 0, 229, 0, 0, 230, 0, 0, 231,
- 0, 0, 0, 232, 2, 2, 2, 233, 234, 12, 12, 12, 235, 12, 12, 12,
- 0, 236, 237, 0, 4, 0, 0, 0, 0, 0, 0, 4, 2, 2, 5, 12,
- 0, 232, 12, 12, 0, 0, 232, 12, 238, 238, 238, 238, 0, 239, 0, 0,
- 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18,
- 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12,
- 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247,
- 247, 12, 12, 12, 247, 249, 12, 12, 0, 0, 0, 12, 0, 250, 0, 0,
- 251, 247, 252, 253, 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255,
- 255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,
- 12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,
- 0, 12, 12, 12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0,
- 267, 267, 267, 267, 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270,
- 271, 271, 271, 271, 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12,
- 237, 2, 2, 2, 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12,
- 277, 2, 2, 2, 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12,
- 280, 280, 280, 280, 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283,
- 281, 281, 282, 12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286,
- 286, 12, 12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290,
- 289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12,
- 294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12,
- 12, 12, 299, 297, 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154,
- 155, 154, 12, 12, 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304,
- 300, 300, 304, 12, 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12,
- 247, 247, 247, 249, 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24,
- 25, 26, 25, 307, 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29,
- 29, 29, 29, 311, 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313,
- 232, 0, 0, 0, 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315,
- 316, 0, 0, 0, 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150,
- 319, 150, 319, 288, 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321,
- 320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324,
- 320, 320, 322, 12, 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14,
- 0, 0, 0, 234, 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327,
- 327, 327, 327, 328, 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0,
- 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12,
- 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338,
- 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341,
- 342, 342, 342, 342, 343, 343, 343, 343, 343, 343, 343, 344, 343, 343, 344, 12,
- 345, 345, 345, 345, 345, 12, 345, 345, 345, 345, 345, 12, 346, 346, 346, 346,
- 346, 346, 12, 12, 347, 347, 347, 347, 347, 12, 12, 348, 349, 349, 350, 349,
- 350, 351, 349, 349, 351, 349, 349, 349, 351, 349, 351, 352, 353, 353, 353, 353,
- 353, 354, 12, 12, 353, 355, 12, 12, 353, 353, 12, 12, 2, 274, 2, 2,
- 356, 2, 273, 12, 357, 358, 359, 357, 357, 357, 357, 357, 357, 360, 361, 362,
- 363, 363, 363, 363, 363, 364, 363, 363, 365, 365, 365, 365, 366, 366, 366, 366,
- 366, 366, 366, 367, 12, 368, 366, 366, 369, 369, 369, 369, 370, 371, 372, 369,
- 373, 373, 373, 373, 373, 373, 373, 374, 375, 375, 375, 375, 375, 375, 376, 377,
- 378, 378, 378, 378, 379, 379, 379, 379, 379, 379, 12, 379, 380, 379, 379, 379,
- 381, 382, 12, 381, 381, 383, 383, 381, 381, 381, 381, 381, 381, 384, 385, 386,
- 381, 381, 387, 12, 388, 388, 388, 388, 389, 389, 389, 389, 390, 390, 390, 390,
- 390, 391, 392, 390, 390, 391, 12, 12, 393, 393, 393, 393, 393, 394, 395, 393,
- 396, 396, 396, 396, 396, 397, 396, 396, 398, 398, 398, 398, 399, 12, 398, 398,
- 400, 400, 400, 400, 401, 12, 402, 403, 12, 12, 402, 400, 404, 404, 404, 404,
- 404, 404, 405, 12, 406, 406, 406, 406, 407, 12, 12, 12, 407, 12, 408, 406,
- 409, 409, 409, 409, 409, 409, 12, 12, 409, 409, 410, 12, 411, 411, 411, 411,
- 411, 411, 412, 413, 413, 12, 12, 12, 12, 12, 12, 414, 415, 415, 415, 415,
- 415, 415, 12, 12, 416, 416, 416, 416, 416, 416, 417, 12, 418, 418, 418, 418,
- 418, 418, 419, 12, 420, 420, 420, 420, 420, 420, 420, 12, 421, 421, 421, 421,
- 421, 422, 12, 12, 423, 423, 423, 423, 423, 423, 423, 424, 425, 423, 423, 423,
- 423, 424, 12, 426, 427, 427, 427, 427, 428, 12, 12, 429, 430, 430, 430, 430,
- 430, 430, 431, 12, 430, 430, 432, 12, 433, 433, 433, 433, 433, 434, 433, 433,
- 433, 433, 12, 12, 435, 435, 435, 435, 435, 436, 12, 12, 437, 437, 437, 437,
- 118, 119, 119, 119, 119, 127, 12, 12, 438, 438, 438, 438, 439, 438, 438, 438,
- 440, 12, 12, 12, 441, 442, 443, 444, 441, 441, 441, 444, 441, 441, 445, 12,
- 446, 446, 446, 446, 446, 446, 447, 12, 446, 446, 448, 12, 449, 450, 449, 451,
- 451, 449, 449, 449, 449, 449, 452, 449, 452, 450, 453, 449, 449, 451, 451, 454,
- 455, 456, 12, 450, 449, 457, 449, 455, 449, 455, 12, 12, 458, 458, 458, 458,
- 458, 458, 458, 459, 460, 12, 12, 12, 461, 461, 461, 461, 461, 461, 12, 12,
- 461, 461, 462, 12, 463, 463, 463, 463, 463, 464, 463, 463, 463, 463, 463, 464,
- 465, 465, 465, 465, 465, 466, 12, 12, 465, 465, 467, 12, 178, 178, 178, 180,
- 468, 468, 468, 468, 468, 468, 469, 12, 470, 470, 470, 470, 470, 470, 471, 472,
- 470, 470, 470, 12, 470, 471, 12, 12, 473, 473, 473, 473, 473, 473, 473, 12,
- 474, 474, 474, 474, 475, 12, 12, 476, 477, 478, 479, 477, 477, 480, 477, 477,
- 477, 477, 477, 477, 477, 481, 482, 477, 477, 478, 12, 12, 477, 477, 483, 12,
- 484, 484, 485, 484, 484, 484, 484, 484, 484, 486, 12, 12, 487, 487, 487, 487,
- 487, 487, 12, 12, 488, 488, 488, 488, 489, 12, 12, 12, 490, 490, 490, 490,
- 490, 490, 491, 12, 53, 53, 492, 12, 493, 493, 494, 493, 493, 493, 493, 493,
- 493, 495, 493, 493, 493, 496, 12, 12, 493, 493, 493, 497, 498, 498, 498, 498,
- 499, 498, 498, 498, 498, 498, 500, 498, 498, 501, 12, 12, 502, 503, 504, 502,
- 502, 502, 502, 502, 502, 503, 505, 504, 502, 502, 12, 12, 502, 502, 506, 12,
- 507, 508, 509, 507, 507, 507, 507, 507, 507, 507, 507, 510, 508, 507, 511, 12,
- 507, 507, 512, 12, 513, 513, 513, 513, 513, 513, 514, 12, 515, 515, 515, 515,
- 516, 515, 515, 515, 515, 515, 517, 518, 515, 515, 519, 12, 520, 12, 12, 12,
- 100, 100, 100, 100, 96, 12, 12, 98, 521, 521, 521, 521, 521, 521, 522, 12,
- 521, 521, 521, 523, 521, 524, 12, 12, 521, 12, 12, 12, 525, 525, 525, 525,
- 526, 12, 12, 12, 527, 527, 527, 527, 527, 528, 12, 12, 529, 529, 529, 529,
- 529, 530, 12, 12, 272, 272, 531, 12, 532, 532, 532, 532, 532, 532, 532, 533,
- 532, 532, 534, 535, 536, 536, 536, 536, 536, 536, 536, 537, 536, 536, 538, 12,
- 539, 539, 539, 539, 539, 539, 539, 540, 539, 540, 12, 12, 541, 541, 541, 541,
- 541, 542, 12, 12, 541, 541, 543, 541, 543, 541, 541, 541, 541, 541, 12, 544,
- 545, 545, 545, 545, 545, 545, 546, 12, 547, 547, 547, 547, 547, 547, 548, 549,
- 547, 547, 12, 549, 550, 551, 12, 12, 249, 12, 12, 12, 552, 552, 552, 552,
- 552, 552, 12, 12, 553, 553, 553, 553, 553, 554, 12, 12, 552, 552, 555, 12,
- 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12,
- 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12,
- 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12,
- 563, 563, 566, 563, 7, 7, 7, 567, 7, 199, 12, 12, 0, 246, 12, 12,
- 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, 213, 569, 7, 0,
- 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, 0, 0, 0, 229,
- 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, 0, 240, 232, 316,
- 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, 229, 0, 0, 0,
- 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, 574, 574, 574, 12,
- 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, 12, 275, 273, 12,
- 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, 19, 19, 19, 581,
- 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585,
- 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589,
- 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, 151, 154, 151, 594,
- 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597, 12, 12,
- 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, 0, 234, 12, 12,
- 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, 604, 310, 603, 414,
- 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, 29, 29, 606, 29,
- 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, 12, 239, 0, 0,
- 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, 0, 232, 131, 0,
- 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, 608, 12, 12, 12,
- 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962,
- 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0,
- 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,
- 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0,
- 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
- 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160,
- 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,
- 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206,
- 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,
- 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,
- 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,
- 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
- 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
- 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,
- 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,
- 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
- 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
- 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130,
- 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,
- 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522,
- 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567,
- 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549,
- 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559,
- 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,
- 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,
- 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662,
- 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,
- 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671,
- 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,
- 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,
- 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
- 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
- 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
- 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
- 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
- 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
- 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
- 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
- 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
- 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,
- 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
- 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
- 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
- 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
- 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
- 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,
- 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,
- 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,
- 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
- 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,
- 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790,
- 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
- 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,
- 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,
- 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
- 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
- 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,
- 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,
- 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,
- 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,
- 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,
- 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0,
- 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0,
- 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847,
- 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,
- 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,
- 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0,
- 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,
- 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890,
- 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897,
- 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,
- 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917,
- 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924,
- 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,
- 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825,
- 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
- 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
- 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
- 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
- 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
- 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
- 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
- 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
- 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
- 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
- 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
- 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
- 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
- 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
- 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
- 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
- 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525,
- 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0,
- 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
- 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
- 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
- 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
- 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171,
- 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
- 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
- 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
- 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
- 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
- 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916,
- 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,
- 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,
- 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121,
- 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142,
- 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169,
- 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
- 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
- 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
- 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39,
- 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266,
- 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286,
- 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852,
- 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324,
- 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
- 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50,
- 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78,
- 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55,
- 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861,
- 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
- 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467,
- 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
- 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875,
- 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531,
- 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559,
- 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73,
- 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898,
- 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902,
- 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
- 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81,
- 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669,
- 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686,
- 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
- 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
- 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925,
- 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800,
- 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816,
- 817, 818, 819, 820, 821, 935, 0, 0,
-};
-static const int16_t
-_hb_ucd_i16[92] =
-{
- 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16,
- 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914,
- 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0,
- 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8,
- -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0,
- 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0,
-};
-
-static inline uint_fast8_t
-_hb_ucd_gc (unsigned u)
-{
- return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
-}
-static inline uint_fast8_t
-_hb_ucd_ccc (unsigned u)
-{
- return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
-}
-static inline unsigned
-_hb_ucd_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline int_fast16_t
-_hb_ucd_bmg (unsigned u)
-{
- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
-}
-static inline uint_fast8_t
-_hb_ucd_sc (unsigned u)
-{
- return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
-}
-static inline uint_fast16_t
-_hb_ucd_dm (unsigned u)
-{
- return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
-}
-
-
-#else
-
-static const uint8_t
-_hb_ucd_u8[13370] =
-{
- 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 21, 21, 21, 21, 23, 7, 7,
- 7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 21, 36,
- 7, 7, 7, 7, 35, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71,
- 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67,
- 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34,
- 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90,
- 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
- 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108,
- 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119,
- 120,121,122,123,124,125,126,127, 34,128,129,111,130,131,132,133,
- 134,135,136,137,138,139,140,111,141,142,111,143,144,145,146,111,
- 147,148,149,150,151,152,153,111,154,155,156,157,111,158,159,160,
- 34, 34, 34, 34, 34, 34, 34, 34,161, 34, 34,111,111,111,111,111,
- 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,162,
- 34, 34, 34, 34, 34, 34, 34, 34,163,111,111,111,111,111,111,111,
- 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
- 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111,
- 34, 34, 34, 34,164,165,166, 34,111,111,111,111,167,168,169,170,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,
- 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119,
- 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,
- 111,111,111,111,111,111,111,111, 34,171,111,111,111,111,111,111,
- 111,111,111,111,111,111,111,111,111,111,111,111,111,111,172, 67,
- 67, 67,173,174,175,130, 65,111,176,177,178,179,180,181,182,183,
- 67, 67, 67, 67,184,185,111,111,111,111,111,111,111,111,186,111,
- 187,188,189,111,111,190,111,111,111,191,111,111,111,111,111, 34,
- 34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111,
- 67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111,
- 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
- 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111,
- 200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2,
- 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25,
- 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
- 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
- 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
- 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
- 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
- 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
- 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
- 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
- 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10,
- 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
- 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11,
- 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
- 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53,
- 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55,
- 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61,
- 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43,
- 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36,
- 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73,
- 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36,
- 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36,
- 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20,
- 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43,
- 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2,
- 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 59, 43, 43, 43, 43,
- 36, 36, 36, 36, 75, 43, 43, 43, 43, 76, 43, 43, 43, 43, 43, 43,
- 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78,
- 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36,
- 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36,
- 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78,
- 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36,
- 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43,
- 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78,
- 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36,
- 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2,
- 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43,
- 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79,
- 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36,
- 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43,
- 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7,
- 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84,
- 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43,
- 43, 43, 77, 78, 78, 78, 81, 36, 86, 82, 78, 78, 78, 78, 78, 78,
- 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78,
- 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87,
- 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77,
- 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2,
- 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57,
- 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36,
- 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36,
- 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61,
- 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78,
- 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43,
- 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61,
- 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43,
- 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43,
- 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36,
- 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61,
- 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43,
- 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16,
- 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66,
- 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94,
- 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36,
- 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2,
- 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78,
- 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43,
- 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 76,
- 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36,
- 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78,
- 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2,
- 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78,
- 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2,
- 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36,
- 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 36,
- 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2,
- 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36,
- 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2,
- 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2,
- 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2,
- 43, 57, 43, 43, 43, 43, 43, 43, 77, 43, 43, 43, 65, 36, 64, 36,
- 36, 36, 65, 82, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40,
- 40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16,
- 16, 16, 16, 16, 16,100, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32,
- 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11,
- 16, 16, 16, 16,101,101,101,101, 16, 16, 16, 16, 11, 11,102,103,
- 41, 16, 16, 16, 11, 11,102, 41, 16, 16, 16, 16, 11, 11,104, 41,
- 105,105,105,105,105,106, 59, 59, 51, 51, 51, 2,107,108,107,108,
- 2, 2, 2, 2,109, 59, 59,110, 2, 2, 2, 2,111,112, 2,113,
- 114, 2,115,116, 2, 2, 2, 2, 2, 9,114, 2, 2, 2, 2,117,
- 59, 59, 59, 59, 59, 59, 59, 59,118, 40, 27, 27, 27, 8,115,119,
- 27, 27, 27, 27, 27, 8,115, 94, 20, 20, 20, 20, 20, 20, 20, 20,
- 43, 43, 43, 43, 43, 43,120, 48, 99, 48, 99, 43, 43, 43, 43, 43,
- 61,121, 61,122, 61, 34, 11, 16, 11, 32,122, 61, 46, 11, 11, 61,
- 61, 61,121,121,121, 11, 11,123, 11, 11, 35, 36, 39, 61, 16, 11,
- 8, 8, 46, 16, 16, 26, 61,124, 95, 95, 95, 95, 95, 95, 95, 95,
- 95,125,126, 95,127, 61, 61, 61, 8, 8,128, 61, 61, 8, 61, 61,
- 128, 26, 61,128, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 61, 8,
- 61,128,128, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 61, 61, 61, 61, 4, 4, 61, 61,
- 8, 61, 61, 61,129,130, 61, 61, 61, 61, 61, 61, 61, 61,128, 61,
- 61, 61, 61, 61, 61, 26, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61,
- 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27,
- 61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, 26,
- 61, 61, 61, 61, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27,
- 27, 27, 61, 61, 61, 61, 61, 61, 8, 8,115,131, 8, 8, 8, 8,
- 8, 8, 8, 4, 4, 4, 4, 4, 8,115,132,132,132,132,132,132,
- 132,132,132,132,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8,
- 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,128, 26, 8, 8,128, 61,
- 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11,
- 32, 32,124, 61, 61,122, 34,133, 43, 32, 16, 16, 50, 2, 90, 2,
- 36, 36, 36, 36, 36, 36, 36, 75, 2, 2, 2, 2, 2, 2, 2, 56,
- 2,107,107, 2,111,112,107, 2, 2, 2, 2, 6, 2, 98,107, 2,
- 107, 4, 4, 4, 4, 2, 2, 80, 2, 2, 2, 2, 2, 51, 2, 2,
- 98,134, 2, 2, 2, 2, 2, 2, 61, 2,135,132,132,132,136, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 1, 2,137,138, 4, 4, 4, 4,
- 4, 61, 4, 4, 4, 4,139, 94,140, 95, 95, 95, 95, 43, 43, 78,
- 141, 40, 40, 61, 95,142, 58, 61, 72, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 64,143,144, 63, 36, 36, 36, 36, 36, 58, 40, 63,
- 61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61,
- 61, 61, 61, 61, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 27,
- 36, 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,146, 2,
- 32, 32, 32, 32, 32, 32, 32, 64, 48,147, 43, 43, 43, 43, 43, 80,
- 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 95, 95, 95, 95, 95,
- 43, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41,144, 40, 40, 40, 40,
- 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32,
- 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,148, 34, 35,
- 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32,
- 11, 11, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 34, 16, 16, 16,
- 32, 16, 16, 32, 32, 16, 16, 16, 16, 40,149, 35, 40, 35, 36, 36,
- 36, 65, 36, 65, 36, 64, 36, 36, 36, 82, 79, 77, 61, 61, 43, 43,
- 27, 27, 27, 61,150, 61, 61, 61, 36, 36, 2, 2, 2, 2, 2, 2,
- 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 78, 78, 78, 78, 78, 78,
- 78, 78, 43, 43, 43, 43, 43, 2, 43, 36, 36, 36, 2, 66, 66, 64,
- 36, 36, 36, 43, 43, 43, 43, 2, 36, 36, 36, 64, 43, 43, 43, 43,
- 43, 78, 78, 78, 78, 78, 78, 97, 36, 64, 78, 43, 43, 78, 43, 78,
- 97, 2, 2, 2, 2, 2, 2, 80, 7, 7, 7, 7, 7, 7, 7, 2,
- 36, 36, 64, 63, 36, 36, 36, 36, 36, 36, 36, 36, 64, 43, 43, 77,
- 79, 77, 79, 43, 43, 43, 43, 43, 36, 64, 36, 36, 36, 36, 77, 78,
- 7, 7, 7, 7, 7, 7, 2, 2, 63, 36, 36, 71, 61, 82, 77, 36,
- 65, 43, 65, 64, 65, 36, 36, 43, 36, 36, 36, 36, 36, 36, 75, 2,
- 36, 36, 36, 36, 36, 82, 43, 78, 2, 75,151, 43, 43, 43, 43, 43,
- 16, 16, 16, 16, 16,103, 40, 40, 16, 16, 16, 16,100, 41, 41, 41,
- 36, 82, 79, 78, 77, 97, 79, 43,152,152,152,152,152,152,152,152,
- 153,153,153,153,153,153,153,153, 16, 16, 16, 16, 16, 16, 35, 65,
- 36, 36, 36, 36,154, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
- 41, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132,
- 36, 36, 36, 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 36,150, 61,
- 2, 2, 2,135,116, 2, 2, 2, 6,155,156,132,132,132,132,132,
- 132,132,116,135,116, 2,113,157, 2, 2, 2, 2,139,132,132,116,
- 2,158, 8, 8, 60, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,159,
- 2, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,115,
- 116, 4, 2, 36, 36, 36, 36, 36, 63, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 40, 20,160, 53, 20, 26, 8,128, 61,
- 61, 61, 61, 61,161, 59, 61, 61, 2, 2, 2, 90, 27, 27, 27, 27,
- 27, 27, 27, 84, 61, 61, 61, 61, 95, 95,127, 27, 84, 61, 61, 61,
- 61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43,
- 162,162,162,162,162,162,162,162,163, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 87, 36,138, 36, 36, 36, 36, 95, 95, 95,
- 36, 36, 36, 36, 36, 36, 36, 58,164, 95, 95, 95, 95, 95, 95, 95,
- 11, 11, 11, 32, 16, 16, 16, 16, 36, 36, 36, 58, 27, 27, 27, 27,
- 36, 36, 36, 71,145, 27, 27, 27, 36, 36, 36,165, 27, 27, 27, 27,
- 36, 36, 36, 36, 36,165, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30,
- 36, 36, 36, 36, 36, 36, 27, 36, 64, 43, 43, 43, 43, 43, 43, 43,
- 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,165, 30,
- 36, 36, 36, 36, 36, 36,165, 27, 36, 36, 36, 36, 72, 36, 36, 36,
- 36, 36, 64, 43, 43,163, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2,
- 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27,
- 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 64,166, 51,
- 27, 27, 27, 87, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2,
- 36, 43, 43, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27,
- 79, 81, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57, 2, 2, 2, 2,
- 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7,
- 65, 64, 65, 36, 36, 36, 36, 64, 78, 79, 43, 77, 79, 57, 73, 2,
- 2, 43, 43, 43, 43, 43, 67, 59, 36, 36, 36, 64, 43, 43, 79, 43,
- 43, 43, 43, 7, 7, 7, 7, 7, 2, 2, 82, 81, 36, 36, 36, 36,
- 36, 64, 2, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 43, 77,
- 81, 36, 58, 2, 56, 43, 57, 79, 7, 7, 7, 7, 7, 58, 58, 2,
- 90, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 78, 79,
- 43, 78, 77, 43, 2, 2, 2, 65, 36, 36, 36, 36, 36, 36, 36, 64,
- 77, 78, 78, 78, 78, 78, 78, 78, 36, 36, 36, 82, 78, 78, 81, 36,
- 36, 78, 78, 43, 43, 43, 43, 43, 36, 36, 82, 78, 43, 43, 43, 43,
- 78, 43, 77, 65, 36, 58, 2, 2, 7, 7, 7, 7, 7, 2, 2, 65,
- 78, 79, 43, 43, 77, 77, 78, 79, 77, 43, 36, 66, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 78, 78, 43, 79,
- 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 43,
- 78, 79, 43, 43, 43, 77, 79, 79, 57, 2, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 43, 79, 58, 2, 2, 2,
- 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89,
- 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87,
- 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2,
- 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36,
- 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43,
- 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43,
- 43, 43, 43, 77, 43, 2, 66, 2, 43, 43, 43, 43, 43, 43, 43, 79,
- 58, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,
- 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43,
- 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78,
- 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2,
- 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78,
- 77, 57, 2, 2, 2, 2, 2, 2, 27, 27, 84, 61, 61, 61, 53, 20,
- 150, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 21,
- 65, 36, 36, 64, 43, 43, 43, 43, 43, 43, 57, 2, 2, 2, 2, 2,
- 43, 43, 43, 57, 2, 2, 61, 61, 40, 40, 89, 61, 61, 61, 61, 61,
- 7, 7, 7, 7, 7,167, 27, 27, 27, 87, 36, 36, 36, 36, 36, 36,
- 27, 27, 27, 30, 2, 2, 2, 2, 82, 78, 78, 78, 78, 78, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 79, 43, 68, 40, 40, 40, 40, 40, 40,
- 40, 80, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 47, 57,
- 61, 61,168, 79, 43, 61,168, 78, 78,169, 59, 59, 59, 76, 43, 43,
- 43, 70, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61,
- 61, 43, 70, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16,
- 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
- 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
- 11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11,
- 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33,
- 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31,
- 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16,
- 16, 33, 16, 16, 16, 32, 16, 7, 43, 43, 43, 70, 61, 47, 43, 43,
- 43, 43, 43, 43, 43, 43, 70, 61, 61, 61, 47, 61, 61, 61, 61, 61,
- 61, 61, 70, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 43, 43,
- 16, 16, 16, 16, 16, 39, 16, 16, 43, 43, 43, 68, 40, 40, 40, 40,
- 7, 7, 7, 7, 7, 7, 7, 71, 36, 36, 36, 36, 36, 36, 36, 43,
- 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 7, 7,170,
- 36, 36, 36, 36, 36, 75, 43, 43, 16, 16, 43, 43, 43, 68, 40, 40,
- 27, 27, 27, 27, 27, 27,145, 27,171, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61,
- 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21,
- 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9,
- 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0,
- 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15,
- 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7,
- 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12,
- 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17,
- 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1,
- 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1,
- 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 7, 6,
- 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7,
- 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7,
- 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12,
- 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19,
- 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22,
- 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 9, 26, 26, 9, 26, 5,
- 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25,
- 18, 22, 5, 12, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, 17, 22,
- 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21,
- 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16,
- 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15,
- 21, 14, 7, 15, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0,
- 14, 0, 0, 0, 0, 0, 15, 0, 16, 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, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 17, 18, 19, 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, 0, 0, 0, 0, 20, 0, 21,
- 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 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, 0, 0, 35, 0, 36, 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, 0, 0, 0, 37, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 0, 0,
- 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7,
- 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, 16, 19,
- 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 0, 0,
- 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 0,
- 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0,
- 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 55,
- 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, 0, 0,
- 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0,
- 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, 0, 0,
- 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, 0, 79,
- 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, 0, 87,
- 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, 80, 0,
- 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, 51, 0,
- 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0,
- 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, 0, 0,
- 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, 0,107,
- 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, 0, 0,
- 110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 0,
- 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
- 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13,
- 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0,
- 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27,
- 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0,
- 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0,
- 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0,
- 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0,
- 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51,
- 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56,
- 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0,
- 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0,
- 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0,
- 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81,
- 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0,
- 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0,
- 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0,
- 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0,
- 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0,
- 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0,102, 0,
- 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106,107, 0,
- 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, 33, 0,
- 111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, 0, 0,
- 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, 0, 0,
- 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0,121, 0,
- 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, 0, 0,
- 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128,129, 0,
- 130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, 0, 0,
- 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0,138, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6,
- 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1,
- 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26,
- 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35,
- 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0,
- 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0,
- 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 0,
- 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21,
- 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0,
- 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0,
- 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0,
- 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77,
- 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80,
- 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0,
- 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52,
- 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0,
- 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78,
- 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1,
- 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,
- 100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0,
- 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0,
- 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0,
- 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0,
- 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0,
- 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0,
- 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0,
- 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0,
- 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38,
- 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, 55, 0,
- 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, 0, 61,
- 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, 8, 91,
- 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, 0,118,
- 119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, 38, 58,
- 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0,
- 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, 0, 0,
- 0, 0,230,230,230,230,230,232,220,220,220,220,232,216,220,220,
- 220,220,220,202,202,220,220,220,220,202,202,220,220,220, 1, 1,
- 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220,220,220,
- 230,230,230,220,220, 0,230,230,230,220,220,220,220,230,232,220,
- 220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220,
- 230,230,230,230,220,230,230,230,222,220,230,230,220,220,230,222,
- 228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22,
- 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0,
- 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,
- 230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,
- 220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,
- 230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230,
- 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220,230,220,
- 220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9,
- 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84,
- 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103,
- 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122,220,220,
- 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0,
- 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0,
- 230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9,
- 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0,
- 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, 0, 0,
- 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,
- 214,220,202,230,230,230,230,230,232,228,228,220,218,230,233,220,
- 230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230,
- 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, 0, 0,
- 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220,
- 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0,
- 230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6,
- 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,
- 216,216,216,216,216, 0,220,220,220, 0,232,232,220,230,230,230,
- 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, 3, 3,
- 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, 13, 3,
- 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, 3, 3,
- 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, 3, 3,
- 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, 27, 28,
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0,
- 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0,
- 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 0,
- 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24,
- 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, 0, 8,
- 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, 35, 19,
- 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, 0, 1,
- 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, 14, 0,
- 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53,
- 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, 19, 1,
- 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, 0, 0,
- 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0,
- 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7,
- 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0,
- 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16,
- 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0,
- 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9,
- 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0,
- 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28,
- 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4,
- 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21,
- 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0,
- 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0,
- 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1,
- 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0,
- 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, 21, 21,
- 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, 9, 1,
- 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 3, 3, 3, 3, 3, 3, 3, 15, 3, 16, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 18, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 17, 17, 18, 17, 19, 20, 21, 22, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 25, 25, 26, 27, 28, 29, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 52, 53, 31, 31, 31, 31, 54, 55, 55, 56, 31,
- 31, 31, 31, 31, 31, 31, 57, 58, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 59, 60, 31, 61, 62, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 64, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31,
- 31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17,
- 72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17,
- 17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31,
- 23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 84, 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3,
- 4, 5, 6, 7, 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6,
- 7, 8, 9, 10, 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 19, 27, 28, 29, 30, 30, 31, 31, 32, 32,
- 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 40, 41, 41,
- 42, 42, 42, 43, 44, 44, 45, 46, 47, 47, 47, 47, 48, 48, 48, 48,
- 48, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
- 54, 55, 56, 56, 57, 58, 59, 51, 60, 61, 62, 63, 64, 65, 66, 7,
- 67, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 7, 4, 4, 4, 4,
- 77, 77, 77, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 86, 87, 88, 88,
- 89, 90, 48, 91, 0, 0, 92, 92, 92, 92, 92, 93, 94, 95, 96, 97,
- 98, 47, 99,100,101,102, 0,103,104,105, 0, 0, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0,106,106,106,106,
- 106,106,106,106,106,106,106,107,108,108,108,108,108, 11,109,110,
- 111, 4,112, 4,113,114,115,116,117,118,119,120,121,122,123,124,
- 125,126, 50,127, 47, 47, 47, 47, 47, 47, 47, 47,128,128,128,128,
- 128,128,128,128,128,128,128,128, 92, 92, 92, 92, 92, 92, 92, 92,
- 129,130, 19, 19, 19, 19, 19, 19,131, 19, 19, 19,132,133, 19,134,
- 135,136,137,101,138,138,138,138, 0, 77,139,140,128,128,141,142,
- 143,144,145,146,147,148,149,150,151,152,153,153,154,154,154,154,
- 154,154, 4, 4,155,156,157,158,159,160,161,162,163,164,165,166,
- 167,168,169,169,170,170,171,171,172,172,128,128, 19, 19,173,174,
- 175,176,177,178,179,179,180,181,182,183,184,185,186,186,187,188,
- 189,190,128,128,191,191,192,192,128,128,193,193,194,195,196,196,
- 197,197,128,128,198,198,199,199,200,200,201,201,202,203,204,205,
- 28, 28,128,128,206,207,208,208,209,210,211,211,128,128,212,212,
- 213,213,214, 34,215,215,215,215,215,215,215,215,215,215,215,215,
- 215,215,128,128,128,128,128,128,128,128,216,216,217,217,217,217,
- 217,217,217,217,217,217,128,128,128,128,128,128,218,218,218,218,
- 218,218,218,218,218,218,128,128,128,128,128,128,110,110,110,110,
- 110,110,110,110,110,219,220,221,222,222,222,222,223,223,223,223,
- 224,224,224,225,226,226,226,226,226,226,226,226,226,226,226,226,
- 227,227,227,227,227,227,227,227,226,226,128,128,128,128,128,128,
- 128,128,104,104,228,229,229,229,230,231,232,232,232,232,232,232,
- 128,128,128,128,233,233,234, 0,128,128,128,128,128,128,128,128,
- 7,235, 0, 0, 0, 0, 0, 0, 0,236,237, 0, 77, 77, 0, 0,
- 0, 0,128,128,238,238,238,238,238,238,238,238,238,238,238,238,
- 128,128,128,128,128,128,128,128, 4, 4,128,128,239, 11, 11, 11,
- 240,240,128,128,128,128,241,242,128,128,128,128,128,128,243,243,
- 128,128,128,128,128,128,128,128,128,128, 48, 48,244,244,244,244,
- 245,245,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19,
- 128,128,128,128,246, 0,128,128, 0, 0, 0, 0, 92, 92,128,128,
- 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0,
- 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4,
- 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9,
- 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 14, 13, 13, 13,
- 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18,
- 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21,
- 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28,
- 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32,
- 32, 33, 34, 32, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
- 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41,
- 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44,
- 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49,
- 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 53, 53, 53, 53,
- 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57,
- 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64,
- 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 67, 67, 67, 67,
- 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73,
- 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50,
- 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84,
- 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0,
- 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0,
- 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92,
- 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 13, 13, 94, 94, 94, 94,
- 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102,
- 102,102,102,103,104,104,104,105, 52, 0,104,104, 0, 0, 0,102,
- 52, 52, 0, 0, 0, 0, 52,106, 0,102,102,107,102,102,102,102,
- 102,108, 0, 0,109,109,109,109,109,110,110,110,111,111,111,111,
- 13, 13,112,112,112,112,112,112, 0, 0,113, 4,114, 4, 4, 4,
- 115,115,115, 0,116,116,116,116,117,117,117,117,117,117, 32, 32,
- 118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, 49, 49,
- 123,123,123,123,123,123, 49, 49,124,124,124,124,124,124,125,125,
- 53, 53, 53, 4, 4,126,127, 54,125,125,125,125,128,128,128,128,
- 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21,130, 8, 0,131, 0,
- 0, 0, 0, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101,
- 102,134, 52, 52,135,135,135,135, 11, 0, 11, 11, 11, 0, 0,136,
- 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142,
- 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146,
- 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151,
- 151,151,151,151,152,152,152,152,153,153,153,153,154,154,155,155,
- 156,156,156,156,156,156,157,157,158,158,159,159,159,159,159,159,
- 160,160,161,161,161,161,161,161,162,162,162,162,162,162,163,163,
- 164,164,164,164,165,165,165,165,166,166,166,166,167,167,168,168,
- 169,169,169,169,170,170,170,170,171,171,171,171,172,172,172,172,
- 173,173,173,173,173,173,173,174,175,175,175,176,176,176,176,177,
- 177,177,177,178,178,178,179,179,180,180,180,180,181,181,181,181,
- 181,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185,
- 185,185,186, 43,187,187,187,187,188,188,188,189,189,189,189,189,
- 190,190,190,191,190,190,190,190,192,192,192,192,193,193,193,193,
- 194,194,194,194,195,195,195,195,195,195, 66, 66,196,196,196,196,
- 197,197,197,197,198,198,198,198,199,199,199,199,200,200,200,200,
- 201,201,201,201,202,202,202,202,202,203,203,203,203,203,203, 55,
- 204,204,204,204,205,205,205,205,205,205,205,206,206,206,206,206,
- 207,207,207,207,207,207,208,208,208,208,208,208,209,209,209,209,
- 210,210,210,210,110,110,110,110,211,211,211,211,212,212,212,212,
- 213,213,213,213,214,214,214,214,215,215,215,216,216,216,216,216,
- 216,217,217,217,218,218,218,218,219,219,219,219,220,220,220,220,
- 220,220,221, 94,222,222,222,222,223,223,223,223,224, 99, 99, 99,
- 99, 99, 99, 99, 99, 99,102,225, 99,226,102,227,227,227,227,227,
- 228,228,228,228,228,228, 0, 0, 8, 0, 0, 0, 0, 0,229,230,
- 231, 0,232, 0,233,233,233,233, 91, 91, 91, 13,234,234,234,234,
- 235,235,235,235,236,236,236,236,237,237,237,237,238,238,238,238,
- 239,239,239,239,240, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2,
- 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2,
- 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10,
- 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14,
- 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19,
- 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20,
- 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21,
- 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30,
- 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33,
- 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
- 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
- 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47,
- 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52,
- 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56,
- 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60,
- 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0,
- 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71,
- 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74,
- 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78,
- 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7,
- 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89,
- 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86,
- 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4,
- 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,
- 100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,
- 105,106,106,106,106,106,106,106,106,106,107,105,108,109,109,109,
- 109,109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55,
- 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114,
- 115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2,
- 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120,
- 121,121,121,121,121,121,121,122,123,123,123,123,124,124,124,124,
- 124,124,124,125,126,126,126,126,127,127,127,127,128,128,128,128,
- 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18,
- 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,
- 109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139,
- 140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142,
- 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,
- 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,
- 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,
- 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,
- 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,
- 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,
- 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,
- 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,
- 174,174,174,175,176,176,176,176,177,177,177,177,178,178,178,178,
- 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182,
- 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,
- 187, 45, 45, 45,188,188,188,188,189,189,189,189,190,190,190,190,
- 191,191,191,191,191,191,192,191,193,193,193,193,194,194,194,194,
- 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198,
- 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,
- 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,
- 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,
- 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214,
- 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218,
- 219,219,219,219,220,220,220,220,221,221,221,221,222,223,223,223,
- 224,224,224,224,223,223,223,223,225,106,106,106,226,106,106,106,
- 106,227,109,109,228,228,228,228,229,229,229,229, 0,230, 86, 0,
- 0, 0,230, 7, 82,138, 7, 0, 0, 0,231, 86,232,232,232,232,
- 233,233,233,233,234,234,234,234,235,235,235,235,236,236,236,236,
- 237,237,237,237,238,238,238,238,239, 0, 0, 0, 0, 0, 0, 0,
- 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0,
- 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9,
- 0, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55,
- 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4,
- 4, 4, 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3,
- 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1,
- 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38,
- 64, 64, 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3,
- 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7,
- 5, 5, 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21,
- 22, 22, 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20,
- 36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18,
- 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33,
- 8, 8, 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30,
- 29, 29, 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35,
- 35, 35, 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44,
- 44, 0, 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31,
- 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48,
- 52, 52, 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91,
- 62, 62, 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70,
- 73, 73, 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0,
- 0, 1, 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6,
- 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19,
- 19, 19, 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19,
- 27, 27, 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13,
- 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12,
- 0, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12,
- 12, 12, 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77,
- 79, 79, 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75,
- 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84,
- 84, 84, 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87,
- 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4,
- 3, 3, 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0,
- 49, 49, 49, 49, 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67,
- 42, 42, 42, 42, 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53,
- 59, 59, 59, 59, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,
- 135,135,135,135,106,106,106,106,104,104,104,104,161,161,161,161,
- 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,
- 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72,
- 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88,
- 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83,
- 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130,
- 144,144,144,144,156,156,156,156,156, 3, 3, 3,147,147,147,147,
- 148,148,148,148,158,158,158,158,153,153,153,153,149,149,149,149,
- 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, 96, 96, 96, 96,
- 111,111,111,111,100,100,100,100,100, 36, 36, 36,108,108,108,108,
- 129,129,129,129,109,109,109,109,107,107,107,107,107,107,107, 1,
- 137,137,137,137,124,124,124,124,123,123,123,123,114,114,114,114,
- 102,102,102,102,126,126,126,126,142,142,142,142,125,125,125,125,
- 154,154,154,154,150,150,150,150,141,141,141,141,140,140,140,140,
- 121,121,121,121,133,133,133,133,134,134,134,134,138,138,138,138,
- 143,143,143,143,145,145,145,145,163,163,163,163, 63, 63, 63, 63,
- 157,157,157,157, 80, 80, 80, 80,127,127,127,127,115,115,115,115,
- 159,159,159,159,103,103,103,103,119,119,119,119,146,146,146,146,
- 99, 99, 99, 99,136,139, 13, 13,155,155,155,155,136,136,136,136,
- 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17,139,139,139,139,
- 105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,
- 151,151,151,151,160,160,160,160,152,152,152,152,164,164,164,164,
- 113,113,113,113,132,132,132,132, 15, 0, 0, 0, 0, 1, 2, 3,
- 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9,
- 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0,
- 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34,
- 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 41, 42, 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, 0, 43, 44, 0, 45,
- 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51,
- 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0,
- 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0,
- 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59,
- 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 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,
- 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, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0,
- 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0,
- 111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 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,117, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,
- 120,121, 0,122,123,124,125,126, 0,127, 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,128,129,130,131,132,133,
- 134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,
- 150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 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,165, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 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,169,
- 170, 0, 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178,
- 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,
- 195,196,197,198,199,200,201,202,203,204,205,206, 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, 1, 2, 3, 4,
-};
-static const uint16_t
-_hb_ucd_u16[4920] =
-{
- 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12,
- 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23,
- 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31,
- 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39,
- 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13,
- 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48,
- 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56,
- 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63,
- 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32,
- 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83,
- 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91,
- 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102,
- 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111,
- 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119,
- 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47,
- 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66,
- 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145,
- 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153,
- 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145,
- 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47,
- 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146,
- 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32,
- 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183,
- 47, 47, 184, 185, 186, 61, 47, 187, 11, 9, 9, 9, 66, 188, 189, 190,
- 11, 11, 191, 27, 27, 27, 192, 193, 11, 194, 27, 27, 32, 32, 32, 32,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 195, 13, 13, 13, 13, 13, 13,
- 196, 196, 196, 196, 196, 197, 196, 11, 198, 198, 198, 199, 200, 201, 201, 200,
- 202, 203, 204, 205, 206, 207, 208, 209, 210, 27, 211, 211, 211, 212, 213, 32,
- 214, 215, 216, 217, 218, 145, 219, 219, 220, 221, 222, 146, 223, 224, 146, 225,
- 226, 226, 226, 226, 226, 226, 226, 226, 227, 146, 228, 146, 146, 146, 146, 229,
- 146, 230, 226, 231, 146, 232, 233, 146, 146, 146, 146, 146, 146, 146, 145, 145,
- 145, 234, 146, 146, 146, 146, 235, 145, 146, 146, 146, 146, 146, 146, 146, 146,
- 146, 146, 146, 236, 237, 146, 146, 238, 146, 146, 146, 146, 146, 146, 239, 146,
- 146, 146, 146, 146, 146, 146, 240, 241, 145, 242, 146, 146, 243, 226, 244, 226,
- 245, 246, 226, 226, 226, 247, 226, 248, 146, 146, 146, 226, 249, 146, 146, 146,
- 9, 9, 9, 11, 11, 11, 250, 251, 13, 13, 13, 13, 13, 13, 252, 253,
- 11, 11, 11, 47, 47, 47, 254, 255, 47, 47, 47, 47, 47, 47, 32, 32,
- 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, 267, 47, 47, 47,
- 47, 268, 148, 47, 47, 47, 47, 269, 47, 270, 47, 47, 146, 146, 146, 47,
- 146, 146, 271, 146, 272, 273, 146, 146, 271, 146, 146, 273, 146, 146, 146, 146,
- 47, 47, 47, 47, 146, 146, 146, 146, 47, 274, 47, 47, 47, 47, 47, 47,
- 47, 146, 146, 146, 146, 47, 47, 187, 275, 47, 61, 47, 13, 13, 276, 277,
- 13, 278, 47, 47, 47, 47, 279, 280, 31, 281, 282, 283, 13, 13, 13, 284,
- 285, 286, 287, 288, 289, 290, 11, 291, 292, 47, 293, 294, 47, 47, 47, 295,
- 296, 47, 47, 297, 298, 160, 32, 299, 61, 47, 300, 47, 301, 302, 47, 47,
- 72, 47, 47, 303, 304, 305, 306, 61, 47, 47, 307, 308, 309, 310, 47, 311,
- 47, 47, 47, 312, 58, 313, 314, 315, 47, 47, 47, 11, 11, 316, 317, 11,
- 11, 11, 11, 11, 47, 47, 318, 160, 319, 319, 319, 319, 319, 319, 319, 319,
- 320, 320, 320, 320, 320, 320, 320, 320, 11, 321, 322, 47, 47, 47, 47, 47,
- 47, 47, 47, 323, 31, 324, 47, 47, 47, 47, 47, 325, 146, 47, 47, 47,
- 47, 47, 47, 47, 326, 146, 146, 327, 32, 328, 32, 329, 330, 331, 332, 47,
- 47, 47, 47, 47, 47, 47, 47, 333, 334, 2, 3, 4, 5, 335, 336, 337,
- 47, 338, 47, 47, 47, 47, 339, 340, 341, 145, 145, 342, 219, 219, 219, 343,
- 344, 146, 146, 146, 146, 146, 146, 345, 346, 346, 346, 346, 346, 346, 346, 346,
- 47, 47, 47, 47, 47, 47, 347, 145, 47, 47, 348, 47, 349, 47, 47, 60,
- 47, 350, 47, 47, 47, 351, 219, 219, 9, 9, 147, 11, 11, 47, 47, 47,
- 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 350, 9,
- 9, 352, 11, 11, 11, 11, 11, 11, 27, 27, 27, 27, 27, 27, 27, 27,
- 47, 47, 47, 47, 47, 353, 47, 354, 47, 47, 355, 145, 145, 145, 47, 356,
- 47, 357, 47, 350, 66, 66, 66, 66, 47, 47, 47, 358, 145, 145, 145, 145,
- 359, 47, 47, 360, 145, 66, 47, 361, 47, 362, 145, 145, 363, 47, 364, 66,
- 47, 47, 47, 365, 47, 366, 47, 366, 47, 365, 144, 145, 145, 145, 145, 145,
- 9, 9, 9, 9, 11, 11, 11, 367, 47, 47, 368, 160, 160, 160, 160, 160,
- 145, 145, 145, 145, 145, 145, 145, 145, 47, 47, 369, 47, 47, 47, 47, 143,
- 47, 362, 370, 47, 60, 371, 66, 47, 372, 66, 66, 47, 373, 145, 47, 47,
- 374, 47, 47, 360, 375, 376, 377, 378, 180, 47, 47, 379, 380, 47, 47, 160,
- 97, 47, 381, 382, 383, 47, 47, 384, 180, 47, 47, 385, 386, 387, 388, 145,
- 47, 47, 389, 390, 359, 32, 32, 32, 47, 47, 365, 47, 47, 391, 172, 160,
- 92, 47, 47, 113, 392, 393, 394, 32, 47, 47, 47, 395, 396, 397, 47, 47,
- 47, 47, 47, 398, 399, 160, 160, 160, 47, 47, 400, 401, 402, 403, 32, 32,
- 47, 47, 47, 404, 405, 160, 66, 66, 47, 47, 406, 407, 160, 160, 160, 160,
- 47, 143, 408, 409, 47, 47, 47, 47, 47, 47, 389, 410, 66, 66, 66, 66,
- 9, 9, 9, 9, 11, 11, 128, 411, 47, 47, 47, 412, 413, 160, 160, 160,
- 47, 47, 47, 47, 47, 414, 415, 416, 417, 47, 47, 418, 419, 420, 47, 47,
- 421, 422, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66,
- 47, 47, 400, 423, 424, 128, 145, 425, 47, 156, 426, 427, 32, 32, 32, 32,
- 47, 47, 47, 359, 428, 160, 47, 47, 429, 430, 160, 160, 160, 160, 160, 160,
- 47, 47, 47, 47, 47, 47, 47, 431, 432, 47, 47, 433, 434, 160, 160, 160,
- 47, 47, 47, 47, 145, 435, 436, 437, 219, 219, 219, 219, 219, 219, 219, 66,
- 47, 47, 47, 47, 47, 47, 47, 424, 47, 47, 47, 208, 438, 32, 32, 32,
- 47, 47, 47, 47, 47, 47, 305, 47, 47, 47, 47, 47, 160, 47, 47, 439,
- 47, 47, 47, 440, 441, 442, 443, 47, 9, 9, 9, 9, 9, 9, 11, 11,
- 145, 444, 66, 66, 66, 66, 66, 66, 47, 47, 47, 47, 391, 445, 416, 416,
- 446, 447, 27, 27, 27, 27, 448, 416, 47, 449, 208, 208, 208, 208, 208, 208,
- 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 450, 451,
- 452, 146, 453, 146, 146, 146, 146, 146, 146, 146, 146, 146, 454, 146, 146, 146,
- 9, 455, 11, 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11,
- 456, 457, 11, 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 456, 457, 11,
- 196, 9, 458, 459, 9, 460, 11, 9, 455, 11, 196, 9, 461, 462, 463, 464,
- 11, 465, 9, 466, 467, 468, 469, 11, 470, 9, 471, 11, 472, 160, 160, 160,
- 32, 32, 32, 473, 32, 32, 474, 475, 476, 477, 32, 32, 32, 32, 32, 32,
- 478, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27,
- 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 479, 480, 146, 146, 146,
- 47, 47, 481, 32, 47, 47, 482, 483, 47, 47, 47, 47, 47, 47, 484, 160,
- 47, 47, 47, 47, 355, 32, 32, 32, 9, 9, 458, 11, 485, 305, 66, 66,
- 145, 145, 486, 487, 145, 145, 145, 145, 145, 145, 488, 145, 145, 145, 145, 145,
- 47, 47, 47, 47, 47, 47, 47, 226, 489, 146, 146, 146, 146, 146, 146, 146,
- 146, 146, 146, 146, 146, 146, 146, 490, 146, 146, 146, 146, 146, 146, 146, 160,
- 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962,
- 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0,
- 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,
- 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0,
- 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
- 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160,
- 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,
- 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206,
- 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,
- 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,
- 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,
- 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
- 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,1093,1280, 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, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
- 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,
- 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,
- 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
- 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
- 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130,
- 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,
- 1434,1438,1443, 0,1450, 0,1455,1461,1514, 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,1446,1458,1468,1476,1480,1486,1517, 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,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522,
- 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567,
- 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549,
- 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559,
- 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,
- 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,
- 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662,
- 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,
- 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671,
- 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,
- 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,
- 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
- 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
- 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
- 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
- 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
- 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
- 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
- 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
- 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
- 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,
- 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
- 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
- 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
- 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
- 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
- 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,
- 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,
- 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,
- 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
- 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,
- 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790,
- 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
- 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,
- 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,
- 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
- 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
- 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,
- 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,
- 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,
- 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,
- 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,
- 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0,
- 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0,
- 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847,
- 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,
- 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,
- 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0,
- 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,
- 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890,
- 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897,
- 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,
- 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917,
- 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924,
- 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,
- 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825,
- 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
- 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
- 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
- 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
- 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
- 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
- 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
- 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
- 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
- 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
- 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
- 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
- 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
- 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
- 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
- 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
- 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525,
- 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0,
- 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
- 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
- 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
- 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
- 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171,
- 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
- 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
- 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
- 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
- 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
- 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916,
- 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,
- 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,
- 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121,
- 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142,
- 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169,
- 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
- 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
- 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
- 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39,
- 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266,
- 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286,
- 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852,
- 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324,
- 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
- 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50,
- 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78,
- 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55,
- 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861,
- 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
- 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467,
- 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
- 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875,
- 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531,
- 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559,
- 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73,
- 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898,
- 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902,
- 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
- 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81,
- 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669,
- 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686,
- 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
- 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
- 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925,
- 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800,
- 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816,
- 817, 818, 819, 820, 821, 935, 0, 0,
-};
-static const int16_t
-_hb_ucd_i16[92] =
-{
- 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16,
- 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914,
- 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0,
- 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8,
- -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0,
- 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0,
-};
-
-static inline uint_fast8_t
-_hb_ucd_gc (unsigned u)
-{
- return u<1114112u?_hb_ucd_u8[5080+(((_hb_ucd_u8[1152+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
-}
-static inline uint_fast8_t
-_hb_ucd_ccc (unsigned u)
-{
- return u<125259u?_hb_ucd_u8[7038+(((_hb_ucd_u8[6482+(((_hb_ucd_u8[6022+(((_hb_ucd_u8[5670+(((_hb_ucd_u8[5424+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
-}
-static inline unsigned
-_hb_ucd_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline int_fast16_t
-_hb_ucd_bmg (unsigned u)
-{
- return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7930+(((_hb_ucd_u8[7698+(((_hb_ucd_u8[7602+(((_hb_ucd_b4(7538+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
-}
-static inline uint_fast8_t
-_hb_ucd_sc (unsigned u)
-{
- return u<918016u?_hb_ucd_u8[11228+(((_hb_ucd_u8[10264+(((_hb_ucd_u8[9276+(((_hb_ucd_u8[8596+(((_hb_ucd_u8[8292+(((_hb_ucd_u8[8178+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
-}
-static inline uint_fast16_t
-_hb_ucd_dm (unsigned u)
-{
- return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12570+(((_hb_ucd_u8[12188+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
-}
-
-#endif
-
-
-#endif /* HB_UCD_TABLE_HH */
-
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc b/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc
deleted file mode 100644
index 4c8b1ee5e61..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-ucd.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2012 Grigori Goronzy <[email protected]>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "hb.hh"
-#include "hb-unicode.hh"
-#include "hb-machinery.hh"
-
-#include "hb-ucd-table.hh"
-
-static hb_unicode_combining_class_t
-hb_ucd_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return (hb_unicode_combining_class_t) _hb_ucd_ccc (unicode);
-}
-
-static hb_unicode_general_category_t
-hb_ucd_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return (hb_unicode_general_category_t) _hb_ucd_gc (unicode);
-}
-
-static hb_codepoint_t
-hb_ucd_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return unicode + _hb_ucd_bmg (unicode);
-}
-
-static hb_script_t
-hb_ucd_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
- void *user_data HB_UNUSED)
-{
- return _hb_ucd_sc_map[_hb_ucd_sc (unicode)];
-}
-
-
-#define SBASE 0xAC00u
-#define LBASE 0x1100u
-#define VBASE 0x1161u
-#define TBASE 0x11A7u
-#define SCOUNT 11172u
-#define LCOUNT 19u
-#define VCOUNT 21u
-#define TCOUNT 28u
-#define NCOUNT (VCOUNT * TCOUNT)
-
-static inline bool
-_hb_ucd_decompose_hangul (hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b)
-{
- unsigned si = ab - SBASE;
-
- if (si >= SCOUNT)
- return false;
-
- if (si % TCOUNT)
- {
- /* LV,T */
- *a = SBASE + (si / TCOUNT) * TCOUNT;
- *b = TBASE + (si % TCOUNT);
- return true;
- } else {
- /* L,V */
- *a = LBASE + (si / NCOUNT);
- *b = VBASE + (si % NCOUNT) / TCOUNT;
- return true;
- }
-}
-
-static inline bool
-_hb_ucd_compose_hangul (hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab)
-{
- if (a >= SBASE && a < (SBASE + SCOUNT) && b > TBASE && b < (TBASE + TCOUNT) &&
- !((a - SBASE) % TCOUNT))
- {
- /* LV,T */
- *ab = a + (b - TBASE);
- return true;
- }
- else if (a >= LBASE && a < (LBASE + LCOUNT) && b >= VBASE && b < (VBASE + VCOUNT))
- {
- /* L,V */
- int li = a - LBASE;
- int vi = b - VBASE;
- *ab = SBASE + li * NCOUNT + vi * TCOUNT;
- return true;
- }
- else
- return false;
-}
-
-static int
-_cmp_pair (const void *_key, const void *_item)
-{
- uint64_t& a = * (uint64_t*) _key;
- uint64_t b = (* (uint64_t*) _item) & HB_CODEPOINT_ENCODE3(0x1FFFFFu, 0x1FFFFFu, 0);
-
- return a < b ? -1 : a > b ? +1 : 0;
-}
-static int
-_cmp_pair_11_7_14 (const void *_key, const void *_item)
-{
- uint32_t& a = * (uint32_t*) _key;
- uint32_t b = (* (uint32_t*) _item) & HB_CODEPOINT_ENCODE3_11_7_14(0x1FFFFFu, 0x1FFFFFu, 0);
-
- return a < b ? -1 : a > b ? +1 : 0;
-}
-
-static hb_bool_t
-hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
- void *user_data HB_UNUSED)
-{
- // Hangul is handled algorithmically.
- if (_hb_ucd_compose_hangul (a, b, ab)) return true;
-
- hb_codepoint_t u = 0;
-
- if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
- {
- /* If "a" is small enough and "b" is in the U+0300 range,
- * the composition data is encoded in a 32bit array sorted
- * by "a,b" pair. */
- uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
- const uint32_t *v = hb_bsearch (k,
- _hb_ucd_dm2_u32_map,
- ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
- sizeof (*_hb_ucd_dm2_u32_map),
- _cmp_pair_11_7_14);
- if (likely (!v)) return false;
- u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v);
- }
- else
- {
- /* Otherwise it is stored in a 64bit array sorted by
- * "a,b" pair. */
- uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
- const uint64_t *v = hb_bsearch (k,
- _hb_ucd_dm2_u64_map,
- ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
- sizeof (*_hb_ucd_dm2_u64_map),
- _cmp_pair);
- if (likely (!v)) return false;
- u = HB_CODEPOINT_DECODE3_3 (*v);
- }
-
- if (unlikely (!u)) return false;
- *ab = u;
- return true;
-}
-
-static hb_bool_t
-hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
- void *user_data HB_UNUSED)
-{
- if (_hb_ucd_decompose_hangul (ab, a, b)) return true;
-
- unsigned i = _hb_ucd_dm (ab);
-
- /* If no data, there's no decomposition. */
- if (likely (!i)) return false;
- i--;
-
- /* Check if it's a single-character decomposition. */
- if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map))
- {
- /* Single-character decompositions currently are only in plane 0 or plane 2. */
- if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map))
- {
- /* Plane 0. */
- *a = _hb_ucd_dm1_p0_map[i];
- }
- else
- {
- /* Plane 2. */
- i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map);
- *a = 0x20000 | _hb_ucd_dm1_p2_map[i];
- }
- *b = 0;
- return true;
- }
- i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map);
-
- /* Otherwise they are encoded either in a 32bit array or a 64bit array. */
- if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map))
- {
- /* 32bit array. */
- uint32_t v = _hb_ucd_dm2_u32_map[i];
- *a = HB_CODEPOINT_DECODE3_11_7_14_1 (v);
- *b = HB_CODEPOINT_DECODE3_11_7_14_2 (v);
- return true;
- }
- i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map);
-
- /* 64bit array. */
- uint64_t v = _hb_ucd_dm2_u64_map[i];
- *a = HB_CODEPOINT_DECODE3_1 (v);
- *b = HB_CODEPOINT_DECODE3_2 (v);
- return true;
-}
-
-
-static void free_static_ucd_funcs ();
-
-static struct hb_ucd_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucd_unicode_funcs_lazy_loader_t>
-{
- static hb_unicode_funcs_t *create ()
- {
- hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
-
- hb_unicode_funcs_set_combining_class_func (funcs, hb_ucd_combining_class, nullptr, nullptr);
- hb_unicode_funcs_set_general_category_func (funcs, hb_ucd_general_category, nullptr, nullptr);
- hb_unicode_funcs_set_mirroring_func (funcs, hb_ucd_mirroring, nullptr, nullptr);
- hb_unicode_funcs_set_script_func (funcs, hb_ucd_script, nullptr, nullptr);
- hb_unicode_funcs_set_compose_func (funcs, hb_ucd_compose, nullptr, nullptr);
- hb_unicode_funcs_set_decompose_func (funcs, hb_ucd_decompose, nullptr, nullptr);
-
- hb_unicode_funcs_make_immutable (funcs);
-
- hb_atexit (free_static_ucd_funcs);
-
- return funcs;
- }
-} static_ucd_funcs;
-
-static inline
-void free_static_ucd_funcs ()
-{
- static_ucd_funcs.free_instance ();
-}
-
-hb_unicode_funcs_t *
-hb_ucd_get_unicode_funcs ()
-{
-#ifdef HB_NO_UCD
- return hb_unicode_funcs_get_empty ();
-#endif
- return static_ucd_funcs.get_unconst ();
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh
deleted file mode 100644
index 13b1c4b1d40..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-emoji-table.hh
+++ /dev/null
@@ -1,79 +0,0 @@
-/* == Start of generated table == */
-/*
- * The following tables are generated by running:
- *
- * ./gen-emoji-table.py emoji-data.txt
- *
- * on file with this header:
- *
- * # emoji-data.txt
- * # Date: 2022-08-02, 00:26:10 GMT
- * # © 2022 Unicode®, Inc.
- * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
- * # For terms of use, see https://www.unicode.org/terms_of_use.html
- * #
- * # Emoji Data for UTS #51
- * # Used with Emoji Version 15.0 and subsequent minor revisions (if any)
- * #
- * # For documentation and usage, see https://www.unicode.org/reports/tr51
- */
-
-#ifndef HB_UNICODE_EMOJI_TABLE_HH
-#define HB_UNICODE_EMOJI_TABLE_HH
-
-#include "hb-unicode.hh"
-
-static const uint8_t
-_hb_emoji_u8[464] =
-{
- 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12,
- 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0,
- 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25,
- 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0,
- 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0,
- 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21,
- 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0,
- 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33,
- 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0,
- 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16,
- 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0,
- 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3,
- 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0,
- 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0,
- 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255,
- 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0,
- 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24,
- 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0,
- 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0,
- 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7,
- 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255,
- 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0,
- 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255,
-};
-
-static inline unsigned
-_hb_emoji_b4 (const uint8_t* a, unsigned i)
-{
- return (a[i>>1]>>((i&1u)<<2))&15u;
-}
-static inline unsigned
-_hb_emoji_b1 (const uint8_t* a, unsigned i)
-{
- return (a[i>>3]>>((i&7u)<<0))&1u;
-}
-static inline uint_fast8_t
-_hb_emoji_is_Extended_Pictographic (unsigned u)
-{
- return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0;
-}
-
-
-#endif /* HB_UNICODE_EMOJI_TABLE_HH */
-
-/* == End of generated table == */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
index 39aaee5baa7..82bb9a4ddc7 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -28,10 +28,11 @@
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_UNICODE_HH
-#define HB_UNICODE_HH
+#ifndef HB_UNICODE_PRIVATE_HH
+#define HB_UNICODE_PRIVATE_HH
-#include "hb.hh"
+#include "hb-private.hh"
+#include "hb-object-private.hh"
extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
@@ -42,58 +43,56 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
- HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (eastasian_width)) \
+ HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
HB_UNICODE_FUNC_IMPLEMENT (general_category) \
HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
HB_UNICODE_FUNC_IMPLEMENT (script) \
HB_UNICODE_FUNC_IMPLEMENT (compose) \
HB_UNICODE_FUNC_IMPLEMENT (decompose) \
- HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility)) \
+ HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
/* ^--- Add new callbacks here */
/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
- HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width)) \
+ HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
/* ^--- Add new simple callbacks here */
-struct hb_unicode_funcs_t
-{
+struct hb_unicode_funcs_t {
hb_object_header_t header;
+ ASSERT_POD ();
hb_unicode_funcs_t *parent;
+ bool immutable;
+
#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
- return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); }
+ inline return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); }
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
#undef HB_UNICODE_FUNC_IMPLEMENT
- hb_bool_t compose (hb_codepoint_t a, hb_codepoint_t b,
- hb_codepoint_t *ab)
+ inline hb_bool_t compose (hb_codepoint_t a, hb_codepoint_t b,
+ hb_codepoint_t *ab)
{
*ab = 0;
if (unlikely (!a || !b)) return false;
return func.compose (this, a, b, ab, user_data.compose);
}
- hb_bool_t decompose (hb_codepoint_t ab,
- hb_codepoint_t *a, hb_codepoint_t *b)
+ inline hb_bool_t decompose (hb_codepoint_t ab,
+ hb_codepoint_t *a, hb_codepoint_t *b)
{
*a = ab; *b = 0;
return func.decompose (this, ab, a, b, user_data.decompose);
}
- unsigned int decompose_compatibility (hb_codepoint_t u,
- hb_codepoint_t *decomposed)
+ inline unsigned int decompose_compatibility (hb_codepoint_t u,
+ hb_codepoint_t *decomposed)
{
-#ifdef HB_DISABLE_DEPRECATED
- unsigned int ret = 0;
-#else
unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
-#endif
if (ret == 1 && u == decomposed[0]) {
decomposed[0] = 0;
return 0;
@@ -102,27 +101,34 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
return ret;
}
- unsigned int
- modified_combining_class (hb_codepoint_t u)
+
+ inline unsigned int
+ modified_combining_class (hb_codepoint_t unicode)
{
- /* Reorder SAKOT to ensure it comes after any tone marks. */
- if (unlikely (u == 0x1A60u)) return 254;
- /* Reorder PADMA to ensure it comes after any vowel marks. */
- if (unlikely (u == 0x0FC6u)) return 254;
+ /* XXX This hack belongs to the Myanmar shaper. */
+ if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
+
+ /* 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;
+
+ /* XXX This hack belongs to the Tibetan shaper:
+ * Reorder PADMA to ensure it comes after any vowel marks. */
+ if (unlikely (unicode == 0x0FC6u)) return 254;
/* Reorder TSA -PHRU to reorder before U+0F74 */
- if (unlikely (u == 0x0F39u)) return 127;
+ if (unlikely (unicode == 0x0F39u)) return 127;
- return _hb_modified_combining_class[combining_class (u)];
+ return _hb_modified_combining_class[combining_class (unicode)];
}
- static hb_bool_t
+ static inline hb_bool_t
is_variation_selector (hb_codepoint_t unicode)
{
- /* U+180B..180D, U+180F MONGOLIAN FREE VARIATION SELECTORs are handled in the
+ /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
* Arabic shaper. No need to match them here. */
return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
- 0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
- 0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */
+ 0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
+ 0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */
}
/* Default_Ignorable codepoints:
@@ -133,7 +139,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* As such, we make exceptions for those four.
* Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503
*
- * Unicode 14.0:
+ * Unicode 7.0:
* $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
* 00AD # Cf SOFT HYPHEN
* 034F # Mn COMBINING GRAPHEME JOINER
@@ -142,7 +148,6 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
* 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
* 180E # Cf MONGOLIAN VOWEL SEPARATOR
- * 180F # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR
* 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
* 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
* 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS
@@ -163,7 +168,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* E0100..E01EF # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
* E01F0..E0FFF # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
*/
- static hb_bool_t
+ static inline hb_bool_t
is_default_ignorable (hb_codepoint_t ch)
{
hb_codepoint_t plane = ch >> 16;
@@ -197,8 +202,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
}
/* Space estimates based on:
- * https://unicode.org/charts/PDF/U2000.pdf
- * https://docs.microsoft.com/en-us/typography/develop/character-design-standards/whitespace
+ * http://www.unicode.org/charts/PDF/U2000.pdf
+ * https://www.microsoft.com/typography/developers/fdsspec/spaces.aspx
*/
enum space_t {
NOT_SPACE = 0,
@@ -215,7 +220,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
SPACE_PUNCTUATION,
SPACE_NARROW,
};
- static space_t
+ static inline space_t
space_fallback_type (hb_codepoint_t u)
{
switch (u)
@@ -259,22 +264,22 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
#undef HB_UNICODE_FUNC_IMPLEMENT
} destroy;
};
-DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
-/*
- * Modified combining marks
- */
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
+
+
+/* Modified combining marks */
/* Hebrew
*
* We permute the "fixed-position" classes 10-26 into the order
* described in the SBL Hebrew manual:
*
- * https://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
+ * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
*
* (as recommended by:
- * https://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering/msg22823/)
+ * http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
*
* More details here:
* https://bugzilla.mozilla.org/show_bug.cgi?id=662055
@@ -287,8 +292,8 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
#define HB_MODIFIED_COMBINING_CLASS_CCC15 18 /* tsere */
#define HB_MODIFIED_COMBINING_CLASS_CCC16 19 /* segol */
#define HB_MODIFIED_COMBINING_CLASS_CCC17 20 /* patah */
-#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats & qamats qatan */
-#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam & holam haser for vav*/
+#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats */
+#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam */
#define HB_MODIFIED_COMBINING_CLASS_CCC20 24 /* qubuts */
#define HB_MODIFIED_COMBINING_CLASS_CCC21 12 /* dagesh */
#define HB_MODIFIED_COMBINING_CLASS_CCC22 25 /* meteg */
@@ -301,8 +306,8 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
* Arabic
*
* Modify to move Shadda (ccc=33) before other marks. See:
- * https://unicode.org/faq/normalization.html#8
- * https://unicode.org/faq/normalization.html#9
+ * http://unicode.org/faq/normalization.html#8
+ * http://unicode.org/faq/normalization.html#9
*/
#define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */
#define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */
@@ -321,11 +326,11 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
*
* Modify Telugu length marks (ccc=84, ccc=91).
* These are the only matras in the main Indic scripts range that have
- * a non-zero ccc. That makes them reorder with the Halant (ccc=9).
- * Assign 4 and 5, which are otherwise unassigned.
+ * a non-zero ccc. That makes them reorder with the Halant that is
+ * ccc=9. Just zero them, we don't need them in our Indic shaper.
*/
-#define HB_MODIFIED_COMBINING_CLASS_CCC84 4 /* length mark */
-#define HB_MODIFIED_COMBINING_CLASS_CCC91 5 /* ai length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
/* Thai
*
@@ -341,9 +346,9 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
#define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
/* Tibetan
- *
- * In case of multiple vowel-signs, use u first (but after achung)
- * this allows Dzongkha multi-vowel shortcuts to render correctly
+ *
+ * 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 132 /* sign i */
@@ -357,47 +362,10 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
-#define HB_UNICODE_GENERAL_CATEGORY_IS_LETTER(gen_cat) \
+#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \
(FLAG_UNSAFE (gen_cat) & \
- (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | \
- FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \
- FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \
- FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) | \
- FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER)))
-
-/*
- * Ranges, used for bsearch tables.
- */
-
-struct hb_unicode_range_t
-{
- static int
- cmp (const void *_key, const void *_item)
- {
- hb_codepoint_t cp = *((hb_codepoint_t *) _key);
- const hb_unicode_range_t *range = (hb_unicode_range_t *) _item;
-
- if (cp < range->start)
- return -1;
- else if (cp <= range->end)
- return 0;
- else
- return +1;
- }
-
- hb_codepoint_t start;
- hb_codepoint_t end;
-};
-
-/*
- * Emoji.
- */
-
-HB_INTERNAL bool
-_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp);
-
-
-extern "C" HB_INTERNAL hb_unicode_funcs_t *hb_ucd_get_unicode_funcs ();
-
+ (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL)))
-#endif /* HB_UNICODE_HH */
+#endif /* HB_UNICODE_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
index aa2735bedb0..726baeb0f19 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
@@ -28,30 +28,11 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb.hh"
+#include "hb-private.hh"
-#include "hb-unicode.hh"
+#include "hb-unicode-private.hh"
-/**
- * SECTION: hb-unicode
- * @title: hb-unicode
- * @short_description: Unicode character property access
- * @include: hb.h
- *
- * Unicode functions are used to access Unicode character properties.
- * With these functions, client programs can query various properties from
- * the Unicode Character Database for any code point, such as General
- * Category (gc), Script (sc), Canonical Combining Class (ccc), etc.
- *
- * Client programs can optionally pass in their own Unicode functions
- * that implement the same queries. The set of functions available is
- * defined by the virtual methods in #hb_unicode_funcs_t.
- *
- * HarfBuzz provides built-in default functions for each method in
- * #hb_unicode_funcs_t.
- **/
-
/*
* hb_unicode_funcs_t
@@ -65,7 +46,6 @@ hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
}
-#ifndef HB_DISABLE_DEPRECATED
static unsigned int
hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode HB_UNUSED,
@@ -73,7 +53,6 @@ hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
{
return 1;
}
-#endif
static hb_unicode_general_category_t
hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
@@ -85,7 +64,7 @@ hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
static hb_codepoint_t
hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode,
+ hb_codepoint_t unicode HB_UNUSED,
void *user_data HB_UNUSED)
{
return unicode;
@@ -120,7 +99,6 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
}
-#ifndef HB_DISABLE_DEPRECATED
static unsigned int
hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u HB_UNUSED,
@@ -129,52 +107,56 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
{
return 0;
}
-#endif
-#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
-#include "hb-glib.h"
-#endif
-#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
-#include "hb-icu.h"
-#endif
-/**
- * hb_unicode_funcs_get_default:
- *
- * Fetches a pointer to the default Unicode-functions structure that is used
- * when no functions are explicitly set on #hb_buffer_t.
- *
- * Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
- *
- * Since: 0.9.2
- **/
+#define HB_UNICODE_FUNCS_IMPLEMENT_SET \
+ HB_UNICODE_FUNCS_IMPLEMENT (glib) \
+ HB_UNICODE_FUNCS_IMPLEMENT (icu) \
+ HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
+ HB_UNICODE_FUNCS_IMPLEMENT (nil) \
+ /* ^--- Add new callbacks before nil */
+
+#define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
+
+/* Prototype them all */
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
+HB_UNICODE_FUNCS_IMPLEMENT_SET
+#undef HB_UNICODE_FUNCS_IMPLEMENT
+
+
hb_unicode_funcs_t *
-hb_unicode_funcs_get_default ()
+hb_unicode_funcs_get_default (void)
{
-#if !defined(HB_NO_UNICODE_FUNCS) && !defined(HB_NO_UCD)
- return hb_ucd_get_unicode_funcs ();
-#elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
- return hb_glib_get_unicode_funcs ();
-#elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
- return hb_icu_get_unicode_funcs ();
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+ return hb_##set##_get_unicode_funcs ();
+
+#if defined(HAVE_UCDN)
+ HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
+#elif defined(HAVE_GLIB)
+ HB_UNICODE_FUNCS_IMPLEMENT(glib)
+#elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
+ HB_UNICODE_FUNCS_IMPLEMENT(icu)
#else
#define HB_UNICODE_FUNCS_NIL 1
- return hb_unicode_funcs_get_empty ();
+ HB_UNICODE_FUNCS_IMPLEMENT(nil)
#endif
+
+#undef HB_UNICODE_FUNCS_IMPLEMENT
}
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
#error "Could not find any Unicode functions implementation, you have to provide your own"
-#error "Consider building hb-ucd.cc. If you absolutely want to build without any, define HB_NO_UNICODE_FUNCS."
+#error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code."
#endif
/**
- * hb_unicode_funcs_create:
- * @parent: (nullable): Parent Unicode-functions structure
+ * hb_unicode_funcs_create: (Xconstructor)
+ * @parent: (nullable):
*
- * Creates a new #hb_unicode_funcs_t structure of Unicode functions.
+ *
*
- * Return value: (transfer full): The Unicode-functions structure
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -203,11 +185,11 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
}
-DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) =
-{
+const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
HB_OBJECT_HEADER_STATIC,
nullptr, /* parent */
+ true, /* immutable */
{
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
@@ -218,25 +200,25 @@ DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) =
/**
* hb_unicode_funcs_get_empty:
*
- * Fetches the singleton empty Unicode-functions structure.
+ *
*
- * Return value: (transfer full): The empty Unicode-functions structure
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_unicode_funcs_t *
-hb_unicode_funcs_get_empty ()
+hb_unicode_funcs_get_empty (void)
{
- return const_cast<hb_unicode_funcs_t *> (&Null (hb_unicode_funcs_t));
+ return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
}
/**
* hb_unicode_funcs_reference: (skip)
- * @ufuncs: The Unicode-functions structure
+ * @ufuncs: Unicode functions.
*
- * Increases the reference count on a Unicode-functions structure.
+ *
*
- * Return value: (transfer full): The Unicode-functions structure
+ * Return value: (transfer full):
*
* Since: 0.9.2
**/
@@ -248,11 +230,9 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
/**
* hb_unicode_funcs_destroy: (skip)
- * @ufuncs: The Unicode-functions structure
+ * @ufuncs: Unicode functions.
*
- * Decreases the reference count on a Unicode-functions structure. When
- * the reference count reaches zero, the Unicode-functions structure is
- * destroyed, freeing all memory.
+ *
*
* Since: 0.9.2
**/
@@ -268,28 +248,28 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
hb_unicode_funcs_destroy (ufuncs->parent);
- hb_free (ufuncs);
+ free (ufuncs);
}
/**
* hb_unicode_funcs_set_user_data: (skip)
- * @ufuncs: The Unicode-functions structure
- * @key: The user-data key
- * @data: A pointer to the user data
- * @destroy: (nullable): A callback to call when @data is not needed anymore
- * @replace: Whether to replace an existing data with the same key
+ * @ufuncs: Unicode functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
*
- * Attaches a user-data key/data pair to the specified Unicode-functions structure.
+ *
*
- * Return value: `true` if success, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
hb_bool_t replace)
{
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
@@ -297,19 +277,18 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_get_user_data: (skip)
- * @ufuncs: The Unicode-functions structure
- * @key: The user-data key to query
+ * @ufuncs: Unicode functions.
+ * @key:
*
- * Fetches the user-data associated with the specified key,
- * attached to the specified Unicode-functions structure.
+ *
*
- * Return value: (transfer none): A pointer to the user data
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
void *
-hb_unicode_funcs_get_user_data (const hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key)
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key)
{
return hb_object_get_user_data (ufuncs, key);
}
@@ -317,47 +296,44 @@ hb_unicode_funcs_get_user_data (const hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_make_immutable:
- * @ufuncs: The Unicode-functions structure
+ * @ufuncs: Unicode functions.
*
- * Makes the specified Unicode-functions structure
- * immutable.
+ *
*
* Since: 0.9.2
**/
void
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
{
- if (hb_object_is_immutable (ufuncs))
+ if (unlikely (hb_object_is_inert (ufuncs)))
return;
- hb_object_make_immutable (ufuncs);
+ ufuncs->immutable = true;
}
/**
* hb_unicode_funcs_is_immutable:
- * @ufuncs: The Unicode-functions structure
+ * @ufuncs: Unicode functions.
*
- * Tests whether the specified Unicode-functions structure
- * is immutable.
+ *
*
- * Return value: `true` if @ufuncs is immutable, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
hb_bool_t
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
{
- return hb_object_is_immutable (ufuncs);
+ return ufuncs->immutable;
}
/**
* hb_unicode_funcs_get_parent:
- * @ufuncs: The Unicode-functions structure
+ * @ufuncs: Unicode functions.
*
- * Fetches the parent of the Unicode-functions structure
- * @ufuncs.
+ *
*
- * Return value: The parent Unicode-functions structure
+ * Return value:
*
* Since: 0.9.2
**/
@@ -376,31 +352,21 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
void *user_data, \
hb_destroy_func_t destroy) \
{ \
- if (hb_object_is_immutable (ufuncs)) \
- goto fail; \
- \
- if (!func) \
- { \
- if (destroy) \
- destroy (user_data); \
- destroy = nullptr; \
- user_data = ufuncs->parent->user_data.name; \
- } \
+ if (ufuncs->immutable) \
+ return; \
\
if (ufuncs->destroy.name) \
ufuncs->destroy.name (ufuncs->user_data.name); \
\
- if (func) \
+ if (func) { \
ufuncs->func.name = func; \
- else \
+ ufuncs->user_data.name = user_data; \
+ ufuncs->destroy.name = destroy; \
+ } else { \
ufuncs->func.name = ufuncs->parent->func.name; \
- ufuncs->user_data.name = user_data; \
- ufuncs->destroy.name = destroy; \
- return; \
- \
-fail: \
- if (destroy) \
- destroy (user_data); \
+ ufuncs->user_data.name = ufuncs->parent->user_data.name; \
+ ufuncs->destroy.name = nullptr; \
+ } \
}
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
@@ -420,18 +386,14 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
/**
* hb_unicode_compose:
- * @ufuncs: The Unicode-functions structure
- * @a: The first Unicode code point to compose
- * @b: The second Unicode code point to compose
- * @ab: (out): The composition of @a, @b
+ * @ufuncs: Unicode functions.
+ * @a:
+ * @b:
+ * @ab: (out):
*
- * Fetches the composition of a sequence of two Unicode
- * code points.
+ *
*
- * Calls the composition function of the specified
- * Unicode-functions structure @ufuncs.
- *
- * Return value: `true` if @a and @b composed, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -446,17 +408,14 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_decompose:
- * @ufuncs: The Unicode-functions structure
- * @ab: Unicode code point to decompose
- * @a: (out): The first code point of the decomposition of @ab
- * @b: (out): The second code point of the decomposition of @ab
- *
- * Fetches the decomposition of a Unicode code point.
+ * @ufuncs: Unicode functions.
+ * @ab:
+ * @a: (out):
+ * @b: (out):
*
- * Calls the decomposition function of the specified
- * Unicode-functions structure @ufuncs.
+ *
*
- * Return value: `true` if @ab was decomposed, `false` otherwise
+ * Return value:
*
* Since: 0.9.2
**/
@@ -469,20 +428,17 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
return ufuncs->decompose (ab, a, b);
}
-#ifndef HB_DISABLE_DEPRECATED
/**
* hb_unicode_decompose_compatibility:
- * @ufuncs: The Unicode-functions structure
- * @u: Code point to decompose
- * @decomposed: (out): Compatibility decomposition of @u
+ * @ufuncs: Unicode functions.
+ * @u:
+ * @decomposed: (out):
*
- * Fetches the compatibility decomposition of a Unicode
- * code point. Deprecated.
+ *
*
- * Return value: length of @decomposed.
+ * Return value:
*
* Since: 0.9.2
- * Deprecated: 2.0.0
**/
unsigned int
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
@@ -491,11 +447,9 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
{
return ufuncs->decompose_compatibility (u, decomposed);
}
-#endif
-#ifndef HB_NO_OT_SHAPE
-/* See hb-unicode.hh for details. */
+/* See hb-unicode-private.hh for details. */
const uint8_t
_hb_modified_combining_class[256] =
{
@@ -607,19 +561,3 @@ _hb_modified_combining_class[256] =
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
};
-#endif
-
-
-/*
- * Emoji
- */
-#ifndef HB_NO_EMOJI_SEQUENCES
-
-#include "hb-unicode-emoji-table.hh"
-
-bool
-_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
-{
- return _hb_emoji_is_Extended_Pictographic (cp);
-}
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
index 5b5c45cae32..2657f481300 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
@@ -28,7 +28,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -40,52 +40,7 @@
HB_BEGIN_DECLS
-/**
- * HB_UNICODE_MAX:
- *
- * Maximum valid Unicode code point.
- *
- * Since: 1.9.0
- **/
-#define HB_UNICODE_MAX 0x10FFFFu
-
-
-/**
- * hb_unicode_general_category_t:
- * @HB_UNICODE_GENERAL_CATEGORY_CONTROL: [Cc]
- * @HB_UNICODE_GENERAL_CATEGORY_FORMAT: [Cf]
- * @HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: [Cn]
- * @HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE: [Co]
- * @HB_UNICODE_GENERAL_CATEGORY_SURROGATE: [Cs]
- * @HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER: [Ll]
- * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER: [Lm]
- * @HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: [Lo]
- * @HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER: [Lt]
- * @HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER: [Lu]
- * @HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: [Mc]
- * @HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: [Me]
- * @HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: [Mn]
- * @HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER: [Nd]
- * @HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER: [Nl]
- * @HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER: [No]
- * @HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: [Pc]
- * @HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: [Pd]
- * @HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: [Pe]
- * @HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: [Pf]
- * @HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: [Pi]
- * @HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: [Po]
- * @HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: [Ps]
- * @HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: [Sc]
- * @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: [Sk]
- * @HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: [Sm]
- * @HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: [So]
- * @HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: [Zl]
- * @HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: [Zp]
- * @HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR: [Zs]
- *
- * Data type for the "General_Category" (gc) property from
- * the Unicode Character Database.
- **/
+/* hb_unicode_general_category_t */
/* Unicode Character Database property: General_Category (gc) */
typedef enum
@@ -122,74 +77,13 @@ typedef enum
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */
} hb_unicode_general_category_t;
-/**
- * hb_unicode_combining_class_t:
- * @HB_UNICODE_COMBINING_CLASS_NOT_REORDERED: Spacing and enclosing marks; also many vowel and consonant signs, even if nonspacing
- * @HB_UNICODE_COMBINING_CLASS_OVERLAY: Marks which overlay a base letter or symbol
- * @HB_UNICODE_COMBINING_CLASS_NUKTA: Diacritic nukta marks in Brahmi-derived scripts
- * @HB_UNICODE_COMBINING_CLASS_KANA_VOICING: Hiragana/Katakana voicing marks
- * @HB_UNICODE_COMBINING_CLASS_VIRAMA: Viramas
- * @HB_UNICODE_COMBINING_CLASS_CCC10: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC11: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC12: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC13: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC14: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC15: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC16: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC17: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC18: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC19: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC20: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC21: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC22: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC23: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC24: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC25: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC26: [Hebrew]
- * @HB_UNICODE_COMBINING_CLASS_CCC27: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC28: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC29: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC30: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC31: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC32: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC33: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC34: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC35: [Arabic]
- * @HB_UNICODE_COMBINING_CLASS_CCC36: [Syriac]
- * @HB_UNICODE_COMBINING_CLASS_CCC84: [Telugu]
- * @HB_UNICODE_COMBINING_CLASS_CCC91: [Telugu]
- * @HB_UNICODE_COMBINING_CLASS_CCC103: [Thai]
- * @HB_UNICODE_COMBINING_CLASS_CCC107: [Thai]
- * @HB_UNICODE_COMBINING_CLASS_CCC118: [Lao]
- * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao]
- * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan]
- * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan]
- * @HB_UNICODE_COMBINING_CLASS_CCC132: [Tibetan] Since: 7.2.0
- * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left
- * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below
- * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above
- * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: Marks attached at the top right
- * @HB_UNICODE_COMBINING_CLASS_BELOW_LEFT: Distinct marks at the bottom left
- * @HB_UNICODE_COMBINING_CLASS_BELOW: Distinct marks directly below
- * @HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: Distinct marks at the bottom right
- * @HB_UNICODE_COMBINING_CLASS_LEFT: Distinct marks to the left
- * @HB_UNICODE_COMBINING_CLASS_RIGHT: Distinct marks to the right
- * @HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT: Distinct marks at the top left
- * @HB_UNICODE_COMBINING_CLASS_ABOVE: Distinct marks directly above
- * @HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT: Distinct marks at the top right
- * @HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: Distinct marks subtending two bases
- * @HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: Distinct marks extending above two bases
- * @HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT: Greek iota subscript only
- * @HB_UNICODE_COMBINING_CLASS_INVALID: Invalid combining class
- *
- * Data type for the Canonical_Combining_Class (ccc) property
- * from the Unicode Character Database.
- *
- * <note>Note: newer versions of Unicode may add new values.
- * Client programs should be ready to handle any value in the 0..254 range
- * being returned from hb_unicode_combining_class().</note>
- *
- **/
+/* hb_unicode_combining_class_t */
+
+/* Note: newer versions of Unicode may add new values. Clients should be ready to handle
+ * any value in the 0..254 range being returned from hb_unicode_combining_class().
+ */
+
+/* Unicode Character Database property: Canonical_Combining_Class (ccc) */
typedef enum
{
HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0,
@@ -246,7 +140,7 @@ typedef enum
/* Tibetan */
HB_UNICODE_COMBINING_CLASS_CCC129 = 129,
HB_UNICODE_COMBINING_CLASS_CCC130 = 130,
- HB_UNICODE_COMBINING_CLASS_CCC132 = 132,
+ HB_UNICODE_COMBINING_CLASS_CCC133 = 132,
HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT = 200,
@@ -274,18 +168,6 @@ typedef enum
* hb_unicode_funcs_t
*/
-/**
- * hb_unicode_funcs_t:
- *
- * Data type containing a set of virtual methods used for
- * accessing various Unicode character properties.
- *
- * HarfBuzz provides a default function for each of the
- * methods in #hb_unicode_funcs_t. Client programs can implement
- * their own replacements for the individual Unicode functions, as
- * needed, and replace the default by calling the setter for a
- * method.
- **/
typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
@@ -310,15 +192,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
HB_EXTERN hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
hb_bool_t replace);
HB_EXTERN void *
-hb_unicode_funcs_get_user_data (const hb_unicode_funcs_t *ufuncs,
- hb_user_data_key_t *key);
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+ hb_user_data_key_t *key);
HB_EXTERN void
@@ -337,141 +219,69 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
/* typedefs */
-/**
- * hb_unicode_combining_class_func_t:
- * @ufuncs: A Unicode-functions structure
- * @unicode: The code point to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should retrieve the Canonical Combining Class (ccc)
- * property for a specified Unicode code point.
- *
- * Return value: The #hb_unicode_combining_class_t of @unicode
- *
- **/
typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
-
-/**
- * hb_unicode_general_category_func_t:
- * @ufuncs: A Unicode-functions structure
- * @unicode: The code point to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should retrieve the General Category property for
- * a specified Unicode code point.
- *
- * Return value: The #hb_unicode_general_category_t of @unicode
- *
- **/
+typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
-
-/**
- * hb_unicode_mirroring_func_t:
- * @ufuncs: A Unicode-functions structure
- * @unicode: The code point to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should retrieve the Bi-Directional Mirroring Glyph
- * code point for a specified Unicode code point.
- *
- * <note>Note: If a code point does not have a specified
- * Bi-Directional Mirroring Glyph defined, the method should
- * return the original code point.</note>
- *
- * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode
- *
- **/
typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
-
-/**
- * hb_unicode_script_func_t:
- * @ufuncs: A Unicode-functions structure
- * @unicode: The code point to query
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should retrieve the Script property for a
- * specified Unicode code point.
- *
- * Return value: The #hb_script_t of @unicode
- *
- **/
typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
-/**
- * hb_unicode_compose_func_t:
- * @ufuncs: A Unicode-functions structure
- * @a: The first code point to compose
- * @b: The second code point to compose
- * @ab: (out): The composed code point
- * @user_data: user data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should compose a sequence of two input Unicode code
- * points by canonical equivalence, returning the composed code
- * point in a #hb_codepoint_t output parameter (if successful).
- * The method must return an #hb_bool_t indicating the success
- * of the composition.
- *
- * Return value: `true` is @a,@b composed, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab,
void *user_data);
-
-/**
- * hb_unicode_decompose_func_t:
- * @ufuncs: A Unicode-functions structure
- * @ab: The code point to decompose
- * @a: (out): The first decomposed code point
- * @b: (out): The second decomposed code point
- * @user_data: user data pointer passed by the caller
- *
- * A virtual method for the #hb_unicode_funcs_t structure.
- *
- * This method should decompose an input Unicode code point,
- * returning the two decomposed code points in #hb_codepoint_t
- * output parameters (if successful). The method must return an
- * #hb_bool_t indicating the success of the composition.
- *
- * Return value: `true` if @ab decomposed, `false` otherwise
- *
- **/
typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab,
hb_codepoint_t *a,
hb_codepoint_t *b,
void *user_data);
-/* func setters */
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: a Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ */
+typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed,
+ void *user_data);
+
+/* See Unicode 6.1 for details on the maximum decomposition length. */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
+/* setters */
/**
* hb_unicode_funcs_set_combining_class_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_combining_class_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -481,13 +291,29 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
void *user_data, hb_destroy_func_t destroy);
/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+HB_EXTERN void
+hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_eastasian_width_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
+/**
* hb_unicode_funcs_set_general_category_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_general_category_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -498,12 +324,12 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_mirroring_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_mirroring_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -514,12 +340,12 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_script_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_script_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -530,12 +356,12 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_compose_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_compose_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -546,12 +372,12 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_funcs_set_decompose_func:
- * @ufuncs: A Unicode-functions structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
*
- * Sets the implementation function for #hb_unicode_decompose_func_t.
+ *
*
* Since: 0.9.2
**/
@@ -560,17 +386,26 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_decompose_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+HB_EXTERN void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_decompose_compatibility_func_t func,
+ void *user_data, hb_destroy_func_t destroy);
+
/* accessors */
/**
* hb_unicode_combining_class:
- * @ufuncs: The Unicode-functions structure
- * @unicode: The code point to query
- *
- * Retrieves the Canonical Combining Class (ccc) property
- * of code point @unicode.
- *
- * Return value: The #hb_unicode_combining_class_t of @unicode
*
* Since: 0.9.2
**/
@@ -579,14 +414,16 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
/**
- * hb_unicode_general_category:
- * @ufuncs: The Unicode-functions structure
- * @unicode: The code point to query
- *
- * Retrieves the General Category (gc) property
- * of code point @unicode.
+ * hb_unicode_eastasian_width:
*
- * Return value: The #hb_unicode_general_category_t of @unicode
+ * Since: 0.9.2
+ **/
+HB_EXTERN unsigned int
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+/**
+ * hb_unicode_general_category:
*
* Since: 0.9.2
**/
@@ -596,13 +433,6 @@ hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_mirroring:
- * @ufuncs: The Unicode-functions structure
- * @unicode: The code point to query
- *
- * Retrieves the Bi-directional Mirroring Glyph code
- * point defined for code point @unicode.
- *
- * Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode
*
* Since: 0.9.2
**/
@@ -612,13 +442,6 @@ hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_script:
- * @ufuncs: The Unicode-functions structure
- * @unicode: The code point to query
- *
- * Retrieves the #hb_script_t script to which code
- * point @unicode belongs.
- *
- * Return value: The #hb_script_t of @unicode
*
* Since: 0.9.2
**/
@@ -638,6 +461,11 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *a,
hb_codepoint_t *b);
+HB_EXTERN unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u,
+ hb_codepoint_t *decomposed);
+
HB_END_DECLS
#endif /* HB_UNICODE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc b/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc
deleted file mode 100644
index 9648e026635..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * Copyright © 2011,2012,2013 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.hh"
-
-#ifdef HAVE_UNISCRIBE
-
-#ifdef HB_NO_OT_TAG
-#error "Cannot compile 'uniscribe' shaper with HB_NO_OT_TAG."
-#endif
-
-#include "hb-shaper-impl.hh"
-
-#include <windows.h>
-#include <usp10.h>
-#include <rpc.h>
-
-#ifndef E_NOT_SUFFICIENT_BUFFER
-#define E_NOT_SUFFICIENT_BUFFER HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)
-#endif
-
-#include "hb-uniscribe.h"
-
-#include "hb-ms-feature-ranges.hh"
-#include "hb-open-file.hh"
-#include "hb-ot-name-table.hh"
-#include "hb-ot-layout.h"
-
-
-/**
- * SECTION:hb-uniscribe
- * @title: hb-uniscribe
- * @short_description: Windows integration
- * @include: hb-uniscribe.h
- *
- * Functions for using HarfBuzz with Windows fonts.
- **/
-
-typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
- const WCHAR *pwcInChars,
- int cInChars,
- int cMaxItems,
- const SCRIPT_CONTROL *psControl,
- const SCRIPT_STATE *psState,
- SCRIPT_ITEM *pItems,
- OPENTYPE_TAG *pScriptTags,
- int *pcItems
-);
-
-typedef HRESULT (WINAPI *SSOT) /*ScriptShapeOpenType*/(
- HDC hdc,
- SCRIPT_CACHE *psc,
- SCRIPT_ANALYSIS *psa,
- OPENTYPE_TAG tagScript,
- OPENTYPE_TAG tagLangSys,
- int *rcRangeChars,
- TEXTRANGE_PROPERTIES **rpRangeProperties,
- int cRanges,
- const WCHAR *pwcChars,
- int cChars,
- int cMaxGlyphs,
- WORD *pwLogClust,
- SCRIPT_CHARPROP *pCharProps,
- WORD *pwOutGlyphs,
- SCRIPT_GLYPHPROP *pOutGlyphProps,
- int *pcGlyphs
-);
-
-typedef HRESULT (WINAPI *SPOT) /*ScriptPlaceOpenType*/(
- HDC hdc,
- SCRIPT_CACHE *psc,
- SCRIPT_ANALYSIS *psa,
- OPENTYPE_TAG tagScript,
- OPENTYPE_TAG tagLangSys,
- int *rcRangeChars,
- TEXTRANGE_PROPERTIES **rpRangeProperties,
- int cRanges,
- const WCHAR *pwcChars,
- WORD *pwLogClust,
- SCRIPT_CHARPROP *pCharProps,
- int cChars,
- const WORD *pwGlyphs,
- const SCRIPT_GLYPHPROP *pGlyphProps,
- int cGlyphs,
- int *piAdvance,
- GOFFSET *pGoffset,
- ABC *pABC
-);
-
-
-/* Fallback implementations. */
-
-static HRESULT WINAPI
-hb_ScriptItemizeOpenType(
- const WCHAR *pwcInChars,
- int cInChars,
- int cMaxItems,
- const SCRIPT_CONTROL *psControl,
- const SCRIPT_STATE *psState,
- SCRIPT_ITEM *pItems,
- OPENTYPE_TAG *pScriptTags,
- int *pcItems
-)
-{
-{
- return ScriptItemize (pwcInChars,
- cInChars,
- cMaxItems,
- psControl,
- psState,
- pItems,
- pcItems);
-}
-}
-
-static HRESULT WINAPI
-hb_ScriptShapeOpenType(
- HDC hdc,
- SCRIPT_CACHE *psc,
- SCRIPT_ANALYSIS *psa,
- OPENTYPE_TAG tagScript,
- OPENTYPE_TAG tagLangSys,
- int *rcRangeChars,
- TEXTRANGE_PROPERTIES **rpRangeProperties,
- int cRanges,
- const WCHAR *pwcChars,
- int cChars,
- int cMaxGlyphs,
- WORD *pwLogClust,
- SCRIPT_CHARPROP *pCharProps,
- WORD *pwOutGlyphs,
- SCRIPT_GLYPHPROP *pOutGlyphProps,
- int *pcGlyphs
-)
-{
- SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pOutGlyphProps;
- return ScriptShape (hdc,
- psc,
- pwcChars,
- cChars,
- cMaxGlyphs,
- psa,
- pwOutGlyphs,
- pwLogClust,
- psva,
- pcGlyphs);
-}
-
-static HRESULT WINAPI
-hb_ScriptPlaceOpenType(
- HDC hdc,
- SCRIPT_CACHE *psc,
- SCRIPT_ANALYSIS *psa,
- OPENTYPE_TAG tagScript,
- OPENTYPE_TAG tagLangSys,
- int *rcRangeChars,
- TEXTRANGE_PROPERTIES **rpRangeProperties,
- int cRanges,
- const WCHAR *pwcChars,
- WORD *pwLogClust,
- SCRIPT_CHARPROP *pCharProps,
- int cChars,
- const WORD *pwGlyphs,
- const SCRIPT_GLYPHPROP *pGlyphProps,
- int cGlyphs,
- int *piAdvance,
- GOFFSET *pGoffset,
- ABC *pABC
-)
-{
- SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pGlyphProps;
- return ScriptPlace (hdc,
- psc,
- pwGlyphs,
- cGlyphs,
- psva,
- psa,
- piAdvance,
- pGoffset,
- pABC);
-}
-
-
-struct hb_uniscribe_shaper_funcs_t
-{
- SIOT ScriptItemizeOpenType;
- SSOT ScriptShapeOpenType;
- SPOT ScriptPlaceOpenType;
-
- void init ()
- {
- HMODULE hinstLib;
- this->ScriptItemizeOpenType = nullptr;
- this->ScriptShapeOpenType = nullptr;
- this->ScriptPlaceOpenType = nullptr;
-
- hinstLib = GetModuleHandle (TEXT ("usp10.dll"));
- if (hinstLib)
- {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-function-type"
- this->ScriptItemizeOpenType = (SIOT) GetProcAddress (hinstLib, "ScriptItemizeOpenType");
- this->ScriptShapeOpenType = (SSOT) GetProcAddress (hinstLib, "ScriptShapeOpenType");
- this->ScriptPlaceOpenType = (SPOT) GetProcAddress (hinstLib, "ScriptPlaceOpenType");
-#pragma GCC diagnostic pop
- }
- if (!this->ScriptItemizeOpenType ||
- !this->ScriptShapeOpenType ||
- !this->ScriptPlaceOpenType)
- {
- DEBUG_MSG (UNISCRIBE, nullptr, "OpenType versions of functions not found; falling back.");
- this->ScriptItemizeOpenType = hb_ScriptItemizeOpenType;
- this->ScriptShapeOpenType = hb_ScriptShapeOpenType;
- this->ScriptPlaceOpenType = hb_ScriptPlaceOpenType;
- }
- }
-};
-
-static inline void free_static_uniscribe_shaper_funcs ();
-
-static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_uniscribe_shaper_funcs_t,
- hb_uniscribe_shaper_funcs_lazy_loader_t>
-{
- static hb_uniscribe_shaper_funcs_t *create ()
- {
- hb_uniscribe_shaper_funcs_t *funcs = (hb_uniscribe_shaper_funcs_t *) hb_calloc (1, sizeof (hb_uniscribe_shaper_funcs_t));
- if (unlikely (!funcs))
- return nullptr;
-
- funcs->init ();
-
- hb_atexit (free_static_uniscribe_shaper_funcs);
-
- return funcs;
- }
- static void destroy (hb_uniscribe_shaper_funcs_t *p)
- {
- hb_free ((void *) p);
- }
- static hb_uniscribe_shaper_funcs_t *get_null ()
- {
- return nullptr;
- }
-} static_uniscribe_shaper_funcs;
-
-static inline
-void free_static_uniscribe_shaper_funcs ()
-{
- static_uniscribe_shaper_funcs.free_instance ();
-}
-
-static hb_uniscribe_shaper_funcs_t *
-hb_uniscribe_shaper_get_funcs ()
-{
- return static_uniscribe_shaper_funcs.get_unconst ();
-}
-
-
-/*
- * shaper face data
- */
-
-struct hb_uniscribe_face_data_t {
- HANDLE fh;
- hb_uniscribe_shaper_funcs_t *funcs;
- wchar_t face_name[LF_FACESIZE];
-};
-
-/* face_name should point to a wchar_t[LF_FACESIZE] object. */
-static void
-_hb_generate_unique_face_name (wchar_t *face_name, unsigned int *plen)
-{
- /* We'll create a private name for the font from a UUID using a simple,
- * somewhat base64-like encoding scheme */
- const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
- UUID id;
- UuidCreate ((UUID*) &id);
- static_assert ((2 + 3 * (16/2) < LF_FACESIZE), "");
- unsigned int name_str_len = 0;
- face_name[name_str_len++] = 'F';
- face_name[name_str_len++] = '_';
- unsigned char *p = (unsigned char *) &id;
- for (unsigned int i = 0; i < 16; i += 2)
- {
- /* Spread the 16 bits from two bytes of the UUID across three chars of face_name,
- * using the bits in groups of 5,5,6 to select chars from enc.
- * This will generate 24 characters; with the 'F_' prefix we already provided,
- * the name will be 26 chars (plus the NUL terminator), so will always fit within
- * face_name (LF_FACESIZE = 32). */
- face_name[name_str_len++] = enc[p[i] >> 3];
- face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f];
- face_name[name_str_len++] = enc[p[i + 1] & 0x3f];
- }
- face_name[name_str_len] = 0;
- if (plen)
- *plen = name_str_len;
-}
-
-/* Destroys blob. */
-static hb_blob_t *
-_hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
-{
- /* Create a copy of the font data, with the 'name' table replaced by a
- * table that names the font with our private F_* name created above.
- * For simplicity, we just append a new 'name' table and update the
- * sfnt directory; the original table is left in place, but unused.
- *
- * The new table will contain just 5 name IDs: family, style, unique,
- * full, PS. All of them point to the same name data with our unique name.
- */
-
- blob = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (blob);
-
- unsigned int length, new_length, name_str_len;
- const char *orig_sfnt_data = hb_blob_get_data (blob, &length);
-
- _hb_generate_unique_face_name (new_name, &name_str_len);
-
- static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 };
-
- unsigned int name_table_length = OT::name::min_size +
- ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
- name_str_len * 2; /* for name data in UTF16BE form */
- unsigned int padded_name_table_length = ((name_table_length + 3) & ~3);
- unsigned int name_table_offset = (length + 3) & ~3;
-
- new_length = name_table_offset + padded_name_table_length;
- void *new_sfnt_data = hb_calloc (1, new_length);
- if (!new_sfnt_data)
- {
- hb_blob_destroy (blob);
- return nullptr;
- }
-
- hb_memcpy(new_sfnt_data, orig_sfnt_data, length);
-
- OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
- name.format = 0;
- name.count = ARRAY_LENGTH (name_IDs);
- name.stringOffset = name.get_size ();
- for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++)
- {
- OT::NameRecord &record = name.nameRecordZ[i];
- record.platformID = 3;
- record.encodingID = 1;
- record.languageID = 0x0409u; /* English */
- record.nameID = name_IDs[i];
- record.length = name_str_len * 2;
- record.offset = 0;
- }
-
- /* Copy string data from new_name, converting wchar_t to UTF16BE. */
- unsigned char *p = &StructAfter<unsigned char> (name);
- for (unsigned int i = 0; i < name_str_len; i++)
- {
- *p++ = new_name[i] >> 8;
- *p++ = new_name[i] & 0xff;
- }
-
- /* Adjust name table entry to point to new name table */
- const OT::OpenTypeFontFile &file = * (OT::OpenTypeFontFile *) (new_sfnt_data);
- unsigned int face_count = file.get_face_count ();
- for (unsigned int face_index = 0; face_index < face_count; face_index++)
- {
- /* Note: doing multiple edits (ie. TTC) can be unsafe. There may be
- * toe-stepping. But we don't really care. */
- const OT::OpenTypeFontFace &face = file.get_face (face_index);
- unsigned int index;
- if (face.find_table_index (HB_OT_TAG_name, &index))
- {
- OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index));
- record.checkSum.set_for_data (&name, padded_name_table_length);
- record.offset = name_table_offset;
- record.length = name_table_length;
- }
- else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */
- {
- hb_free (new_sfnt_data);
- hb_blob_destroy (blob);
- return nullptr;
- }
- }
-
- /* The checkSumAdjustment field in the 'head' table is now wrong,
- * but that doesn't actually seem to cause any problems so we don't
- * bother. */
-
- hb_blob_destroy (blob);
- return hb_blob_create ((const char *) new_sfnt_data, new_length,
- HB_MEMORY_MODE_WRITABLE, new_sfnt_data, hb_free);
-}
-
-hb_uniscribe_face_data_t *
-_hb_uniscribe_shaper_face_data_create (hb_face_t *face)
-{
- hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_calloc (1, sizeof (hb_uniscribe_face_data_t));
- if (unlikely (!data))
- return nullptr;
-
- data->funcs = hb_uniscribe_shaper_get_funcs ();
- if (unlikely (!data->funcs))
- {
- hb_free (data);
- return nullptr;
- }
-
- hb_blob_t *blob = hb_face_reference_blob (face);
- if (unlikely (!hb_blob_get_length (blob)))
- DEBUG_MSG (UNISCRIBE, face, "Face has empty blob");
-
- blob = _hb_rename_font (blob, data->face_name);
- if (unlikely (!blob))
- {
- hb_free (data);
- return nullptr;
- }
-
- DWORD num_fonts_installed;
- data->fh = AddFontMemResourceEx ((void *) hb_blob_get_data (blob, nullptr),
- hb_blob_get_length (blob),
- 0, &num_fonts_installed);
- if (unlikely (!data->fh))
- {
- DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
- hb_free (data);
- return nullptr;
- }
-
- return data;
-}
-
-void
-_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data)
-{
- RemoveFontMemResourceEx (data->fh);
- hb_free (data);
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_uniscribe_font_data_t
-{
- HDC hdc;
- mutable LOGFONTW log_font;
- HFONT hfont;
- mutable SCRIPT_CACHE script_cache;
- double x_mult, y_mult; /* From LOGFONT space to HB space. */
-};
-
-static bool
-populate_log_font (LOGFONTW *lf,
- hb_font_t *font,
- unsigned int font_size)
-{
- hb_memset (lf, 0, sizeof (*lf));
- lf->lfHeight = - (int) font_size;
- lf->lfCharSet = DEFAULT_CHARSET;
-
- hb_memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
-
- return true;
-}
-
-hb_uniscribe_font_data_t *
-_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
-{
- hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) hb_calloc (1, sizeof (hb_uniscribe_font_data_t));
- if (unlikely (!data))
- return nullptr;
-
- int font_size = font->face->get_upem (); /* Default... */
- /* No idea if the following is even a good idea. */
- if (font->y_ppem)
- font_size = font->y_ppem;
-
- if (font_size < 0)
- font_size = -font_size;
- data->x_mult = (double) font->x_scale / font_size;
- data->y_mult = (double) font->y_scale / font_size;
-
- data->hdc = GetDC (nullptr);
-
- if (unlikely (!populate_log_font (&data->log_font, font, font_size))) {
- DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed");
- _hb_uniscribe_shaper_font_data_destroy (data);
- return nullptr;
- }
-
- data->hfont = CreateFontIndirectW (&data->log_font);
- if (unlikely (!data->hfont)) {
- DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed");
- _hb_uniscribe_shaper_font_data_destroy (data);
- return nullptr;
- }
-
- if (!SelectObject (data->hdc, data->hfont)) {
- DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed");
- _hb_uniscribe_shaper_font_data_destroy (data);
- return nullptr;
- }
-
- return data;
-}
-
-void
-_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
-{
- if (data->hdc)
- ReleaseDC (nullptr, data->hdc);
- if (data->hfont)
- DeleteObject (data->hfont);
- if (data->script_cache)
- ScriptFreeCache (&data->script_cache);
- hb_free (data);
-}
-
-/**
- * hb_uniscribe_font_get_logfontw:
- * @font: The #hb_font_t to work upon
- *
- * Fetches the LOGFONTW structure that corresponds to the
- * specified #hb_font_t font.
- *
- * Return value: a pointer to the LOGFONTW retrieved
- *
- **/
-LOGFONTW *
-hb_uniscribe_font_get_logfontw (hb_font_t *font)
-{
- const hb_uniscribe_font_data_t *data = font->data.uniscribe;
- return data ? &data->log_font : nullptr;
-}
-
-/**
- * hb_uniscribe_font_get_hfont:
- * @font: The #hb_font_t to work upon
- *
- * Fetches the HFONT handle that corresponds to the
- * specified #hb_font_t font.
- *
- * Return value: the HFONT retreieved
- *
- **/
-HFONT
-hb_uniscribe_font_get_hfont (hb_font_t *font)
-{
- const hb_uniscribe_font_data_t *data = font->data.uniscribe;
- return data ? data->hfont : nullptr;
-}
-
-
-/*
- * shaper
- */
-
-
-hb_bool_t
-_hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features)
-{
- hb_face_t *face = font->face;
- const hb_uniscribe_face_data_t *face_data = face->data.uniscribe;
- const hb_uniscribe_font_data_t *font_data = font->data.uniscribe;
- hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
-
-#define FAIL(...) \
- HB_STMT_START { \
- DEBUG_MSG (UNISCRIBE, nullptr, __VA_ARGS__); \
- return false; \
- } HB_STMT_END
-
- HRESULT hr;
-
-retry:
-
- unsigned int scratch_size;
- hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
-
-#define ALLOCATE_ARRAY(Type, name, len) \
- Type *name = (Type *) scratch; \
- do { \
- unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
- assert (_consumed <= scratch_size); \
- scratch += _consumed; \
- scratch_size -= _consumed; \
- } while (0)
-
-#define utf16_index() var1.u32
-
- ALLOCATE_ARRAY (WCHAR, pchars, buffer->len * 2);
-
- unsigned int chars_len = 0;
- for (unsigned int i = 0; i < buffer->len; i++)
- {
- hb_codepoint_t c = buffer->info[i].codepoint;
- buffer->info[i].utf16_index() = chars_len;
- if (likely (c <= 0xFFFFu))
- pchars[chars_len++] = c;
- else if (unlikely (c > 0x10FFFFu))
- pchars[chars_len++] = 0xFFFDu;
- else {
- pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
- pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
- }
- }
-
- ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
- ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len);
-
- if (num_features)
- {
- /* Need log_clusters to assign features. */
- chars_len = 0;
- for (unsigned int i = 0; i < buffer->len; i++)
- {
- hb_codepoint_t c = buffer->info[i].codepoint;
- unsigned int cluster = buffer->info[i].cluster;
- log_clusters[chars_len++] = cluster;
- if (hb_in_range (c, 0x10000u, 0x10FFFFu))
- log_clusters[chars_len++] = cluster; /* Surrogates. */
- }
- }
-
- /* The -2 in the following is to compensate for possible
- * alignment needed after the WORD array. sizeof(WORD) == 2. */
- unsigned int glyphs_size = (scratch_size * sizeof (int) - 2)
- / (sizeof (WORD) +
- sizeof (SCRIPT_GLYPHPROP) +
- sizeof (int) +
- sizeof (GOFFSET) +
- sizeof (uint32_t));
-
- ALLOCATE_ARRAY (WORD, glyphs, glyphs_size);
- ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size);
- ALLOCATE_ARRAY (int, advances, glyphs_size);
- ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size);
- ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
-
- /* Note:
- * We can't touch the contents of glyph_props. Our fallback
- * implementations of Shape and Place functions use that buffer
- * by casting it to a different type. It works because they
- * both agree about it, but if we want to access it here we
- * need address that issue first.
- */
-
-#undef ALLOCATE_ARRAY
-
-#define MAX_ITEMS 256
-
- SCRIPT_ITEM items[MAX_ITEMS + 1];
- SCRIPT_CONTROL bidi_control = {0};
- SCRIPT_STATE bidi_state = {0};
- ULONG script_tags[MAX_ITEMS];
- int item_count;
-
- /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */
- //bidi_control.fMergeNeutralItems = true;
- *(uint32_t*)&bidi_control |= 1u<<24;
-
- bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
- bidi_state.fOverrideDirection = 1;
-
- hr = funcs->ScriptItemizeOpenType (pchars,
- chars_len,
- MAX_ITEMS,
- &bidi_control,
- &bidi_state,
- items,
- script_tags,
- &item_count);
- if (unlikely (FAILED (hr)))
- FAIL ("ScriptItemizeOpenType() failed: 0x%08lx", hr);
-
-#undef MAX_ITEMS
-
- hb_tag_t lang_tag;
- unsigned int lang_count = 1;
- hb_ot_tags_from_script_and_language (buffer->props.script,
- buffer->props.language,
- nullptr, nullptr,
- &lang_count, &lang_tag);
- OPENTYPE_TAG language_tag = hb_uint32_swap (lang_count ? lang_tag : HB_TAG_NONE);
-
- /*
- * Set up features.
- */
- static_assert ((sizeof (TEXTRANGE_PROPERTIES) == sizeof (hb_ms_features_t)), "");
- static_assert ((sizeof (OPENTYPE_FEATURE_RECORD) == sizeof (hb_ms_feature_t)), "");
- hb_vector_t<hb_ms_feature_t> feature_records;
- hb_vector_t<hb_ms_range_record_t> range_records;
- bool has_features = false;
- if (num_features)
- has_features = hb_ms_setup_features (features,
- num_features,
- feature_records,
- range_records);
-
- hb_vector_t<hb_ms_features_t*> range_properties;
- hb_vector_t<uint32_t> range_char_counts;
-
- unsigned int glyphs_offset = 0;
- unsigned int glyphs_len;
- bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
- for (int i = 0; i < item_count; i++)
- {
- unsigned int chars_offset = items[i].iCharPos;
- unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset;
-
- if (has_features)
- hb_ms_make_feature_ranges (feature_records,
- range_records,
- item_chars_len,
- chars_offset,
- log_clusters,
- range_properties,
- range_char_counts);
-
- /* Asking for glyphs in logical order circumvents at least
- * one bug in Uniscribe. */
- items[i].a.fLogicalOrder = true;
-
- retry_shape:
- hr = funcs->ScriptShapeOpenType (font_data->hdc,
- &font_data->script_cache,
- &items[i].a,
- script_tags[i],
- language_tag,
- (int *) range_char_counts.arrayZ,
- (TEXTRANGE_PROPERTIES**) range_properties.arrayZ,
- range_properties.length,
- pchars + chars_offset,
- item_chars_len,
- glyphs_size - glyphs_offset,
- /* out */
- log_clusters + chars_offset,
- char_props + chars_offset,
- glyphs + glyphs_offset,
- glyph_props + glyphs_offset,
- (int *) &glyphs_len);
-
- if (unlikely (items[i].a.fNoGlyphIndex))
- FAIL ("ScriptShapeOpenType() set fNoGlyphIndex");
- if (unlikely (hr == E_OUTOFMEMORY || hr == E_NOT_SUFFICIENT_BUFFER))
- {
- if (unlikely (!buffer->ensure (buffer->allocated * 2)))
- FAIL ("Buffer resize failed");
- goto retry;
- }
- if (unlikely (hr == USP_E_SCRIPT_NOT_IN_FONT))
- {
- if (items[i].a.eScript == SCRIPT_UNDEFINED)
- FAIL ("ScriptShapeOpenType() failed: Font doesn't support script");
- items[i].a.eScript = SCRIPT_UNDEFINED;
- goto retry_shape;
- }
- if (unlikely (FAILED (hr)))
- {
- FAIL ("ScriptShapeOpenType() failed: 0x%08lx", hr);
- }
-
- for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++)
- log_clusters[j] += glyphs_offset;
-
- hr = funcs->ScriptPlaceOpenType (font_data->hdc,
- &font_data->script_cache,
- &items[i].a,
- script_tags[i],
- language_tag,
- (int *) range_char_counts.arrayZ,
- (TEXTRANGE_PROPERTIES**) range_properties.arrayZ,
- range_properties.length,
- pchars + chars_offset,
- log_clusters + chars_offset,
- char_props + chars_offset,
- item_chars_len,
- glyphs + glyphs_offset,
- glyph_props + glyphs_offset,
- glyphs_len,
- /* out */
- advances + glyphs_offset,
- offsets + glyphs_offset,
- nullptr);
- if (unlikely (FAILED (hr)))
- FAIL ("ScriptPlaceOpenType() failed: 0x%08lx", hr);
-
- if (DEBUG_ENABLED (UNISCRIBE))
- fprintf (stderr, "Item %d RTL %d LayoutRTL %d LogicalOrder %d ScriptTag %c%c%c%c\n",
- i,
- items[i].a.fRTL,
- items[i].a.fLayoutRTL,
- items[i].a.fLogicalOrder,
- HB_UNTAG (hb_uint32_swap (script_tags[i])));
-
- glyphs_offset += glyphs_len;
- }
- glyphs_len = glyphs_offset;
-
- /* Ok, we've got everything we need, now compose output buffer,
- * very, *very*, carefully! */
-
- /* Calculate visual-clusters. That's what we ship. */
- for (unsigned int i = 0; i < glyphs_len; i++)
- vis_clusters[i] = (uint32_t) -1;
- for (unsigned int i = 0; i < buffer->len; i++) {
- uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
- *p = hb_min (*p, buffer->info[i].cluster);
- }
- for (unsigned int i = 1; i < glyphs_len; i++)
- if (vis_clusters[i] == (uint32_t) -1)
- vis_clusters[i] = vis_clusters[i - 1];
-
-#undef utf16_index
-
- if (unlikely (!buffer->ensure (glyphs_len)))
- FAIL ("Buffer in error");
-
-#undef FAIL
-
- /* Set glyph infos */
- buffer->len = 0;
- for (unsigned int i = 0; i < glyphs_len; i++)
- {
- hb_glyph_info_t *info = &buffer->info[buffer->len++];
-
- info->codepoint = glyphs[i];
- info->cluster = vis_clusters[i];
-
- /* The rest is crap. Let's store position info there for now. */
- info->mask = advances[i];
- info->var1.i32 = offsets[i].du;
- info->var2.i32 = offsets[i].dv;
- }
-
- /* Set glyph positions */
- buffer->clear_positions ();
- double x_mult = font_data->x_mult, y_mult = font_data->y_mult;
- for (unsigned int i = 0; i < glyphs_len; i++)
- {
- hb_glyph_info_t *info = &buffer->info[i];
- hb_glyph_position_t *pos = &buffer->pos[i];
-
- /* TODO vertical */
- pos->x_advance = x_mult * (int32_t) info->mask;
- pos->x_offset = x_mult * (backward ? -info->var1.i32 : info->var1.i32);
- pos->y_offset = y_mult * info->var2.i32;
- }
-
- if (backward)
- hb_buffer_reverse (buffer);
-
- buffer->clear_glyph_flags ();
- buffer->unsafe_to_break ();
-
- /* Wow, done! */
- return true;
-}
-
-
-#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.h b/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.h
deleted file mode 100644
index 4e4ef9986a6..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-uniscribe.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright © 2011 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_UNISCRIBE_H
-#define HB_UNISCRIBE_H
-
-#include "hb.h"
-
-#include <windows.h>
-
-HB_BEGIN_DECLS
-
-
-HB_EXTERN LOGFONTW *
-hb_uniscribe_font_get_logfontw (hb_font_t *font);
-
-HB_EXTERN HFONT
-hb_uniscribe_font_get_hfont (hb_font_t *font);
-
-
-HB_END_DECLS
-
-#endif /* HB_UNISCRIBE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
new file mode 100644
index 00000000000..211eb4dc023
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
@@ -0,0 +1,282 @@
+/*
+ * Copyright © 2011,2012,2014 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_UTF_PRIVATE_HH
+#define HB_UTF_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+struct hb_utf8_t
+{
+ typedef uint8_t codepoint_t;
+
+ static inline const uint8_t *
+ next (const uint8_t *text,
+ const uint8_t *end,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ /* Written to only accept well-formed sequences.
+ * Based on ideas from ICU's U8_NEXT.
+ * Generates one "replacement" for each ill-formed byte. */
+
+ hb_codepoint_t c = *text++;
+
+ if (c > 0x7Fu)
+ {
+ if (hb_in_range<hb_codepoint_t> (c, 0xC2u, 0xDFu)) /* Two-byte */
+ {
+ unsigned int t1;
+ if (likely (text < end &&
+ (t1 = text[0] - 0x80u) <= 0x3Fu))
+ {
+ c = ((c&0x1Fu)<<6) | t1;
+ text++;
+ }
+ else
+ goto error;
+ }
+ else if (hb_in_range<hb_codepoint_t> (c, 0xE0u, 0xEFu)) /* Three-byte */
+ {
+ unsigned int t1, t2;
+ if (likely (1 < end - text &&
+ (t1 = text[0] - 0x80u) <= 0x3Fu &&
+ (t2 = text[1] - 0x80u) <= 0x3Fu))
+ {
+ c = ((c&0xFu)<<12) | (t1<<6) | t2;
+ 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<hb_codepoint_t> (c, 0xF0u, 0xF4u)) /* Four-byte */
+ {
+ unsigned int t1, t2, t3;
+ if (likely (2 < end - text &&
+ (t1 = text[0] - 0x80u) <= 0x3Fu &&
+ (t2 = text[1] - 0x80u) <= 0x3Fu &&
+ (t3 = text[2] - 0x80u) <= 0x3Fu))
+ {
+ c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3;
+ if (unlikely (!hb_in_range<hb_codepoint_t> (c, 0x10000u, 0x10FFFFu)))
+ goto error;
+ text += 3;
+ }
+ else
+ goto error;
+ }
+ else
+ goto error;
+ }
+
+ *unicode = c;
+ return text;
+
+ error:
+ *unicode = replacement;
+ return text;
+ }
+
+ static inline const uint8_t *
+ prev (const uint8_t *text,
+ const uint8_t *start,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ const uint8_t *end = text--;
+ while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
+ text--;
+
+ if (likely (next (text, end, unicode, replacement) == end))
+ return text;
+
+ *unicode = replacement;
+ return end - 1;
+ }
+
+ static inline unsigned int
+ strlen (const uint8_t *text)
+ {
+ return ::strlen ((const char *) text);
+ }
+};
+
+
+struct hb_utf16_t
+{
+ typedef uint16_t codepoint_t;
+
+ static inline const uint16_t *
+ next (const uint16_t *text,
+ const uint16_t *end,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ hb_codepoint_t c = *text++;
+
+ if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
+ {
+ *unicode = c;
+ return text;
+ }
+
+ if (likely (c <= 0xDBFFu && text < end))
+ {
+ /* High-surrogate in c */
+ hb_codepoint_t l = *text;
+ if (likely (hb_in_range<hb_codepoint_t> (l, 0xDC00u, 0xDFFFu)))
+ {
+ /* Low-surrogate in l */
+ *unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u);
+ text++;
+ return text;
+ }
+ }
+
+ /* Lonely / out-of-order surrogate. */
+ *unicode = replacement;
+ return text;
+ }
+
+ static inline const uint16_t *
+ prev (const uint16_t *text,
+ const uint16_t *start,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ hb_codepoint_t c = *--text;
+
+ if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
+ {
+ *unicode = c;
+ return text;
+ }
+
+ if (likely (c >= 0xDC00u && start < text))
+ {
+ /* Low-surrogate in c */
+ hb_codepoint_t h = text[-1];
+ if (likely (hb_in_range<hb_codepoint_t> (h, 0xD800u, 0xDBFFu)))
+ {
+ /* High-surrogate in h */
+ *unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
+ text--;
+ return text;
+ }
+ }
+
+ /* Lonely / out-of-order surrogate. */
+ *unicode = replacement;
+ return text;
+ }
+
+
+ static inline unsigned int
+ strlen (const uint16_t *text)
+ {
+ unsigned int l = 0;
+ while (*text++) l++;
+ return l;
+ }
+};
+
+
+template <bool validate=true>
+struct hb_utf32_t
+{
+ typedef uint32_t codepoint_t;
+
+ static inline const uint32_t *
+ next (const uint32_t *text,
+ const uint32_t *end HB_UNUSED,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ hb_codepoint_t c = *unicode = *text++;
+ if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu)))
+ *unicode = replacement;
+ return text;
+ }
+
+ static inline const uint32_t *
+ prev (const uint32_t *text,
+ const uint32_t *start HB_UNUSED,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ hb_codepoint_t c = *unicode = *--text;
+ if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu)))
+ *unicode = replacement;
+ return text;
+ }
+
+ static inline unsigned int
+ strlen (const uint32_t *text)
+ {
+ unsigned int l = 0;
+ while (*text++) l++;
+ return l;
+ }
+};
+
+
+struct hb_latin1_t
+{
+ typedef uint8_t codepoint_t;
+
+ static inline const uint8_t *
+ next (const uint8_t *text,
+ const uint8_t *end HB_UNUSED,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement HB_UNUSED)
+ {
+ *unicode = *text++;
+ return text;
+ }
+
+ static inline const uint8_t *
+ prev (const uint8_t *text,
+ const uint8_t *start HB_UNUSED,
+ hb_codepoint_t *unicode,
+ hb_codepoint_t replacement)
+ {
+ *unicode = *--text;
+ return text;
+ }
+
+ static inline unsigned int
+ strlen (const uint8_t *text)
+ {
+ unsigned int l = 0;
+ while (*text++) l++;
+ return l;
+ }
+};
+
+#endif /* HB_UTF_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-utf.hh b/src/3rdparty/harfbuzz-ng/src/hb-utf.hh
deleted file mode 100644
index 1120bd1cccf..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-utf.hh
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright © 2011,2012,2014 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_UTF_HH
-#define HB_UTF_HH
-
-#include "hb.hh"
-
-#include "hb-open-type.hh"
-
-
-struct hb_utf8_t
-{
- typedef uint8_t codepoint_t;
- static constexpr unsigned max_len = 4;
-
- static const codepoint_t *
- next (const codepoint_t *text,
- const codepoint_t *end,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- /* Written to only accept well-formed sequences.
- * Based on ideas from ICU's U8_NEXT.
- * Generates one "replacement" for each ill-formed byte. */
-
- hb_codepoint_t c = *text++;
-
- if (c > 0x7Fu)
- {
- if (hb_in_range<hb_codepoint_t> (c, 0xC2u, 0xDFu)) /* Two-byte */
- {
- unsigned int t1;
- if (likely (text < end &&
- (t1 = text[0] - 0x80u) <= 0x3Fu))
- {
- c = ((c&0x1Fu)<<6) | t1;
- text++;
- }
- else
- goto error;
- }
- else if (hb_in_range<hb_codepoint_t> (c, 0xE0u, 0xEFu)) /* Three-byte */
- {
- unsigned int t1, t2;
- if (likely (1 < end - text &&
- (t1 = text[0] - 0x80u) <= 0x3Fu &&
- (t2 = text[1] - 0x80u) <= 0x3Fu))
- {
- c = ((c&0xFu)<<12) | (t1<<6) | t2;
- 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<hb_codepoint_t> (c, 0xF0u, 0xF4u)) /* Four-byte */
- {
- unsigned int t1, t2, t3;
- if (likely (2 < end - text &&
- (t1 = text[0] - 0x80u) <= 0x3Fu &&
- (t2 = text[1] - 0x80u) <= 0x3Fu &&
- (t3 = text[2] - 0x80u) <= 0x3Fu))
- {
- c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3;
- if (unlikely (!hb_in_range<hb_codepoint_t> (c, 0x10000u, 0x10FFFFu)))
- goto error;
- text += 3;
- }
- else
- goto error;
- }
- else
- goto error;
- }
-
- *unicode = c;
- return text;
-
- error:
- *unicode = replacement;
- return text;
- }
-
- static const codepoint_t *
- prev (const codepoint_t *text,
- const codepoint_t *start,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- const codepoint_t *end = text--;
- while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
- text--;
-
- if (likely (next (text, end, unicode, replacement) == end))
- return text;
-
- *unicode = replacement;
- return end - 1;
- }
-
- static unsigned int
- strlen (const codepoint_t *text)
- { return ::strlen ((const char *) text); }
-
- static unsigned int
- encode_len (hb_codepoint_t unicode)
- {
- if (unicode < 0x0080u) return 1;
- if (unicode < 0x0800u) return 2;
- if (unicode < 0x10000u) return 3;
- if (unicode < 0x110000u) return 4;
- return 3;
- }
-
- static codepoint_t *
- encode (codepoint_t *text,
- const codepoint_t *end,
- hb_codepoint_t unicode)
- {
- if (unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu)))
- unicode = 0xFFFDu;
- if (unicode < 0x0080u)
- *text++ = unicode;
- else if (unicode < 0x0800u)
- {
- if (end - text >= 2)
- {
- *text++ = 0xC0u + (0x1Fu & (unicode >> 6));
- *text++ = 0x80u + (0x3Fu & (unicode ));
- }
- }
- else if (unicode < 0x10000u)
- {
- if (end - text >= 3)
- {
- *text++ = 0xE0u + (0x0Fu & (unicode >> 12));
- *text++ = 0x80u + (0x3Fu & (unicode >> 6));
- *text++ = 0x80u + (0x3Fu & (unicode ));
- }
- }
- else
- {
- if (end - text >= 4)
- {
- *text++ = 0xF0u + (0x07u & (unicode >> 18));
- *text++ = 0x80u + (0x3Fu & (unicode >> 12));
- *text++ = 0x80u + (0x3Fu & (unicode >> 6));
- *text++ = 0x80u + (0x3Fu & (unicode ));
- }
- }
- return text;
- }
-};
-
-
-template <typename TCodepoint>
-struct hb_utf16_xe_t
-{
- static_assert (sizeof (TCodepoint) == 2, "");
- typedef TCodepoint codepoint_t;
- static constexpr unsigned max_len = 2;
-
- static const codepoint_t *
- next (const codepoint_t *text,
- const codepoint_t *end,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- hb_codepoint_t c = *text++;
-
- if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
- {
- *unicode = c;
- return text;
- }
-
- if (likely (c <= 0xDBFFu && text < end))
- {
- /* High-surrogate in c */
- hb_codepoint_t l = *text;
- if (likely (hb_in_range<hb_codepoint_t> (l, 0xDC00u, 0xDFFFu)))
- {
- /* Low-surrogate in l */
- *unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u);
- text++;
- return text;
- }
- }
-
- /* Lonely / out-of-order surrogate. */
- *unicode = replacement;
- return text;
- }
-
- static const codepoint_t *
- prev (const codepoint_t *text,
- const codepoint_t *start,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- hb_codepoint_t c = *--text;
-
- if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
- {
- *unicode = c;
- return text;
- }
-
- if (likely (c >= 0xDC00u && start < text))
- {
- /* Low-surrogate in c */
- hb_codepoint_t h = text[-1];
- if (likely (hb_in_range<hb_codepoint_t> (h, 0xD800u, 0xDBFFu)))
- {
- /* High-surrogate in h */
- *unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
- text--;
- return text;
- }
- }
-
- /* Lonely / out-of-order surrogate. */
- *unicode = replacement;
- return text;
- }
-
-
- static unsigned int
- strlen (const codepoint_t *text)
- {
- unsigned int l = 0;
- while (*text++) l++;
- return l;
- }
-
- static unsigned int
- encode_len (hb_codepoint_t unicode)
- {
- return unicode < 0x10000 ? 1 : 2;
- }
-
- static codepoint_t *
- encode (codepoint_t *text,
- const codepoint_t *end,
- hb_codepoint_t unicode)
- {
- if (unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu)))
- unicode = 0xFFFDu;
- if (unicode < 0x10000u)
- *text++ = unicode;
- else if (end - text >= 2)
- {
- unicode -= 0x10000u;
- *text++ = 0xD800u + (unicode >> 10);
- *text++ = 0xDC00u + (unicode & 0x03FFu);
- }
- return text;
- }
-};
-
-typedef hb_utf16_xe_t<uint16_t> hb_utf16_t;
-typedef hb_utf16_xe_t<OT::HBUINT16> hb_utf16_be_t;
-
-
-template <typename TCodepoint, bool validate=true>
-struct hb_utf32_xe_t
-{
- static_assert (sizeof (TCodepoint) == 4, "");
- typedef TCodepoint codepoint_t;
- static constexpr unsigned max_len = 1;
-
- static const TCodepoint *
- next (const TCodepoint *text,
- const TCodepoint *end HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- hb_codepoint_t c = *unicode = *text++;
- if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu)))
- *unicode = replacement;
- return text;
- }
-
- static const TCodepoint *
- prev (const TCodepoint *text,
- const TCodepoint *start HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- hb_codepoint_t c = *unicode = *--text;
- if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu)))
- *unicode = replacement;
- return text;
- }
-
- static unsigned int
- strlen (const TCodepoint *text)
- {
- unsigned int l = 0;
- while (*text++) l++;
- return l;
- }
-
- static unsigned int
- encode_len (hb_codepoint_t unicode HB_UNUSED)
- {
- return 1;
- }
-
- static codepoint_t *
- encode (codepoint_t *text,
- const codepoint_t *end HB_UNUSED,
- hb_codepoint_t unicode)
- {
- if (validate && unlikely (unicode >= 0xD800u && (unicode <= 0xDFFFu || unicode > 0x10FFFFu)))
- unicode = 0xFFFDu;
- *text++ = unicode;
- return text;
- }
-};
-
-typedef hb_utf32_xe_t<uint32_t> hb_utf32_t;
-typedef hb_utf32_xe_t<uint32_t, false> hb_utf32_novalidate_t;
-
-
-struct hb_latin1_t
-{
- typedef uint8_t codepoint_t;
- static constexpr unsigned max_len = 1;
-
- static const codepoint_t *
- next (const codepoint_t *text,
- const codepoint_t *end HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement HB_UNUSED)
- {
- *unicode = *text++;
- return text;
- }
-
- static const codepoint_t *
- prev (const codepoint_t *text,
- const codepoint_t *start HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement HB_UNUSED)
- {
- *unicode = *--text;
- return text;
- }
-
- static unsigned int
- strlen (const codepoint_t *text)
- {
- unsigned int l = 0;
- while (*text++) l++;
- return l;
- }
-
- static unsigned int
- encode_len (hb_codepoint_t unicode HB_UNUSED)
- {
- return 1;
- }
-
- static codepoint_t *
- encode (codepoint_t *text,
- const codepoint_t *end HB_UNUSED,
- hb_codepoint_t unicode)
- {
- if (unlikely (unicode >= 0x0100u))
- unicode = '?';
- *text++ = unicode;
- return text;
- }
-};
-
-
-struct hb_ascii_t
-{
- typedef uint8_t codepoint_t;
- static constexpr unsigned max_len = 1;
-
- static const codepoint_t *
- next (const codepoint_t *text,
- const codepoint_t *end HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- *unicode = *text++;
- if (*unicode >= 0x0080u)
- *unicode = replacement;
- return text;
- }
-
- static const codepoint_t *
- prev (const codepoint_t *text,
- const codepoint_t *start HB_UNUSED,
- hb_codepoint_t *unicode,
- hb_codepoint_t replacement)
- {
- *unicode = *--text;
- if (*unicode >= 0x0080u)
- *unicode = replacement;
- return text;
- }
-
- static unsigned int
- strlen (const codepoint_t *text)
- {
- unsigned int l = 0;
- while (*text++) l++;
- return l;
- }
-
- static unsigned int
- encode_len (hb_codepoint_t unicode HB_UNUSED)
- {
- return 1;
- }
-
- static codepoint_t *
- encode (codepoint_t *text,
- const codepoint_t *end HB_UNUSED,
- hb_codepoint_t unicode)
- {
- if (unlikely (unicode >= 0x0080u))
- unicode = '?';
- *text++ = unicode;
- return text;
- }
-};
-
-template <typename utf_t>
-static inline const typename utf_t::codepoint_t *
-hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start,
- signed offset)
-{
- hb_codepoint_t unicode;
-
- while (offset-- > 0)
- start = utf_t::next (start,
- start + utf_t::max_len,
- &unicode,
- HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
-
- while (offset++ < 0)
- start = utf_t::prev (start,
- start - utf_t::max_len,
- &unicode,
- HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
-
- return start;
-}
-
-
-#endif /* HB_UTF_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh
deleted file mode 100644
index 58d467a405f..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright © 2017,2018 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_VECTOR_HH
-#define HB_VECTOR_HH
-
-#include "hb.hh"
-#include "hb-array.hh"
-#include "hb-meta.hh"
-#include "hb-null.hh"
-
-
-template <typename Type,
- bool sorted=false>
-struct hb_vector_t
-{
- typedef Type item_t;
- static constexpr unsigned item_size = hb_static_size (Type);
- using array_t = typename std::conditional<sorted, hb_sorted_array_t<Type>, hb_array_t<Type>>::type;
- using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type;
-
- hb_vector_t () = default;
- hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
- {
- alloc (lst.size (), true);
- for (auto&& item : lst)
- push (item);
- }
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_vector_t (const Iterable &o) : hb_vector_t ()
- {
- auto iter = hb_iter (o);
- if (iter.is_random_access_iterator)
- alloc (hb_len (iter), true);
- hb_copy (iter, *this);
- }
- hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
- {
- alloc (o.length, true);
- if (unlikely (in_error ())) return;
- copy_vector (o);
- }
- hb_vector_t (hb_vector_t &&o)
- {
- allocated = o.allocated;
- length = o.length;
- arrayZ = o.arrayZ;
- o.init ();
- }
- ~hb_vector_t () { fini (); }
-
- public:
- int allocated = 0; /* == -1 means allocation failed. */
- unsigned int length = 0;
- public:
- Type *arrayZ = nullptr;
-
- void init ()
- {
- allocated = length = 0;
- arrayZ = nullptr;
- }
- void init0 ()
- {
- }
-
- void fini ()
- {
- shrink_vector (0);
- hb_free (arrayZ);
- init ();
- }
-
- void reset ()
- {
- if (unlikely (in_error ()))
- /* Big Hack! We don't know the true allocated size before
- * an allocation failure happened. But we know it was at
- * least as big as length. Restore it to that and continue
- * as if error did not happen. */
- allocated = length;
- resize (0);
- }
-
- friend void swap (hb_vector_t& a, hb_vector_t& b)
- {
- hb_swap (a.allocated, b.allocated);
- hb_swap (a.length, b.length);
- hb_swap (a.arrayZ, b.arrayZ);
- }
-
- hb_vector_t& operator = (const hb_vector_t &o)
- {
- reset ();
- alloc (o.length, true);
- if (unlikely (in_error ())) return *this;
-
- copy_vector (o);
-
- return *this;
- }
- hb_vector_t& operator = (hb_vector_t &&o)
- {
- hb_swap (*this, o);
- return *this;
- }
-
- hb_bytes_t as_bytes () const
- { return hb_bytes_t ((const char *) arrayZ, get_size ()); }
-
- bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); }
- bool operator != (const hb_vector_t &o) const { return !(*this == o); }
- uint32_t hash () const { return as_array ().hash (); }
-
- Type& operator [] (int i_)
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= length))
- return Crap (Type);
- return arrayZ[i];
- }
- const Type& operator [] (int i_) const
- {
- unsigned int i = (unsigned int) i_;
- if (unlikely (i >= length))
- return Null (Type);
- return arrayZ[i];
- }
-
- Type& tail () { return (*this)[length - 1]; }
- const Type& tail () const { return (*this)[length - 1]; }
-
- explicit operator bool () const { return length; }
- unsigned get_size () const { return length * item_size; }
-
- /* Sink interface. */
- template <typename T>
- hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
-
- array_t as_array () { return hb_array (arrayZ, length); }
- c_array_t as_array () const { return hb_array (arrayZ, length); }
-
- /* Iterator. */
- typedef c_array_t iter_t;
- typedef array_t writer_t;
- iter_t iter () const { return as_array (); }
- writer_t writer () { return as_array (); }
- operator iter_t () const { return iter (); }
- operator writer_t () { return writer (); }
-
- /* Faster range-based for loop. */
- Type *begin () const { return arrayZ; }
- Type *end () const { return arrayZ + length; }
-
-
- hb_sorted_array_t<Type> as_sorted_array ()
- { return hb_sorted_array (arrayZ, length); }
- hb_sorted_array_t<const Type> as_sorted_array () const
- { return hb_sorted_array (arrayZ, length); }
-
- template <typename T> explicit operator T * () { return arrayZ; }
- template <typename T> explicit operator const T * () const { return arrayZ; }
-
- Type * operator + (unsigned int i) { return arrayZ + i; }
- const Type * operator + (unsigned int i) const { return arrayZ + i; }
-
- Type *push ()
- {
- if (unlikely (!resize (length + 1)))
- return &Crap (Type);
- return std::addressof (arrayZ[length - 1]);
- }
- template <typename T,
- typename T2 = Type,
- hb_enable_if (!std::is_copy_constructible<T2>::value &&
- std::is_copy_assignable<T>::value)>
- Type *push (T&& v)
- {
- Type *p = push ();
- if (p == &Crap (Type))
- // If push failed to allocate then don't copy v, since this may cause
- // the created copy to leak memory since we won't have stored a
- // reference to it.
- return p;
- *p = std::forward<T> (v);
- return p;
- }
- template <typename T,
- typename T2 = Type,
- hb_enable_if (std::is_copy_constructible<T2>::value)>
- Type *push (T&& v)
- {
- if (unlikely (!alloc (length + 1)))
- // If push failed to allocate then don't copy v, since this may cause
- // the created copy to leak memory since we won't have stored a
- // reference to it.
- return &Crap (Type);
-
- /* Emplace. */
- length++;
- Type *p = std::addressof (arrayZ[length - 1]);
- return new (p) Type (std::forward<T> (v));
- }
-
- bool in_error () const { return allocated < 0; }
-
- template <typename T = Type,
- hb_enable_if (hb_is_trivially_copy_assignable(T))>
- Type *
- realloc_vector (unsigned new_allocated)
- {
- if (!new_allocated)
- {
- hb_free (arrayZ);
- return nullptr;
- }
- return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_copy_assignable(T))>
- Type *
- realloc_vector (unsigned new_allocated)
- {
- if (!new_allocated)
- {
- hb_free (arrayZ);
- return nullptr;
- }
- Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
- if (likely (new_array))
- {
- for (unsigned i = 0; i < length; i++)
- {
- new (std::addressof (new_array[i])) Type ();
- new_array[i] = std::move (arrayZ[i]);
- arrayZ[i].~Type ();
- }
- hb_free (arrayZ);
- }
- return new_array;
- }
-
- template <typename T = Type,
- hb_enable_if (hb_is_trivially_constructible(T))>
- void
- grow_vector (unsigned size)
- {
- memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
- length = size;
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_constructible(T))>
- void
- grow_vector (unsigned size)
- {
- while (length < size)
- {
- length++;
- new (std::addressof (arrayZ[length - 1])) Type ();
- }
- }
-
- template <typename T = Type,
- hb_enable_if (hb_is_trivially_copyable (T))>
- void
- copy_vector (const hb_vector_t &other)
- {
- length = other.length;
-#ifndef HB_OPTIMIZE_SIZE
- if (sizeof (T) >= sizeof (long long))
- /* This runs faster because of alignment. */
- for (unsigned i = 0; i < length; i++)
- arrayZ[i] = other.arrayZ[i];
- else
-#endif
- hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_copyable (T) &&
- std::is_copy_constructible<T>::value)>
- void
- copy_vector (const hb_vector_t &other)
- {
- length = 0;
- while (length < other.length)
- {
- length++;
- new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]);
- }
- }
- template <typename T = Type,
- hb_enable_if (!hb_is_trivially_copyable (T) &&
- !std::is_copy_constructible<T>::value &&
- std::is_default_constructible<T>::value &&
- std::is_copy_assignable<T>::value)>
- void
- copy_vector (const hb_vector_t &other)
- {
- length = 0;
- while (length < other.length)
- {
- length++;
- new (std::addressof (arrayZ[length - 1])) Type ();
- arrayZ[length - 1] = other.arrayZ[length - 1];
- }
- }
-
- void
- shrink_vector (unsigned size)
- {
- while ((unsigned) length > size)
- {
- arrayZ[(unsigned) length - 1].~Type ();
- length--;
- }
- }
-
- void
- shift_down_vector (unsigned i)
- {
- for (; i < length; i++)
- arrayZ[i - 1] = std::move (arrayZ[i]);
- }
-
- /* Allocate for size but don't adjust length. */
- bool alloc (unsigned int size, bool exact=false)
- {
- if (unlikely (in_error ()))
- return false;
-
- unsigned int new_allocated;
- if (exact)
- {
- /* If exact was specified, we allow shrinking the storage. */
- size = hb_max (size, length);
- if (size <= (unsigned) allocated &&
- size >= (unsigned) allocated >> 2)
- return true;
-
- new_allocated = size;
- }
- else
- {
- if (likely (size <= (unsigned) allocated))
- return true;
-
- new_allocated = allocated;
- while (size > new_allocated)
- new_allocated += (new_allocated >> 1) + 8;
- }
-
-
- /* Reallocate */
-
- bool overflows =
- (int) in_error () ||
- (new_allocated < size) ||
- hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
-
- if (unlikely (overflows))
- {
- allocated = -1;
- return false;
- }
-
- Type *new_array = realloc_vector (new_allocated);
-
- if (unlikely (new_allocated && !new_array))
- {
- if (new_allocated <= (unsigned) allocated)
- return true; // shrinking failed; it's okay; happens in our fuzzer
-
- allocated = -1;
- return false;
- }
-
- arrayZ = new_array;
- allocated = new_allocated;
-
- return true;
- }
-
- bool resize (int size_, bool initialize = true, bool exact = false)
- {
- unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
- if (!alloc (size, exact))
- return false;
-
- if (size > length)
- {
- if (initialize)
- grow_vector (size);
- }
- else if (size < length)
- {
- if (initialize)
- shrink_vector (size);
- }
-
- length = size;
- return true;
- }
- bool resize_exact (int size_, bool initialize = true)
- {
- return resize (size_, initialize, true);
- }
-
- Type pop ()
- {
- if (!length) return Null (Type);
- Type v {std::move (arrayZ[length - 1])};
- arrayZ[length - 1].~Type ();
- length--;
- return v;
- }
-
- void remove_ordered (unsigned int i)
- {
- if (unlikely (i >= length))
- return;
- shift_down_vector (i + 1);
- arrayZ[length - 1].~Type ();
- length--;
- }
-
- template <bool Sorted = sorted,
- hb_enable_if (!Sorted)>
- void remove_unordered (unsigned int i)
- {
- if (unlikely (i >= length))
- return;
- if (i != length - 1)
- arrayZ[i] = std::move (arrayZ[length - 1]);
- arrayZ[length - 1].~Type ();
- length--;
- }
-
- void shrink (int size_, bool shrink_memory = true)
- {
- unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
- if (size >= length)
- return;
-
- shrink_vector (size);
-
- if (shrink_memory)
- alloc (size, true); /* To force shrinking memory if needed. */
- }
-
-
- /* Sorting API. */
- void qsort (int (*cmp)(const void*, const void*) = Type::cmp)
- { as_array ().qsort (cmp); }
-
- /* Unsorted search API. */
- template <typename T>
- Type *lsearch (const T &x, Type *not_found = nullptr)
- { return as_array ().lsearch (x, not_found); }
- template <typename T>
- const Type *lsearch (const T &x, const Type *not_found = nullptr) const
- { return as_array ().lsearch (x, not_found); }
- template <typename T>
- bool lfind (const T &x, unsigned *pos = nullptr) const
- { return as_array ().lfind (x, pos); }
-
- /* Sorted search API. */
- template <typename T,
- bool Sorted=sorted, hb_enable_if (Sorted)>
- Type *bsearch (const T &x, Type *not_found = nullptr)
- { return as_array ().bsearch (x, not_found); }
- template <typename T,
- bool Sorted=sorted, hb_enable_if (Sorted)>
- const Type *bsearch (const T &x, const Type *not_found = nullptr) const
- { return as_array ().bsearch (x, not_found); }
- template <typename T,
- bool Sorted=sorted, hb_enable_if (Sorted)>
- bool bfind (const T &x, unsigned int *i = nullptr,
- hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
- unsigned int to_store = (unsigned int) -1) const
- { return as_array ().bfind (x, i, not_found, to_store); }
-};
-
-template <typename Type>
-using hb_sorted_vector_t = hb_vector_t<Type, true>;
-
-#endif /* HB_VECTOR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index e4be376bc68..fc81b66b40a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
+#ifndef HB_H_IN
#error "Include <hb.h> instead."
#endif
@@ -36,41 +36,12 @@
HB_BEGIN_DECLS
-/**
- * HB_VERSION_MAJOR:
- *
- * The major component of the library version available at compile-time.
- */
-#define HB_VERSION_MAJOR 7
-/**
- * HB_VERSION_MINOR:
- *
- * The minor component of the library version available at compile-time.
- */
-#define HB_VERSION_MINOR 2
-/**
- * HB_VERSION_MICRO:
- *
- * The micro component of the library version available at compile-time.
- */
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MAJOR 1
+#define HB_VERSION_MINOR 7
+#define HB_VERSION_MICRO 4
-/**
- * HB_VERSION_STRING:
- *
- * A string literal containing the library version available at compile-time.
- */
-#define HB_VERSION_STRING "7.2.0"
+#define HB_VERSION_STRING "1.7.4"
-/**
- * HB_VERSION_ATLEAST:
- * @major: the major component of the version number
- * @minor: the minor component of the version number
- * @micro: the micro component of the version number
- *
- * Tests the library version at compile-time against a minimum value,
- * as three integer components.
- */
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-icu.h b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc
index 2db6a7b6797..8f322bcb10d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-icu.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc
@@ -1,6 +1,5 @@
/*
- * Copyright © 2009 Red Hat, Inc.
- * Copyright © 2011 Google, Inc.
+ * Copyright © 2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -22,31 +21,19 @@
* 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
* Google Author(s): Behdad Esfahbod
*/
-#ifndef HB_ICU_H
-#define HB_ICU_H
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
-#include "hb.h"
-#include <unicode/uscript.h>
+#if defined(HB_ATOMIC_INT_NIL)
+#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe"
+#error "Check hb-atomic-private.hh for possible resolutions."
+#endif
-HB_BEGIN_DECLS
-
-
-HB_EXTERN hb_script_t
-hb_icu_script_to_script (UScriptCode script);
-
-HB_EXTERN UScriptCode
-hb_icu_script_from_script (hb_script_t script);
-
-
-HB_EXTERN hb_unicode_funcs_t *
-hb_icu_get_unicode_funcs (void);
-
-
-HB_END_DECLS
-
-#endif /* HB_ICU_H */
+#if defined(HB_MUTEX_IMPL_NIL)
+#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
+#error "Check hb-mutex-private.hh for possible resolutions."
+#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb.h b/src/3rdparty/harfbuzz-ng/src/hb.h
index 5a6ae6607c2..7402034f437 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb.h
@@ -28,19 +28,19 @@
#define HB_H
#define HB_H_IN
+#ifndef HB_EXTERN
+#define HB_EXTERN extern
+#endif
+
#include "hb-blob.h"
#include "hb-buffer.h"
#include "hb-common.h"
#include "hb-deprecated.h"
-#include "hb-draw.h"
#include "hb-face.h"
#include "hb-font.h"
-#include "hb-map.h"
-#include "hb-paint.h"
#include "hb-set.h"
#include "hb-shape.h"
#include "hb-shape-plan.h"
-#include "hb-style.h"
#include "hb-unicode.h"
#include "hb-version.h"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh
deleted file mode 100644
index 30b3de499a1..00000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb.hh
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2011,2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_HH
-#define HB_HH
-
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
-#ifdef _MSC_VER
-#pragma warning( disable: 4068 ) /* Unknown pragma */
-#endif
-#if defined(__GNUC__) || defined(__clang__)
-/* Rules:
- *
- * - All pragmas are declared GCC even if they are clang ones. Otherwise GCC
- * nags, even though we instruct it to ignore -Wunknown-pragmas. ¯\_(ツ)_/¯
- *
- * - Within each category, keep sorted.
- *
- * - Warnings whose scope can be expanded in future compiler versions shall
- * be declared as "warning". Otherwise, either ignored or error.
- */
-
-/* Setup. Don't sort order within this category. */
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
-#pragma GCC diagnostic warning "-Wall"
-#pragma GCC diagnostic warning "-Wextra"
-#endif
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
-#pragma GCC diagnostic ignored "-Wpragmas"
-#pragma GCC diagnostic ignored "-Wunknown-pragmas"
-#pragma GCC diagnostic ignored "-Wunknown-warning-option"
-#endif
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
-//#pragma GCC diagnostic warning "-Weverything"
-#endif
-
-/* Error. Should never happen. */
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR
-#pragma GCC diagnostic error "-Wbitwise-instead-of-logical"
-#pragma GCC diagnostic error "-Wcast-align"
-#pragma GCC diagnostic error "-Wcast-function-type"
-#pragma GCC diagnostic error "-Wcomma"
-#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"
-#pragma GCC diagnostic error "-Wembedded-directive"
-#pragma GCC diagnostic error "-Wextra-semi-stmt"
-#pragma GCC diagnostic error "-Wformat-security"
-#pragma GCC diagnostic error "-Wimplicit-function-declaration"
-#pragma GCC diagnostic error "-Winit-self"
-#pragma GCC diagnostic error "-Winjected-class-name"
-#pragma GCC diagnostic error "-Wmissing-braces"
-#pragma GCC diagnostic error "-Wmissing-declarations"
-#pragma GCC diagnostic error "-Wmissing-prototypes"
-#pragma GCC diagnostic error "-Wnarrowing"
-#pragma GCC diagnostic error "-Wnested-externs"
-#pragma GCC diagnostic error "-Wold-style-definition"
-#pragma GCC diagnostic error "-Wpointer-arith"
-#pragma GCC diagnostic error "-Wredundant-decls"
-#pragma GCC diagnostic error "-Wreorder"
-#pragma GCC diagnostic error "-Wsign-compare"
-#pragma GCC diagnostic error "-Wstrict-prototypes"
-#pragma GCC diagnostic error "-Wstring-conversion"
-#pragma GCC diagnostic error "-Wswitch-enum"
-#pragma GCC diagnostic error "-Wtautological-overlap-compare"
-#pragma GCC diagnostic error "-Wunneeded-internal-declaration"
-#pragma GCC diagnostic error "-Wunused"
-#pragma GCC diagnostic error "-Wunused-local-typedefs"
-#pragma GCC diagnostic error "-Wunused-value"
-#pragma GCC diagnostic error "-Wunused-variable"
-#pragma GCC diagnostic error "-Wvla"
-#pragma GCC diagnostic error "-Wwrite-strings"
-#endif
-
-/* Warning. To be investigated if happens. */
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
-#pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
-#pragma GCC diagnostic warning "-Wdeprecated"
-#pragma GCC diagnostic warning "-Wdeprecated-declarations"
-#pragma GCC diagnostic warning "-Wdisabled-optimization"
-#pragma GCC diagnostic warning "-Wdouble-promotion"
-#pragma GCC diagnostic warning "-Wformat=2"
-#pragma GCC diagnostic warning "-Wformat-signedness"
-#pragma GCC diagnostic warning "-Wignored-pragma-optimize"
-#pragma GCC diagnostic warning "-Wlogical-op"
-#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
-#pragma GCC diagnostic warning "-Wmissing-format-attribute"
-#pragma GCC diagnostic warning "-Wundef"
-#pragma GCC diagnostic warning "-Wunsafe-loop-optimizations"
-#pragma GCC diagnostic warning "-Wunused-but-set-variable"
-#endif
-
-/* Ignored currently, but should be fixed at some point. */
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
-#pragma GCC diagnostic ignored "-Wconversion" // TODO fix
-#pragma GCC diagnostic ignored "-Wshadow" // TODO fix
-#pragma GCC diagnostic ignored "-Wunused-parameter" // TODO fix
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic ignored "-Wunused-result" // TODO fix
-#endif
-#endif
-
-/* Ignored intentionally. */
-#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
-#pragma GCC diagnostic ignored "-Wclass-memaccess"
-#pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126
-#pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
-#pragma GCC diagnostic ignored "-Wformat-zero-length"
-#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang
-#pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834
-#pragma GCC diagnostic ignored "-Wstrict-aliasing"
-#pragma GCC diagnostic ignored "-Wtype-limits"
-#pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it
-#endif
-
-#endif
-#endif
-
-
-#include "hb-config.hh"
-#include "hb-limits.hh"
-
-
-/*
- * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
- * config.h.in. Copied here for the convenience of those embedding
- * HarfBuzz and not using our build system.
- */
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-#if defined (_MSC_VER) && defined (HB_DLL_EXPORT)
-#define HB_EXTERN __declspec (dllexport) extern
-#endif
-
-#include "hb.h"
-#define HB_H_IN
-#include "hb-ot.h"
-#define HB_OT_H_IN
-#include "hb-aat.h"
-#define HB_AAT_H_IN
-
-#include <cassert>
-#include <cfloat>
-#include <climits>
-#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
-# define _USE_MATH_DEFINES
-#endif
-#include <cmath>
-#include <cstdarg>
-#include <cstddef>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
-#ifdef __MINGW32_VERSION
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN 1
-#endif
-#else
-#include <intrin.h>
-#endif
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winapifamily.h>
-#endif
-
-#define HB_PASTE1(a,b) a##b
-#define HB_PASTE(a,b) HB_PASTE1(a,b)
-
-
-/* Compile-time custom allocator support. */
-
-#if !defined(HB_CUSTOM_MALLOC) \
- && defined(hb_malloc_impl) \
- && defined(hb_calloc_impl) \
- && defined(hb_realloc_impl) \
- && defined(hb_free_impl)
-#define HB_CUSTOM_MALLOC
-#endif
-
-#ifdef HB_CUSTOM_MALLOC
-extern "C" void* hb_malloc_impl(size_t size);
-extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
-extern "C" void* hb_realloc_impl(void *ptr, size_t size);
-extern "C" void hb_free_impl(void *ptr);
-#define hb_malloc hb_malloc_impl
-#define hb_calloc hb_calloc_impl
-#define hb_realloc hb_realloc_impl
-#define hb_free hb_free_impl
-#else
-#define hb_malloc malloc
-#define hb_calloc calloc
-#define hb_realloc realloc
-#define hb_free free
-#endif
-
-
-/*
- * Compiler attributes
- */
-
-// gcc 10 has __has_builtin but not earlier versions. Sanction any gcc >= 5
-// clang defines it so no need.
-#ifdef __has_builtin
-#define hb_has_builtin __has_builtin
-#else
-#define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5))
-#endif
-
-#if defined(__OPTIMIZE__) && hb_has_builtin(__builtin_expect)
-#define likely(expr) (__builtin_expect (!!(expr), 1))
-#define unlikely(expr) (__builtin_expect (!!(expr), 0))
-#else
-#define likely(expr) (expr)
-#define unlikely(expr) (expr)
-#endif
-
-#if !defined(__GNUC__) && !defined(__clang__)
-#undef __attribute__
-#define __attribute__(x)
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
-#else
-#define HB_PRINTF_FUNC(format_idx, arg_idx)
-#endif
-#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
-#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
-
-#ifndef HB_INTERNAL
-# if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
-# define HB_INTERNAL __attribute__((__visibility__("hidden")))
-# elif defined(__MINGW32__)
- /* We use -export-symbols on mingw32, since it does not support visibility attributes. */
-# define HB_INTERNAL
-# elif defined (_MSC_VER) && defined (HB_DLL_EXPORT)
- /* We do not try to export internal symbols on Visual Studio */
-# define HB_INTERNAL
-#else
-# define HB_INTERNAL
-# define HB_NO_VISIBILITY 1
-# endif
-#endif
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1651 */
-#if defined(__clang__) && __clang_major__ < 10
-#define static_const static
-#else
-#define static_const static const
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#define HB_FUNC __PRETTY_FUNCTION__
-#elif defined(_MSC_VER)
-#define HB_FUNC __FUNCSIG__
-#else
-#define HB_FUNC __func__
-#endif
-
-#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
-/* https://github.com/harfbuzz/harfbuzz/issues/630 */
-#define __restrict
-#endif
-
-/*
- * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
- * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
- * cases that fall through without a break or return statement. HB_FALLTHROUGH
- * is only needed on cases that have code:
- *
- * switch (foo) {
- * case 1: // These cases have no code. No fallthrough annotations are needed.
- * case 2:
- * case 3:
- * foo = 4; // This case has code, so a fallthrough annotation is needed:
- * HB_FALLTHROUGH;
- * default:
- * return foo;
- * }
- */
-#if defined(__clang__) && __cplusplus >= 201103L
- /* clang's fallthrough annotations are only available starting in C++11. */
-# define HB_FALLTHROUGH [[clang::fallthrough]]
-#elif defined(__GNUC__) && (__GNUC__ >= 7)
- /* GNU fallthrough attribute is available from GCC7 */
-# define HB_FALLTHROUGH __attribute__((fallthrough))
-#elif defined(_MSC_VER)
- /*
- * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
- * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
- */
-# include <sal.h>
-# define HB_FALLTHROUGH __fallthrough
-#else
-# define HB_FALLTHROUGH /* FALLTHROUGH */
-#endif
-
-/* A tag to enforce use of return value for a function */
-#if __cplusplus >= 201703L
-# define HB_NODISCARD [[nodiscard]]
-#elif defined(__GNUC__) || defined(__clang__)
-# define HB_NODISCARD __attribute__((warn_unused_result))
-#elif defined(_MSC_VER)
-# define HB_NODISCARD _Check_return_
-#else
-# define HB_NODISCARD
-#endif
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1852 */
-#if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
-/* Disable certain sanitizer errors. */
-/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
-#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
-#else
-#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
-#endif
-
-
-#ifdef _WIN32
- /* We need Windows Vista for both Uniscribe backend and for
- * MemoryBarrier. We don't support compiling on Windows XP,
- * though we run on it fine. */
-# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
-# undef _WIN32_WINNT
-# endif
-# ifndef _WIN32_WINNT
-# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-# define _WIN32_WINNT 0x0600
-# endif
-# endif
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN 1
-# endif
-# ifndef STRICT
-# define STRICT 1
-# endif
-
-# if defined(_WIN32_WCE)
- /* Some things not defined on Windows CE. */
-# define vsnprintf _vsnprintf
-# ifndef HB_NO_GETENV
-# define HB_NO_GETENV
-# endif
-# if _WIN32_WCE < 0x800
-# define HB_NO_SETLOCALE
-# define HB_NO_ERRNO
-# endif
-# elif !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-# ifndef HB_NO_GETENV
-# define HB_NO_GETENV
-# endif
-# endif
-# if defined(_MSC_VER) && _MSC_VER < 1900
-# define snprintf _snprintf
-# endif
-#endif
-
-#ifdef HB_NO_GETENV
-#define getenv(Name) nullptr
-#endif
-
-#ifndef HB_NO_ERRNO
-# include <cerrno>
-#else
-static int HB_UNUSED _hb_errno = 0;
-# undef errno
-# define errno _hb_errno
-#endif
-
-#define HB_STMT_START do
-#define HB_STMT_END while (0)
-
-#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
-/* atexit() is only safe to be called from shared libraries on certain
- * platforms. Whitelist.
- * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
-# if defined(__linux) && defined(__GLIBC_PREREQ)
-# if __GLIBC_PREREQ(2,3)
-/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
-# define HB_USE_ATEXIT 1
-# endif
-# elif defined(_MSC_VER) || defined(__MINGW32__)
-/* For MSVC:
- * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
- * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
- * mingw32 headers say atexit is safe to use in shared libraries.
- */
-# define HB_USE_ATEXIT 1
-# elif defined(__ANDROID__)
-/* This is available since Android NKD r8 or r8b:
- * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
- */
-# define HB_USE_ATEXIT 1
-# elif defined(__APPLE__)
-/* For macOS and related platforms, the atexit man page indicates
- * that it will be invoked when the library is unloaded, not only
- * at application exit.
- */
-# define HB_USE_ATEXIT 1
-# endif
-#endif /* defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) */
-#ifdef HB_NO_ATEXIT
-# undef HB_USE_ATEXIT
-#endif
-#ifndef HB_USE_ATEXIT
-# define HB_USE_ATEXIT 0
-#endif
-#ifndef hb_atexit
-#if !HB_USE_ATEXIT
-# define hb_atexit(_) HB_STMT_START { if (0) (_) (); } HB_STMT_END
-#else /* HB_USE_ATEXIT */
-# ifdef HAVE_ATEXIT
-# define hb_atexit atexit
-# else
- template <void (*function) (void)> struct hb_atexit_t { ~hb_atexit_t () { function (); } };
-# define hb_atexit(f) static hb_atexit_t<f> _hb_atexit_##__LINE__;
-# endif
-#endif
-#endif
-
-
-// Locale business
-
-#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE))
-#define HB_NO_SETLOCALE 1
-#endif
-
-#ifndef HB_NO_SETLOCALE
-
-#include <locale.h>
-#ifdef HAVE_XLOCALE_H
-#include <xlocale.h> // Needed on BSD/OS X for uselocale
-#endif
-
-#ifdef WIN32
-#define hb_locale_t _locale_t
-#else
-#define hb_locale_t locale_t
-#endif
-#define hb_setlocale setlocale
-#define hb_uselocale uselocale
-
-#else
-
-#define hb_locale_t void *
-#define hb_setlocale(Category, Locale) "C"
-#define hb_uselocale(Locale) ((hb_locale_t) 0)
-
-#endif
-
-
-/* Lets assert int types. Saves trouble down the road. */
-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), "");
-
-
-/* Pie time. */
-// https://github.com/harfbuzz/harfbuzz/issues/4166
-#define HB_PI 3.14159265358979f
-#define HB_2_PI (2.f * HB_PI)
-
-
-/* Headers we include for everyone. Keep topologically sorted by dependency.
- * They express dependency amongst themselves, but no other file should include
- * them directly.*/
-#include "hb-cplusplus.hh"
-#include "hb-meta.hh"
-#include "hb-mutex.hh"
-#include "hb-number.hh"
-#include "hb-atomic.hh" // Requires: hb-meta
-#include "hb-null.hh" // Requires: hb-meta
-#include "hb-algs.hh" // Requires: hb-meta hb-null hb-number
-#include "hb-iter.hh" // Requires: hb-algs hb-meta
-#include "hb-debug.hh" // Requires: hb-algs hb-atomic
-#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
-#include "hb-vector.hh" // Requires: hb-array hb-null
-#include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector
-
-#endif /* HB_HH */
diff --git a/src/gui/configure.json b/src/gui/configure.json
index ed6e419f490..7b80162faa5 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -1096,33 +1096,6 @@
"pkg-config-variable": "prefix",
"value": "/usr",
"log": "value"
- },
- "harfbuzz-ng": {
- "label": "Harfbuzz NG",
- "type": "compile",
- "test": {
- "head": [
- "#ifdef __APPLE__",
- " #include <AvailabilityMacros.h>",
- "#endif",
- "#include <stdio.h>"
- ],
- "main": [
- "// Harfbuzz-NG disabled on certain platforms where newer versions do not",
- "// compile. This list is not exhaustive and only based on experimentation.",
- "#ifdef _MSC_VER",
- " printf(\" msc ver: %d \", _MSC_VER);",
- "#endif",
- "#if defined(__QNX__) \\",
- " || (defined(MAC_OS_X_VERSION_10_6) && !defined(MAC_OS_X_VERSION_10_15)) \\",
- " || (defined(_MSC_VER) && _MSC_VER <= 1900) \\",
- " || (defined(__INTEGRITY) && __INTEGRITY_MAJOR_VERSION <= 11) \\",
- " || (defined(__ICC) && __ICC <= 1910) \\",
- " || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)",
- "# error Harfbuzz-NG cannot be used on this platform",
- "#endif"
- ]
- }
}
},
@@ -1250,7 +1223,6 @@
},
"harfbuzz": {
"label": "HarfBuzz",
- "condition": "tests.harfbuzz-ng || (!config.darwin && !config.win32 && libs.harfbuzz) || (input.harfbuzz == 'system')",
"output": [ "privateFeature", "feature" ]
},
"system-harfbuzz": {
diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
index 81529cbefcc..6fe3e200835 100644
--- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
+++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
@@ -361,10 +361,6 @@ void tst_QFontMetrics::elidedMetrics()
void tst_QFontMetrics::zeroWidthMetrics()
{
-#if defined(QT_NO_HARFBUZZ)
- QSKIP("Test unreliable without Harfbuzz-NG");
-#endif
-
QString zwnj(QChar(0x200c));
QString zwsp(QChar(0x200b));
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
index 6f0d84bb77f..05f4a385947 100644
--- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
+++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
@@ -632,9 +632,6 @@ void tst_QGlyphRun::multiLineBoundingRect()
void tst_QGlyphRun::defaultIgnorables()
{
-#if defined(QT_NO_HARFBUZZ)
- QEXPECT_FAIL("", "Ignorables handled differently by old Harfbuzz and Harfbuzz-NG", Abort);
-#endif
QTextLayout layout;
layout.setFont(QFont("QtsSpecialTestFont"));
layout.setText(QChar(0x200D));
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index 5aa33a50a59..0371f519611 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -1239,13 +1239,14 @@ void tst_QTextScriptEngine::thaiWithZWJ()
QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type
//A quick sanity check - check all the characters are individual clusters
- // A thai implementation could either remove the ZWJ character, or hide it.
- // The current implementation merges the cluster for ZWJ and keeps ZWNJ, so we test for that.
+ // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them.
+ // The current implementation hides them, so we test for that.
unsigned short *logClusters = e->layoutData->logClustersPtr;
QCOMPARE(logClusters[0], ushort(0));
QCOMPARE(logClusters[1], ushort(0));
QCOMPARE(logClusters[2], ushort(2));
- for (int i = 3; i < 15; i++)
+ QCOMPARE(logClusters[3], ushort(2));
+ for (int i = 4; i < 15; i++)
QCOMPARE(logClusters[i], ushort(i));
for (int i = 0; i < 3; i++)
QCOMPARE(logClusters[i+15], ushort(0));