Compare commits

...

543 Commits

Author SHA1 Message Date
Behdad Esfahbod d1c00c0470 [COLR] Respect HB_NO_PAINT
Fixes https://github.com/harfbuzz/harfbuzz/issues/4204
2023-04-24 13:24:47 -06:00
Behdad Esfahbod 4129061e37 Revert "Move hb-ot-name-language-static.hh out of hb-static.cc"
This reverts commit 7b5f0dd3a8.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4203
2023-04-24 13:04:05 -06:00
Behdad Esfahbod e76a3649db [atomic] Comment 2023-04-22 10:20:25 -06:00
Behdad Esfahbod 8e43e3a8ce [priority-heap] Comment 2023-04-22 10:16:43 -06:00
Behdad Esfahbod 48f8ed7e02 Docs 2023-04-22 10:14:01 -06:00
Behdad Esfahbod b31684dca4 [cache] Add some AI-generated comments 2023-04-22 09:47:58 -06:00
Behdad Esfahbod bffdca89f7 [pool] Add funny Copilot comment 2023-04-22 09:32:57 -06:00
Behdad Esfahbod a960571f24 [glyf] Comments 2023-04-21 16:45:08 -06:00
Behdad Esfahbod 2b042cc5c6 [VarComposite] Implement trim_padding() 2023-04-21 16:43:47 -06:00
Qunxin Liu 591c9460dc [instancer] compile composite glyphs directly with shifted component
points instead of deltas
2023-04-21 15:47:26 -06:00
Behdad Esfahbod 3520f528aa [CompositeGlyph] Apply gvar deltas with component transform
This was being done wrong for one of the scaled_offsets() cases.
2023-04-21 15:46:36 -06:00
Behdad Esfahbod 33972b3bf6 [glyf] Increase CompositeGlyf memory allocation
The 50% wasn't justified by logic.
2023-04-21 12:37:51 -06:00
Behdad Esfahbod 290cef39be [glyf] When instancing, just spew empty VarComposites
Before we were dropping the entire glyf table.
2023-04-21 12:22:30 -06:00
Behdad Esfahbod 4353192d05 [aat] Tweak a couple sanitize calls that are never called 2023-04-21 11:59:15 -06:00
Behdad Esfahbod 305012609b [hdmx] Remove unused unsafe function 2023-04-21 11:42:18 -06:00
Behdad Esfahbod f74abc307d [face] Comment 2023-04-21 11:37:37 -06:00
Behdad Esfahbod d1f49ba6d2 [VarComposites] More ifdef guards 2023-04-20 18:17:14 -06:00
Behdad Esfahbod 1e9a0511f3 [subset] Fix HB_TINY build 2023-04-20 17:47:04 -06:00
Behdad Esfahbod 106a237e40 [subset/glyf] Close over VarComposite glyphs
Subsetting VarComposite glyphs works now.
2023-04-20 17:46:07 -06:00
Behdad Esfahbod f2d21425a3 [VarC/subset] Support subsetting VarComposites
By renumbering components.
2023-04-20 17:32:59 -06:00
Behdad Esfahbod 15d0a1dcfd [glyf] TODO 2023-04-20 17:28:10 -06:00
Behdad Esfahbod 85d0c3b5f1 [glyf] Comment 2023-04-20 17:17:28 -06:00
Behdad Esfahbod 5d74b42b9e [glyf] Change variable name 2023-04-20 17:15:57 -06:00
Behdad Esfahbod c997e490c7 Remove unnecessary return 2023-04-20 17:02:38 -06:00
Behdad Esfahbod 781da13e99 [glyf] Comment 2023-04-20 16:59:25 -06:00
Behdad Esfahbod 0e4bcf908c [hmtx] Add TODO 2023-04-20 16:23:41 -06:00
Behdad Esfahbod 639f45ef9e [beyond-64k/subset] Implement subsetting of hmtx beyond64k 2023-04-20 16:21:08 -06:00
Behdad Esfahbod b3da715b9c Fix HB_TINY build 2023-04-20 16:05:03 -06:00
Behdad Esfahbod 32f145ff9c Fix build 2023-04-20 15:58:26 -06:00
Behdad Esfahbod 000a3c5dca [beyond-64k/subset] Fetch lsb from glyph table if not available
The beyond-64k hmtx table doesn't encode LSB. If subsetting brings
the glyph under 64k (which currently is the only mode we support),
then we need to encode the LSB, which wasn't available. We need to
fetch xMin from glyf table and set it as LSB.
2023-04-20 15:53:10 -06:00
Behdad Esfahbod 1111c7578e hb_memset 2023-04-20 15:17:23 -06:00
Behdad Esfahbod 219e739c9f [beyond-64k/subset] Lower CompositeGlyph GID24's when possible 2023-04-20 15:13:12 -06:00
Behdad Esfahbod a2e8ecf996 [Glyph] Minor change type of type to enum type
Say that thrice.
2023-04-20 14:08:23 -06:00
Behdad Esfahbod 317e3693da [beyond-64k] Fail hmtx subsetting if subset too large 2023-04-20 11:48:43 -06:00
Behdad Esfahbod 64ecf8720c [beyond-64k] Fix subsetting of maxp 2023-04-20 11:42:45 -06:00
Behdad Esfahbod 7f629c0df2 [docs] clarify purpose of FreeType integration
Fixes https://github.com/harfbuzz/harfbuzz/issues/4200
2023-04-19 13:16:18 -06:00
Garret Rieger 19e1b698c5 [subset] Fix ubsan failure. 2023-04-18 13:21:46 -06:00
Garret Rieger 647b024784 [subset] Fix fuzzer issue https://oss-fuzz.com/testcase-detail/6521393809588224 2023-04-18 13:21:46 -06:00
Garret Rieger 3db6baa20e [subset] add test for lig glyph fix. 2023-04-17 14:35:27 -06:00
Garret Rieger 8658c257c4 [subset] In LigatureSubst subsetting, check if the ligature glyph is in glyphset.
Otherwise coverage will not match the retained ligature sets.
2023-04-17 14:35:27 -06:00
Josef Friedrich ac4c3b3e85 Fix typos in the source code docs 2023-04-17 12:21:05 -06:00
DeadSix27 ef6adadba9 meson: add an option to disable utilities building
Adds the missing utilities option to meson builds for parity with CMake builds
2023-04-17 18:55:38 +02:00
Garret Rieger 90356eb226 [subset] Note --no-layout-closure is only for GSUB. 2023-04-14 15:12:41 -06:00
Garret Rieger 14b9d8d534 [subset] add --no-layout-closure flag.
Disables layout glyph closure. Fixes #4192.
2023-04-14 15:12:41 -06:00
Behdad Esfahbod 9c258936e7 [SECURITY] Update 2023-04-14 11:35:34 -06:00
Pedro Kaj Kjellerup Nacht feb1f6d39e Add security policy
Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
2023-04-14 11:34:06 -06:00
Pedro Kaj Kjellerup Nacht 26c719e8cd Add read-only top-level permissions to cifuzz.yml
Signed-off-by: Pedro Kaj Kjellerup Nacht <pnacht@google.com>
2023-04-12 10:23:20 -06:00
Qunxin Liu 96ed20725c [instancer] update bound metrics for CFF2 instancing 2023-04-05 17:27:11 -06:00
Behdad Esfahbod 04a47932a3 [paint] Remove enum trailing comma in C header
Fixes https://github.com/harfbuzz/harfbuzz/discussions/4188
2023-03-31 11:44:08 -06:00
Garret Rieger 2cd81fdfb6 [subset] fix memory leak.
Fixes fuzzer issue https://oss-fuzz.com/testcase-detail/6169920089227264
2023-03-30 16:19:41 -06:00
Behdad Esfahbod 453ded0539 [indic] Tighten up base-finding
Fixes https://github.com/harfbuzz/harfbuzz/issues/4185
2023-03-28 13:18:03 -06:00
Qunxin Liu c1acfe9966 [instancer] bug fix in TupleVariationData get_size ()
We need to iterate TupleVariationHeader when calculating the total size
2023-03-27 15:37:06 -06:00
Garret Rieger be87200106 [subset] fix buffer overflow fuzzer reported issue. 2023-03-25 10:11:46 -04:00
Garret Rieger 79ae6b657f [subset] Fix fuzzer found memory leaks. 2023-03-25 10:11:46 -04:00
Qunxin Liu ab87d7d225 [instance] add tests for colrv1 full instancing 2023-03-21 11:51:58 -06:00
Qunxin Liu fe671a5ac8 [instancer] support COLRv1 full instancing 2023-03-21 11:51:58 -06:00
Garret Rieger f0f7f22525 [subset] fix fuzzer found null deref.
https://oss-fuzz.com/testcase-detail/5844352760152064
2023-03-21 11:41:09 -06:00
Garret Rieger 79233a1492 [subset] fix incorrectly specified lock.
Lock variable must have a name or it will immediately destruct.
2023-03-16 20:30:39 -06:00
Garret Rieger 8d8bcde8cf [set] don't allow -1 (HB_SET_VALUE_INVALID) to be inserted into a hb_set_t.
Add tests that check all of the addition methods.
2023-03-15 12:10:18 -06:00
Garret Rieger a84cae424d [subset] Don't add invalid gids (-1) to the glyphset when loading glyph map from the accelerator. 2023-03-15 12:10:18 -06:00
Behdad Esfahbod 09a2662361
Merge pull request #4168 from googlefonts/subset_name_collect
[subset] name_id closure
2023-03-14 12:48:12 -06:00
Behdad Esfahbod 75e6498d9a Don't use M_PI
Fixes https://github.com/harfbuzz/harfbuzz/issues/4166

Happy Pi Day!
2023-03-14 12:41:46 -06:00
Qunxin Liu 204e155acb [subset] Add tests for collecting name_ids from STAT and FeatureParams 2023-03-14 10:25:31 -07:00
Jason Simmons 32c889f1d6 Remove extra blank line in hb-outline.cc 2023-03-13 20:35:59 -06:00
Qunxin Liu 0d65738633 [subset] collect elidedFallbackNameID in STAT table 2023-03-13 15:51:45 -07:00
Qunxin Liu 125450d2f2 [subset] collect name_ids for FeratureParams 2023-03-13 15:43:29 -07:00
Garret Rieger 663ecc01d8 [subset] don't free glyphs by range.
The iterator in this loop is a map iterator so glyphs are not necessarily traveresed in order.
2023-03-13 16:32:59 -06:00
Garret Rieger 3d05b96181 [subset] track which glyphs have allocated memory so we can clean up correctly.
Fixes https://oss-fuzz.com/testcase-detail/5388270411579392
2023-03-13 16:03:58 -06:00
Garret Rieger 7a87b17742 Check for failed subset input creation in the fuzzer. 2023-03-13 15:21:25 -06:00
Qunxin Liu de6533d885 [subset] collect name_ids from CPAL table 2023-03-13 13:36:00 -07:00
Qunxin Liu 7b77cd198c [subset] fix bug in CPAL V1tail serialization
We should serialize nameIDs rather than retained color index
2023-03-13 12:51:46 -07:00
Behdad Esfahbod 6d2705a719 [justify-demo] Help message 2023-03-10 12:40:57 -07:00
Simon Cozens 2d8634624c Add Tifinagh to list of both-directions scripts 2023-03-10 10:55:11 -07:00
Jean-Michaël Celerier 905eeee4a4 harfbuzz-config.cmake: support static library build 2023-03-09 20:31:39 +02:00
Garret Rieger 28b05e1cb6 [subset] Fix memory leak in glyf subset.
Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/6525813890875392.
2023-03-08 17:02:04 -07:00
Garret Rieger 9286e12525 Don't subset a glyf table with an unknown format.
Fixes fuzzer issue: https://oss-fuzz.com/testcase-detail/4875306193518592
2023-03-08 14:51:54 -07:00
Behdad Esfahbod cfa9541daa [glyf] "Support" glyf version 1 2023-03-08 10:35:39 -07:00
Behdad Esfahbod 552290f604 [gvar] Fix out-of-memory access issue
Fixes https://oss-fuzz.com/testcase-detail/5953342850596864
2023-03-08 10:25:26 -07:00
Behdad Esfahbod 7327006d68 [GSUB] Support SingleSubst in get_glyph_alternates
Fixes https://github.com/harfbuzz/harfbuzz/discussions/4146
2023-03-07 21:06:01 -07:00
Behdad Esfahbod 69183217df Add test-gsub-get-alternates.cc 2023-03-07 20:56:56 -07:00
Behdad Esfahbod ea17c7a81a [beyond-64k] Implement gvar support
https://github.com/harfbuzz/boring-expansion-spec/issues/85
2023-03-07 14:23:39 -07:00
Behdad Esfahbod f325aba561 [VarComposites] Minor rename 2023-03-06 13:07:42 -07:00
Khaled Hosny b4b089c427 [docs] Disable gtdoc-check by default
It slows build as it causes documentation to be always rebuilt. We now
disable it by default and enable it on relevant CI jobs.
2023-03-06 06:06:06 +02:00
Behdad Esfahbod d165afec1d [justify-demo] Create new fonts all the time
The hb.shape_justify() call modifies the font. This was messing
up justification. Create new fonts all the time.
2023-03-04 21:09:26 -07:00
Khaled Hosny 690145fa00 [justify-demo] Rewrite in a simpler way
No need to overthink it, append text words to the line and reshape, no
need to shape the whole text first and do complicated glyph/input
mapping. Much simpler code and as fast.
2023-03-04 07:19:20 +02:00
Behdad Esfahbod e9d6f23b5d [justify-demo] Fix for LTR typesetting 2023-03-03 17:15:18 -07:00
Behdad Esfahbod 5cf54aedde [justify-demo] Guess segment properties 2023-03-03 17:01:12 -07:00
Behdad Esfahbod 5c334b9686 [justify-demo] Fix crash if font has no variation axis 2023-03-03 16:53:44 -07:00
Behdad Esfahbod ab249fd24b [justify] Fix shrink/expand conditions 2023-03-04 01:46:07 +02:00
Khaled Hosny 039ea9adda [justify] Add demo GTK app 2023-03-04 01:44:01 +02:00
Behdad Esfahbod be47182d48 [hb-cairo] Add Black Foundry copyright 2023-03-03 11:10:16 -07:00
Behdad Esfahbod ab4c321180 [justify] Set out params in more cases 2023-03-03 09:31:16 -07:00
Khaled Hosny e57defc07c [justify] Set var_value when expanding/shrinking to max
When expanding/shrinking the buffer to max (and still not fitting), we
need to also set var_value to the axis max/min otherwise client not have
the correct axis value to draw with.
2023-03-03 09:20:29 -07:00
Behdad Esfahbod a2efa5b489 [map] Another try at fixing old Mac build
https://github.com/harfbuzz/harfbuzz/issues/4138
2023-03-03 09:15:46 -07:00
Khaled Hosny bfab56d3b5 [font] Typo 2023-03-03 13:14:05 +02:00
Khaled Hosny 60841e2618 7.1.0 2023-03-03 01:05:43 +02:00
Qunxin Liu e471ef77f9 [instancer] fix a runtime error
runtime error: -1 is outside the range of representable values of type 'unsigned int'
2023-03-02 14:13:17 -07:00
Behdad Esfahbod 43dbdd9db6 [justify] Document algorithm 2023-03-02 13:42:52 -07:00
Behdad Esfahbod c98bb4cf9c [justify] Fix up after recent changes
Oops.
2023-03-02 13:18:06 -07:00
Behdad Esfahbod fb067390e4 [docs] Fix a warning 2023-03-02 11:40:45 -07:00
Behdad Esfahbod fe83736e26 [sanitize] Protect against an underflow 2023-03-02 11:35:42 -07:00
Behdad Esfahbod 08784baf10 [GSUB/GPOS] Fix sanitization in Format1
Fixes https://oss-fuzz.com/testcase-detail/5120727025319936
2023-03-02 10:48:30 -07:00
Behdad Esfahbod 7897173870 [justify] Fix compiler warnings 2023-03-02 10:38:12 -07:00
Behdad Esfahbod be64cae164 [map] Another try at fixing old Mac builds
Maybe fixes https://github.com/harfbuzz/harfbuzz/issues/4138
2023-03-02 09:50:38 -07:00
Behdad Esfahbod 67e01c1292 [map] Try to work around old Mac compiler bug
Maybe fixes https://github.com/harfbuzz/harfbuzz/issues/4138
2023-03-01 20:08:17 -07:00
Khaled Hosny e359f46a20 Fix build 2023-03-02 03:06:53 +02:00
Behdad Esfahbod e8f94f9e12
Merge pull request #4144 from harfbuzz/justify
Justify
2023-03-01 16:34:01 -07:00
Behdad Esfahbod 6de9d2b89f [justify] Rename hb-view --width to hb-view --justify-to 2023-03-01 14:32:06 -07:00
Behdad Esfahbod 25c66d633d [justify] Wrap in HB_EXPERIMENTAL_API 2023-03-01 14:23:12 -07:00
Behdad Esfahbod 96d4ed0931 [justify] Document API 2023-03-01 14:23:12 -07:00
Behdad Esfahbod d29d7b7a3d [algs] Adjust solve_itp 2023-03-01 14:23:12 -07:00
Behdad Esfahbod aa10deaf42 [justify] Print default buffer width in hb-shape --width=-1 2023-03-01 14:23:12 -07:00
Behdad Esfahbod 93252c6fc3 [justify] Debug output 2023-03-01 14:23:12 -07:00
Behdad Esfahbod b937edfb14 [justify] Add min/max target_width
Speeds up solving when some slack available.
2023-03-01 14:23:12 -07:00
Behdad Esfahbod 6e483c4061 [shape] Add hb_shape_justify() and hb-view --width 2023-03-01 14:23:12 -07:00
Behdad Esfahbod ee4822f969 [algs] Add solve_itp method
Port from kurbo.
2023-03-01 14:23:12 -07:00
Behdad Esfahbod c67c0086ef [GPOS] Fix indexing in MarkLigPos
This was broken in 8708b9e081.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4142
2023-03-01 13:32:44 -07:00
Matthias Clasen 01d34763f0 Typo fix 2023-03-01 10:11:47 -07:00
Behdad Esfahbod 2d33a6b4df [subset-fuzzer] Protect against overflow
Fixes
https://github.com/harfbuzz/harfbuzz/issues/4137#issuecomment-1448994447
2023-02-28 15:31:45 -07:00
Behdad Esfahbod 5226d69733 [font] Make set_variation() respect currently-set variations
Fixes https://github.com/harfbuzz/harfbuzz/issues/4143
2023-02-28 14:50:07 -07:00
Behdad Esfahbod 91627daee2 [outline] Rename internal function 2023-02-28 14:31:25 -07:00
Behdad Esfahbod 5c46286592 Revert "."
This reverts commit 59434578cd.
2023-02-28 12:16:46 -07:00
Behdad Esfahbod 59434578cd . 2023-02-28 12:13:55 -07:00
Behdad Esfahbod bbb9d6d436 [font] Add hb_font_set_variation() 2023-02-28 12:08:11 -07:00
Qunxin Liu a975ec4842 [instancer] apply cvar deltas 2023-02-27 17:05:23 -07:00
Qunxin Liu 8b0c7b9554 [instance] Add struct definition for cvar table
Also add functions to add cvt tables with cvar deltas applied
2023-02-27 17:05:23 -07:00
Qunxin Liu 22cc73f3e9 Move common structs for TupleVariation from gvar to var-common.hh
Also added a table_base in the iterator and related function to handle
different start address for dataoffset in cvar and gvar
2023-02-27 17:05:23 -07:00
Garret Rieger c0fac016dc [subset] update the subset fuzzer to be able to reach instancing code. 2023-02-27 15:07:04 -07:00
Behdad Esfahbod 62fc27f372 [ft] Enlarge glyph-cache value-size again
8bits just doesn't do it. It has caused cache-hammering and high
CPU usage when the font is hinted.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4139
2023-02-27 11:21:32 -07:00
Behdad Esfahbod 921eca3e79 [autotools] Fix hb-info chafa build 2023-02-24 17:07:01 -07:00
Behdad Esfahbod 209f63b785 [TINY] Fix config issue 2023-02-24 16:03:40 -07:00
Qunxin Liu 605aed0544 [instancer] bug fix in post table applying mvar deltas 2023-02-24 13:19:37 -07:00
Garret Rieger 918193ebf9 [subset] fix a class of fuzzer timeouts caused by large shared coverage tables.
More acurately estimates the op count for CoverageFormat2 tables as the population size instead of the size in bytes.
2023-02-22 16:57:39 -07:00
Garret Rieger ddd0f7f40b [subset] Add a test for CFF2 instancing.
Adds option to disable the fonttools comparison check in the test. This is needed since CFF2 instancing is not yet supported in fonttools.
2023-02-22 14:12:55 -07:00
Behdad Esfahbod 33cc3121d4 Comment 2023-02-22 12:03:30 -07:00
Behdad Esfahbod 5bc6ab006d Use __has_builtin for builtin checks instead of compiler versions
https://github.com/harfbuzz/harfbuzz/issues/4066#issuecomment-1439510188
2023-02-22 08:54:18 -07:00
Behdad Esfahbod 6b286cfabf [cubic-glyf] Remove stale comment 2023-02-21 16:15:45 -07:00
Behdad Esfahbod 22b9315628 [cubic-glyf] Handle wrap-around cubic off-curves 2023-02-21 15:50:55 -07:00
Behdad Esfahbod 050f5a58fe [cubic-glyf] Handle contour-initial cubic offcurves 2023-02-21 15:26:27 -07:00
Khaled Hosny 9c27fe625f Revert "[doc] Fix a couple of gtk-doc warnings"
This reverts commit ed42b2fcb5.
2023-02-21 23:25:14 +02:00
Khaled Hosny ed42b2fcb5 [doc] Fix a couple of gtk-doc warnings 2023-02-21 23:08:15 +02:00
Khaled Hosny 0575229477 [blob] Typo in documentation 2023-02-21 18:07:53 +02:00
Khaled Hosny 424f5f2c0d [ci] Don’t build docs while building Windows binaries 2023-02-20 16:05:53 +02:00
Khaled Hosny 1d1f93a612 7.0.1 2023-02-20 15:54:12 +02:00
Behdad Esfahbod 6db871eb3a
Merge pull request #4126 from harfbuzz/cff2-instancer
CFF2 instancer make ots-sanitize happy
2023-02-19 21:08:14 -07:00
Behdad Esfahbod 5b50b07717 [subset-cff] Make BCD writing locale-independent 2023-02-19 20:39:01 -07:00
Behdad Esfahbod 4a735b30c4 [cff2-subset] Update test 2023-02-19 20:39:01 -07:00
Behdad Esfahbod 21ff66cbd4 [subset-cff2] Round blended Private values when instancing
Hopefully no one blends BlueScale...
2023-02-19 20:39:01 -07:00
Behdad Esfahbod a4b7033d01 [cff2-subset] Blend Private values when instancing 2023-02-19 20:39:01 -07:00
Behdad Esfahbod f10a4c9d6a [cff] Rename encode_num to encode_num_cs 2023-02-19 20:39:01 -07:00
Behdad Esfahbod c65eb5a82e [cff] Specialize cff_private_dict_op_serializer_t for CFF1/2 2023-02-19 20:39:01 -07:00
Behdad Esfahbod bf4b34e87e [subset-cff2] Don't encode vsindex in Private dict 2023-02-19 20:39:01 -07:00
Behdad Esfahbod 220caa7e09 [subset-cff2] Only encode VarStore link if any varstore 2023-02-19 20:39:01 -07:00
Behdad Esfahbod 82d9940a93 [subset-cff2] Don't encode vsindex if pinned 2023-02-19 20:39:01 -07:00
Behdad Esfahbod a88f3e8d37 [subset-cff2] Don't serialize VarStore if pinned 2023-02-19 20:39:01 -07:00
Behdad Esfahbod 8c1b47d7e2 [font] Fix compiler warnings 2023-02-19 20:38:43 -07:00
Behdad Esfahbod 7c74fc9631 [CFF] Remove unused member single_val 2023-02-19 14:43:31 -07:00
Behdad Esfahbod 2746597b69 [subset-cff2] Add flush_hintmask
Fixes https://github.com/harfbuzz/harfbuzz/issues/4125
2023-02-19 12:15:22 -07:00
Behdad Esfahbod adccc5355b [MarkBase] Adjust base-finding logic
Fixes https://github.com/harfbuzz/harfbuzz/issues/4124
2023-02-17 12:29:42 -07:00
Behdad Esfahbod 946477fa54 [font] Fix a MSVC "error"
Oh well.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4122
2023-02-16 15:04:49 -07:00
Behdad Esfahbod b41efb6c4d [atomic] Use no-op asm for compiler barrier
Fixes https://github.com/harfbuzz/harfbuzz/pull/4119
2023-02-13 21:45:20 -07:00
Khaled Hosny 2f1aa032b4 [doc] Give this section a nice URL 2023-02-13 09:50:04 +02:00
Khaled Hosny 552f0714e8 [meson] Fix test failure with experimental_api
Pass --experimental-api to all gen-def.py when generating all .def
files, not only harfbuzz.def.

Fixes https://github.com/harfbuzz/harfbuzz/issues/4117
2023-02-13 09:41:51 +02:00
Behdad Esfahbod 40fa046cf3 [hb-info] Declare a variable unused
Fixes https://github.com/harfbuzz/harfbuzz/issues/4115
2023-02-12 10:54:46 -07:00
Khaled Hosny 8bdaeddfcd 7.0.0 2023-02-11 23:52:58 +02:00
Khaled Hosny df6324cbe7 [ci] Build with default wrap mode
Forcing fallback forces checking the subproject even if the option is
disabled.
2023-02-11 23:22:09 +02:00
Khaled Hosny 5b82fa91c5 [meson] Update Glib subproject 2023-02-11 23:22:09 +02:00
Khaled Hosny 31e099fd21 [meson] Update Cairo subproject 2023-02-11 23:22:09 +02:00
Khaled Hosny 8f0da5e5e6 [meson] Update FreeType subproject 2023-02-11 23:22:09 +02:00
Khaled Hosny 59cd1b17a9 [ci] Don’t build docs on macos-aat-fonts job
It fails ninja test, but superfluous anyway.
2023-02-11 20:59:44 +02:00
Khaled Hosny 7188c5643a [doc] Enable gtkdoc-check
Should catch the most blatant issues.
2023-02-11 20:59:44 +02:00
Khaled Hosny 0ea8bbd91a [doc] Use XSince for REPLACEME/EXPERIMENTAL
To hide them from gtk-doc so that we can finally enable gtkdoc-check.
2023-02-11 20:59:44 +02:00
Khaled Hosny 16dfd263b1 [subset] Remove docs for unimplemented flags
GTK-Doc does not like this.
2023-02-11 20:59:44 +02:00
Khaled Hosny 4d25941315 [doc] Fix hb_ot_name_[id|predefined]_t
Shuffle the docs around, so that the enum values appear in documentation
as they now belong to hb_ot_name_predefined_t. The Since field will be
misleading now, though.
2023-02-11 20:59:44 +02:00
Khaled Hosny 13741e68f8 [doc] Minor 2023-02-11 20:59:44 +02:00
Behdad Esfahbod ab191d9dc7 [ot-font] Minor division rounding 2023-02-11 09:31:21 -07:00
Behdad Esfahbod c6c1c6ddf1
Merge pull request #4107 from harfbuzz/cubic-glyf
[glyf] Support cubic curves
2023-02-11 09:20:51 -07:00
Behdad Esfahbod 6ddd490191 [path-builder] Comment re cubic 2023-02-10 14:24:03 -07:00
Behdad Esfahbod 91c2f098d0 [cubic-glyf] Add HB_NO_CUBIC_GLYF 2023-02-10 14:15:16 -07:00
Qunxin Liu af1e605be2 [instancer] bug fix
It's possible that length of all_points equals to 4 for non-empty
glyphs: a composite glyph which contains only one child glyph that is
empty.
2023-02-10 12:51:27 -07:00
Behdad Esfahbod 8302da8630
Merge pull request #4097 from harfbuzz/embolden
Embolden
2023-02-10 12:50:45 -07:00
Jens Kutilek 219e2f12f0 Clarify that those two test fonts are CC0-licensed 2023-02-10 10:06:28 -07:00
Pedro J. Estébanez b1680e9143 Use proper preprocessor checks for UWP 2023-02-10 09:39:40 -07:00
Behdad Esfahbod 96d9e8624c [docs] Improve cluster-level docs 2023-02-09 12:53:17 -07:00
Behdad Esfahbod 737b15c5a0 [embolden] Docs 2023-02-08 17:45:59 -07:00
Khaled Hosny 00a6f8945c [meson] Minor
alias_target() is variadic function.
2023-02-08 22:43:39 +02:00
Behdad Esfahbod 1d9dafbfd5 [glyf] Support cubic curves
https://github.com/harfbuzz/boring-expansion-spec/issues/41
2023-02-07 22:19:45 -07:00
Behdad Esfahbod 64fa5cd482 [GPOS] Fix assert fail introduced recently
Was introduced in 8708b9e081.

If these lookups are recursed to from (Chain)Context out-of-order,
it was possible that last_base > buffer->idx, in which case we
were attaching marks to a base after them... and an assertion
was failing fortunately.

Fixes https://oss-fuzz.com/testcase-detail/6377756666757120
2023-02-07 15:52:53 -07:00
Qunxin Liu 840e1b6b84 [instancer] bug fix 2023-02-07 15:49:12 -07:00
Behdad Esfahbod 3fd9311649 [indic] Use a hb_swap() 2023-02-07 14:16:24 -07:00
Behdad Esfahbod be1c14ee0a [embolden] Adjust font_h_extents 2023-02-07 13:52:53 -07:00
Behdad Esfahbod b350122fb3 [embolden] Fix glyph_extents in hb-ft 2023-02-07 13:49:16 -07:00
Behdad Esfahbod 61a1a88940 [hb-ft] Fix --font-grade 2023-02-07 13:47:04 -07:00
Behdad Esfahbod 560a65e456 [embolden] Update glyph_extents in hb-ot-font 2023-02-07 13:46:13 -07:00
Behdad Esfahbod aef002e0d9 [embolden] Add in-place option
Adds --font-grade to hb-view and hb-shape.
2023-02-07 11:52:25 -07:00
Behdad Esfahbod 0b92c57984 [meson] Add alias "libs" target
Builds libharfbuzz and libharfbuzz-subset.
2023-02-07 10:20:46 -07:00
Khaled Hosny 434c98d4c6 [meson] Add alias "lib" target
Fixes https://github.com/harfbuzz/harfbuzz/issues/4105
2023-02-07 10:06:13 +02:00
Behdad Esfahbod ce6440fceb [buffer] Speed up merge_clusters_impl 2023-02-06 16:12:03 -07:00
Behdad Esfahbod 1930760bc2 [buffer] Fix up previous commit
85be877925 (commitcomment-99547060)
2023-02-06 15:54:09 -07:00
Behdad Esfahbod 30b84faba7 [buffer] Optimize _infos_set_glyph_flags to avoid O(n^2) behavior
85be877925 (commitcomment-99547060)
2023-02-06 15:27:13 -07:00
Behdad Esfahbod 0b97ac39ac [buffer] Optimize _infos_find_min_cluster for monotone clusters 2023-02-06 15:17:09 -07:00
Behdad Esfahbod 8708b9e081 [GPOS] Avoid O(n^2) behavior in mark-attachment
Better implementation; avoids arbitrary limit on look-back.
2023-02-06 14:51:25 -07:00
Behdad Esfahbod 661050b465 Revert "[layout] Limit how far we skip when looking back"
This reverts commit 85be877925.
2023-02-06 13:09:14 -07:00
Behdad Esfahbod b29fbd16fa [gsubgpos] Refactor skippy_iter.match() 2023-02-06 13:09:14 -07:00
Behdad Esfahbod ef2a8f722f [VarComposite] Adjust for RESET_UNSPECIFIED_AXES semantic change
https://github.com/harfbuzz/boring-expansion-spec/issues/81
2023-02-06 12:04:16 -07:00
Behdad Esfahbod 474b99d122 [test-paint] Fix build without FreeType
Fixes https://github.com/harfbuzz/harfbuzz/issues/4103
2023-02-04 10:16:11 -07:00
Behdad Esfahbod d250fd979b [font] Docs 2023-02-02 15:51:22 -07:00
Behdad Esfahbod cf39d316d8 [outline] Add FreeType authors copyrights 2023-02-02 15:51:22 -07:00
Matthias Clasen 061f995845 [font] Document synthetic boldness APIs 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 2119eab69f [embolden] Adjust advance values 2023-02-02 15:51:22 -07:00
Behdad Esfahbod b087266e51 [ot-font] Conditionalize emboldening 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 36dcc9a432 [ot-font] Fix emboldening CFF 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 6b3fe8ac1b [embolden] Semi-handle with negative scales 2023-02-02 15:51:22 -07:00
Behdad Esfahbod e39104ba19 [font/util] Add emboldening API, --font-bold
Needs documentation.
2023-02-02 15:51:22 -07:00
Behdad Esfahbod 4247b78e31 [outline] Comment 2023-02-02 15:51:22 -07:00
Behdad Esfahbod ae522a1372 [embolden] Rename to hb-outline 2023-02-02 15:51:22 -07:00
Behdad Esfahbod fda2f6f64e [embolden] Shuffle under hb_outline_t 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 7774bccb48 [embolden] Renames 2023-02-02 15:51:22 -07:00
Behdad Esfahbod c06f95ebe1 [embolden] Move code 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 6b4a6fbedd [embolden] Add orientation detection 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 1817f18085 [embolden] Simplify recording-pen 2023-02-02 15:51:22 -07:00
Behdad Esfahbod 70149885a7 [font] Towards implementing emboldening 2023-02-02 15:51:22 -07:00
Behdad Esfahbod b5c68c1cf3 [codecov] Enable information patch mode 2023-02-02 15:51:13 -07:00
Garret Rieger fda200658e [subset] fix missing compiled glyph cleanup when serialization succeeds. 2023-02-02 15:25:37 -07:00
Behdad Esfahbod 9bd3259335 [cairo] Fix uninitialized value
Ouch!
2023-02-02 13:36:23 -07:00
Behdad Esfahbod 85be877925 [layout] Limit how far we skip when looking back
See comments.
2023-02-01 20:00:43 -07:00
Behdad Esfahbod d18fd3f7eb [layout] Comment 2023-01-31 16:28:49 -07:00
Behdad Esfahbod 7a4bd97e4a [layout] Build lookup accelerators lazily on-demand
Reduces memory consumption for large multi-script fonts
drastically.
2023-01-31 16:19:37 -07:00
Behdad Esfahbod 83353f13f4 [layout] Reduce memory use slightly
By using raw pointer instead of vector for subtable accelerator.

To be used for more memory saving by making subtable accelerators
lazy-loaded by shape-plans for large fonts.
2023-01-31 16:19:37 -07:00
Garret Rieger 2b6d74b42e [subset] for keep everything, don't drop any tables. 2023-01-31 11:16:53 -07:00
Behdad Esfahbod 277003d553 [ft] Fit advance cache into short int 2023-01-30 22:43:01 -07:00
Behdad Esfahbod a924bbcfce [atomic/cache] Add hb_atomic_short_t 2023-01-30 14:52:22 -07:00
Behdad Esfahbod e7a71ea15b [font] Docs 2023-01-30 11:21:08 -07:00
Behdad Esfahbod cb47dca74c [object] Handle mallocation error in set_user_data
Should make bots happy.
2023-01-29 10:57:29 -07:00
Behdad Esfahbod 548bad221c [user-data] Move methods to header file
No idea why they were in hb-static.
2023-01-29 10:11:40 -07:00
Behdad Esfahbod 02f79f60f2
Merge pull request #4092 from harfbuzz/more-cmap-cache
[ot-font] Use the cmap cache more
2023-01-29 09:36:46 -07:00
Behdad Esfahbod 784fe9ac67 [cmap] Simplify caching 2023-01-29 09:26:52 -07:00
Matthias Clasen a451aa5465 Add back a null check
This was accidentally dropped in the previous commit.
2023-01-29 11:25:28 -05:00
Behdad Esfahbod 6622e04aa1 [solver] Fix unused-variable error
223abd72b9
2023-01-29 09:06:52 -07:00
Matthias Clasen 318aa10708 [ot-font] Use the cmap cache more
Use the cmap cache for get_nominal_glyph and
get_variation_glyph as well. The first of these
is used a lot in pango.
2023-01-29 09:17:17 -05:00
Behdad Esfahbod 5da829eaf5 [font] Comments 2023-01-28 22:18:53 -07:00
Behdad Esfahbod 544dd9678c [font] Fix unlikely 2023-01-28 22:06:46 -07:00
Behdad Esfahbod c1d0daf5f1 [font] unlikely 2023-01-28 22:05:24 -07:00
Behdad Esfahbod 30ee7a21e1 [font] Typo 2023-01-28 21:48:52 -07:00
Matthias Clasen 04056d44e2 [layout] Optimize more buffer message calls
Continuation of da7b66c1f8.
2023-01-28 21:35:20 -07:00
Behdad Esfahbod f8a744d9d5 [ot-font] Add a cmap cache
Speeds up Roboto shaping by 7%, for 1kb per face.
2023-01-28 13:38:07 -07:00
Behdad Esfahbod 1b53ed3c41 [cache] Remove empty fini() 2023-01-28 13:38:07 -07:00
Behdad Esfahbod 115d572571 [cache] Add constructor 2023-01-28 13:38:07 -07:00
Khaled Hosny ae96295d67 Delete commented out include 2023-01-28 22:12:33 +02:00
Matthias Clasen 09b7fce857 Make includes relative 2023-01-28 12:09:45 -07:00
Matthias Clasen e25e4c9a52 Move GDEF table to src/OT/Layout/GDEF 2023-01-28 12:09:45 -07:00
Matthias Clasen f89fa6dcfe Move name table to src/OT/name 2023-01-28 12:09:45 -07:00
Matthias Clasen b8193357c1 [OT::Color] Drop unused includes 2023-01-28 09:54:30 -07:00
Behdad Esfahbod da7b66c1f8 [layout] Optimize buffer message calls
Those aren't exactly free. They were showing up in profiles.
2023-01-27 16:39:06 -07:00
Behdad Esfahbod 49d75ef331 [gsubgpos] Fix bug in cached ChainContextFormat2 application 2023-01-27 15:37:11 -07:00
Behdad Esfahbod d2279a204f [gsubgpos] Avoid a copy into the vector 2023-01-27 13:09:49 -07:00
Qunxin Liu 615595689c [subset/COLR] add tests for copying varStore 2023-01-27 12:21:52 -07:00
Behdad Esfahbod 0f33ea8c4f [subset/COLR] Copy VarStore
Fixes https://github.com/harfbuzz/harfbuzz/issues/4085
2023-01-27 11:26:57 -07:00
Khaled Hosny 6c46da7710 [test] Fix shell script quoting 2023-01-27 10:34:50 +02:00
Matthias Clasen c03c8548f4
Merge pull request #4084 from harfbuzz/cairo-check-funcs
[meson] Enable all checked for Cairo functions for internal Cairo
2023-01-26 23:17:11 -05:00
Khaled Hosny 7a714d1a8d [meson] Enable all checked for Cairo functions for internal Cairo
Similar to what we do with FreeType ones.
2023-01-27 03:16:54 +02:00
Behdad Esfahbod 950c7ab3f0 [gsubgpos] Use accelerator when recursing 2023-01-26 15:26:05 -07:00
Behdad Esfahbod e377888990 [ft-colr] Conditionalize on (unreleased0 FreeType 2.13.0
That's the version that the color API is called stable, and
includes changes that we rely on.
2023-01-26 13:27:55 -07:00
Behdad Esfahbod 281db89a68 [cairo] Try to handle failure in set_user_data 2023-01-26 13:05:12 -07:00
Behdad Esfahbod 2fede3ef4a [layout] Fix a return_trace 2023-01-26 12:56:17 -07:00
Behdad Esfahbod 05a2f31592
Merge pull request #4065 from harfbuzz/cairo-fix-foreground-color
hb-cairo: Fix handling of foreground color
2023-01-26 12:56:02 -07:00
Behdad Esfahbod e484d6b990 [cairo] Handle malloc failure 2023-01-26 12:55:25 -07:00
Behdad Esfahbod 29a36010a1 [cairo] Adapt to cairo foreground API change again 2023-01-26 14:32:25 -05:00
Matthias Clasen 30d0d9c56c Adapt to cairo changes
Adapt to the api in the cairo MR that will be used,
and make the code build with older cairo.
2023-01-26 14:32:25 -05:00
Behdad Esfahbod 034d4d26f2 [hb-cairo] Minor simplify 2023-01-26 14:32:25 -05:00
Behdad Esfahbod 26d34392e2 [hb-cairo] Fix condition 2023-01-26 14:32:25 -05:00
Matthias Clasen f9b3c79047 Update to different cairo API
The cairo will likely end up begin a getter for
a cairo_pattern_t instead of a color.
2023-01-26 14:32:25 -05:00
Behdad Esfahbod 4afdbcbad5 [hb-cairo] Don't call get_foreground_color unnecessarily
That would invalidate cairo cache on foreground change, even
if the glyph doesn't need that.
2023-01-26 14:32:25 -05:00
Matthias Clasen c37ea4f93e hb-cairo: Fix handling of foreground color
Use the new cairo_user_scaled_font_get_foreground_color
to obtain the foreground color, since the cr's source
can't be trusted.

Requires https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/420
2023-01-26 14:32:25 -05:00
Behdad Esfahbod aea37bfd37 Fix c++20 build 2023-01-26 12:19:16 -07:00
Behdad Esfahbod e1dc4920ee [iter] Allow hb_len() to fetch c.len as non-function 2023-01-26 12:19:16 -07:00
Behdad Esfahbod 8d29be39b2 [gsubgpos] Minor drop an unnecessary hb_iter 2023-01-26 12:19:16 -07:00
Matthias Clasen 06b9b3b5b6
Merge pull request #4083 from harfbuzz/bump-cairo
build: Bump to newer cairo
2023-01-26 14:15:52 -05:00
Matthias Clasen 4a632dec78 build: Bump to newer cairo 2023-01-26 13:19:50 -05:00
Matthias Clasen c1a5d20951 [doc] Add a missing comma 2023-01-25 21:53:06 -05:00
Matthias Clasen 8d80d1dd18 [paint] Update expected test results
These tests were affected by recent fixes.
2023-01-25 19:06:51 -05:00
Behdad Esfahbod 570fe998c9 [cairo] Another sweep_gradient fix
k was -1 sometimes.

Fixes the rest of https://roettsch.es/var_colrv1.html
2023-01-25 15:42:24 -07:00
Andres Salomon 13bfef9f01 [COPYING] Another update
Adobe, Inc has copyright in src/hb-subset-cff*, test/api/test-subset*, and
misc other places.

Ebrahim Byagowi has copyright as far back as 2015 in places like
src/hb-directwrite.cc.

Google, Inc has newer copyright into 2022 in places like
src/graph/test-classdef-graph.cc. Also, listing every year was getting a bit
unwieldy, so just do 2010-2022.

Igalia S.L. contributed the stuff in src/hb-ot-math*.

The only references I could find to Martin Hosken & SIL were in
src/hb-graphite2*, and they were 2011, not 2009.

Mozilla's got a bunch of 2015 code in src/hb-ot-shaper-*.

Red Hat has copyright up to 2023 (eg, test/api/test-glyph-names.c).
2023-01-25 15:36:04 -07:00
Behdad Esfahbod ea316b56a0 [cairo] Flip offsets when reversing
Fixes many of the var_colrv1 first row tests.

https://roettsch.es/var_colrv1.html
2023-01-25 15:31:29 -07:00
Behdad Esfahbod 5b05e198cf [cairo] More hb_malloc 2023-01-25 15:24:14 -07:00
Behdad Esfahbod 57352b8bd4 [cairo] Use hb_malloc / hb_free 2023-01-25 15:22:27 -07:00
Behdad Esfahbod a9392c0cbb [cairo] Use hb_swap() 2023-01-25 14:57:02 -07:00
Qunxin Liu 5e86870378 [instancer] compute head/maxp values using only non-empty glyphs 2023-01-25 14:53:19 -07:00
Qunxin Liu d15551c6f3 [instancer] update head table flagbit: allXMinIsLsb 2023-01-25 14:53:19 -07:00
Behdad Esfahbod 2c49eba044 [cairo] Indent 2023-01-25 14:52:39 -07:00
Behdad Esfahbod 2accbdc0b6 [paint] Minor skew 2023-01-25 14:40:04 -07:00
Behdad Esfahbod a4420479a8 Revert "[VarComposite] Fix skew"
This reverts commit 8cf7076309.
2023-01-25 14:37:10 -07:00
Behdad Esfahbod 8cf7076309 [VarComposite] Fix skew 2023-01-25 14:35:35 -07:00
Behdad Esfahbod 626f8e4de3 [paint] Fix skew to match Chrome 2023-01-25 14:33:46 -07:00
Behdad Esfahbod b44ff062e1 [deserialize] Some more 2023-01-25 14:16:46 -07:00
Behdad Esfahbod 57ff696430 [deserialize] One more fix 2023-01-25 14:10:12 -07:00
Behdad Esfahbod e973050986 [hb-buffer-deserialize] Fixups 2023-01-25 14:07:01 -07:00
Behdad Esfahbod a1101f09ca [test-buffer-serialize] Handle too-small out buffer
Need to handle too-small in buffer still.
2023-01-25 13:10:57 -07:00
Behdad Esfahbod 39d50008f8 [hb-info] Format 2023-01-25 12:53:50 -07:00
Behdad Esfahbod 4e2267b729 [hb-info] Add --get-meta 2023-01-25 12:51:53 -07:00
Behdad Esfahbod 42ed6abb6a [hb-info] Add --list-meta 2023-01-25 12:47:16 -07:00
Behdad Esfahbod 2fec4f1c3d [subset] Finish out hb-subset-instancer-solver.cc 2023-01-25 12:21:15 -07:00
Qunxin Liu 90a98dd62a [instancer] fix potential memory leak for compiled glyph bytes
Also calculate max_offsets after glyph bytes are compiled, cause byte
length of a glyph might change after compile
2023-01-25 11:37:19 -07:00
Behdad Esfahbod 223abd72b9 [subset] Add unfinished port of fonttools instancer solver 2023-01-25 11:37:07 -07:00
Behdad Esfahbod 167443e9fc [hb-info] Respect HB_CHAFA=0 2023-01-25 11:37:07 -07:00
Behdad Esfahbod 87df84c386 [hb-info] Fix copyright header 2023-01-25 11:37:07 -07:00
Andres Salomon 0bbc9d5256 [fonts] move OFL-1.1 license to a higher directory
There's a bunch of font directories inside of test/ for which the vast
majority of fonts are licensed under the SIL open font license. We currently
have a COPYING file in test/shape/data/in-house/COPYING that says that most
of the fonts are OFL-1.1, but that doesn't apply to the fonts in, say,
test/api/fonts/ or test/fuzzing/fonts/. Since there are so many OFL-1.1
fonts all over test, let's move the COPYING file to the top-level test/
directory.
2023-01-25 10:07:03 -07:00
Behdad Esfahbod 44a9c4bf59 [COPYING] Update 2023-01-25 09:58:29 -07:00
Andres Salomon c622c6b883 [font] update the license url for TestGVAREight.ttf
The url in the exif data incorrectly links to a proprietary license. However,
permission was granted for distribution under Apache-2 as part of another project,
so link to that project's license instead.

fixes #4062
2023-01-25 09:27:49 -07:00
Matthias Clasen eb0a025e49 Add a test for glyph names
This verifies that hb_font_get_glyph_name
returns false for nonexisting glyphs.
2023-01-24 21:35:04 -07:00
Behdad Esfahbod 1b143b0f0c [font] Docs 2023-01-24 18:34:04 -07:00
Behdad Esfahbod 64ed03c9be [cff1] Return no name for out-of-range glyph IDs
Was returning .notdef before.
2023-01-24 18:33:34 -07:00
Matthias Clasen c89aebc40b hb-font: Document length limit for glyph names
This is useful information for users of the
hb_font_get_glyph_name() API.
2023-01-24 18:29:06 -07:00
Matthias Clasen dd64266ea4 Add a test for glyph extents
This verifies a recent fix for COLRv1 returning
0,0,-1,1 for extents of non-painting glyphs.
2023-01-24 18:08:22 -07:00
Qunxin Liu 73e6f6cc88 [instancer] enable the missing test 2023-01-24 17:28:51 -07:00
Qunxin Liu 27f72f0deb [instancer] avoid double free for compiled glyph bytes
also increase the HB_GLYF_MAX_POINTS limit to 20000 cause the test file has a
.notdef glyph which is a composite glyph and has 10176 points after
get_points() call
2023-01-24 17:28:51 -07:00
Matthias Clasen ac969fffa2 Update meson summary
Include builtin font callbacks and Cairo integration
in the configuration summary.
2023-01-24 17:08:51 -07:00
Behdad Esfahbod 192361cb4d [hb-info] Show color swatch only if printing to terminal 2023-01-24 17:05:38 -07:00
Behdad Esfahbod 817ec182eb [hb-info] Format 2023-01-24 17:02:08 -07:00
Behdad Esfahbod 66ddeb0737 [hb-info] Change Chafa repeat to 16 2023-01-24 17:01:01 -07:00
Behdad Esfahbod 7a29ded169 [hb-info] Render colors in --list-palette
Uses chafa if available
2023-01-24 16:59:44 -07:00
Behdad Esfahbod b684c6edd4 [hb-cairo] Add hb_cairo_context_t 2023-01-24 12:21:12 -07:00
Behdad Esfahbod 279f13c187 [hb-shape] Write trace output to stderr 2023-01-24 11:50:59 -07:00
Behdad Esfahbod 161d8f9d26 [util] Rename a variable 2023-01-24 11:48:10 -07:00
Behdad Esfahbod 68a790261c [util] If --glyphs doesn't have positions, use glyph advances
Such that eg --glyphs=10 works.
2023-01-24 11:44:53 -07:00
Behdad Esfahbod 91a174f151 [hb-view] Hide --annotate and make it alias for --show-extents 2023-01-24 11:27:35 -07:00
Behdad Esfahbod 8cfb0ed072 [hb-view] --annotate enables --show-extents 2023-01-24 11:24:31 -07:00
Behdad Esfahbod 20fcf5c5b8 [hb-view] Add --show-extents 2023-01-24 11:22:55 -07:00
Behdad Esfahbod 72e13fff65 [COLRv1] Handle void extents 2023-01-24 11:05:38 -07:00
Behdad Esfahbod 20318feddf [COLRv1] Don't return extents if glyph has no paint
Fixes https://github.com/harfbuzz/harfbuzz/issues/4068
2023-01-24 11:04:10 -07:00
Behdad Esfahbod 32afdcdb46 [hb-buffer-deserialize-text-unicode] Relax parsing 2023-01-23 21:10:11 -07:00
Behdad Esfahbod 328ee9b4ad [hb-buffer-deserialize-text-unicodes] Rename 2023-01-23 21:06:27 -07:00
Behdad Esfahbod bc596b8cca [buffer-deserialize-text-unicode] Simplify 2023-01-23 21:03:59 -07:00
Behdad Esfahbod 649973a316 Fix build 2023-01-23 21:02:14 -07:00
Behdad Esfahbod f798cf225e [util] Don't require final ']' in --glyphs 2023-01-23 21:00:38 -07:00
Behdad Esfahbod 4268283e54 [buffer-deserialize-text] Accept initial comma 2023-01-23 20:57:56 -07:00
Behdad Esfahbod 2c29b81e7f [buffer-deserialize-text] Separate glyphs / unicodes machines 2023-01-23 20:57:56 -07:00
Behdad Esfahbod d0355eb4bd [buffer-deserialize] Parse whole items at a time
Previous logic would fail if char buffer was partial.
2023-01-23 20:57:56 -07:00
Matthias Clasen f65b04c17c Tweak wording 2023-01-23 19:58:14 -07:00
Matthias Clasen 7e01976bcc [hb-paint] Add some details to the docs 2023-01-23 19:58:14 -07:00
Garret Rieger e4fff64ce3 [repacker] check duplicate() for success.
Fixes fuzzer testcase https://oss-fuzz.com/testcase-detail/5475787333828608.
2023-01-23 18:37:13 -07:00
Behdad Esfahbod 6b72a4ddb0 Revert "[sanitize] Simplify(?) check_range"
This reverts commit af0b1ef8a7.
2023-01-23 18:36:04 -07:00
Behdad Esfahbod 00cf322e23
Merge pull request #4046 from harfbuzz/hb-features-docs
[doc] Try to fix generating hb-features docs
2023-01-23 16:06:26 -07:00
Khaled Hosny 699485b349 [meson] Further simplify generating hb-features.h 2023-01-24 00:15:48 +02:00
Khaled Hosny 2486d6d22f [meson] Reduce repetitions 2023-01-24 00:15:48 +02:00
Khaled Hosny 12f2ecbddb [doc] Generate hb-supported-features.h
See inline comment.
2023-01-24 00:15:48 +02:00
Khaled Hosny 0bbd3360ee [doc] Try to fix generating hb-features docs
Move it to a separate section, since hb-common says include hb.h, while
we want to include hb-features.h here.

This still does not fix generating documentation of undefined macros
(e.g. HB_HAS_GDI since we build docs on Linux).
2023-01-24 00:12:06 +02:00
Behdad Esfahbod af0b1ef8a7 [sanitize] Simplify(?) check_range 2023-01-23 14:31:10 -07:00
Behdad Esfahbod fe94c760e1 [algs] Build fix for clang and __builtin_mul_overflow
Fixes https://github.com/harfbuzz/harfbuzz/issues/4066
2023-01-23 14:05:28 -07:00
Khaled Hosny 1cf61f3053 [meson] Fix build with -Dgobject=disabled 2023-01-23 16:26:35 +02:00
Behdad Esfahbod 2b87af808b [hb-info] Typo 2023-01-22 17:37:51 -07:00
Behdad Esfahbod fe22afe7f9 [hb-info] Simplify 2023-01-22 16:47:50 -07:00
Khaled Hosny eba5762919 Another try 2023-01-22 16:30:34 -07:00
Khaled Hosny 37ab12a372 [util] Try to fix hb-info build 2023-01-22 16:30:34 -07:00
Behdad Esfahbod 5880ab0603 [hb-info] More build fix try 2023-01-22 16:21:43 -07:00
Behdad Esfahbod d76ef46d0a Try to fix autotools build 2023-01-22 16:17:39 -07:00
Behdad Esfahbod 6e58598520 [hb-info] Subfamily 2023-01-22 15:22:30 -07:00
Behdad Esfahbod 4142a460af [hb-info] Add --list-baselines 2023-01-22 15:11:50 -07:00
Behdad Esfahbod 9c62022ded [hb-info] Format 2023-01-22 15:02:21 -07:00
Behdad Esfahbod 0b7d3952ba [hb-info] Add --list-style 2023-01-22 15:00:10 -07:00
Behdad Esfahbod 090a6d0dde [hb-info] Add --get-style 2023-01-22 14:56:25 -07:00
Behdad Esfahbod 5b291d49e8 [hb-info] Rename style to subfamily 2023-01-22 14:51:17 -07:00
Behdad Esfahbod c300bf00f0 [hb-info] Move include around 2023-01-22 14:46:20 -07:00
Behdad Esfahbod b839f53cde [hb-info] Write fallback metrics in --list-metrics 2023-01-22 14:39:26 -07:00
Behdad Esfahbod 7ba3d0c419 [hb-info] Add --list-metrics
Requires hb-gobject
2023-01-22 14:28:13 -07:00
Behdad Esfahbod 4ec3d2e32a [hb-info List enum nicks in --list-names 2023-01-22 14:13:52 -07:00
Behdad Esfahbod def94aa8c5 [features] Add HB_HAS_GOBJECT 2023-01-22 14:01:34 -07:00
Behdad Esfahbod b3006ba9cb Docs 2023-01-22 13:46:35 -07:00
Behdad Esfahbod e3e4d1ecdc [name] Add hb_ot_name_id_predefined_t
Not sure what to do about its docs.
2023-01-22 13:41:43 -07:00
Behdad Esfahbod 3feac1a408 [hb-info] Use tab in --list-palettes 2023-01-22 10:15:14 -07:00
Behdad Esfahbod 752ad51cce [hb-info] Move some initialization to post_parse 2023-01-22 10:12:41 -07:00
Behdad Esfahbod 334f59c955 [hb-info] If name not found, fall back to English 2023-01-22 10:06:05 -07:00
Behdad Esfahbod 7cae553592 [hb-info] Rename --dump-table to --get-table 2023-01-22 09:33:25 -07:00
Behdad Esfahbod 9b499a48bb [hb-info] Add --get-name 2023-01-22 09:27:05 -07:00
Behdad Esfahbod 7a47a369d3 [hmtx] Fix typo 2023-01-22 09:09:45 -07:00
Behdad Esfahbod b987918125
Merge pull request #4052 from googlefonts/instancer_recalc_bounds
[instancer] recalc bounds by default when --instance option is enabled
2023-01-22 09:08:51 -07:00
Behdad Esfahbod e4cdaa1d3f [test] Fix build 2023-01-22 08:36:51 -07:00
Behdad Esfahbod 9ba1e400d6 [test] Remove non-free font and its test
Fixes https://github.com/harfbuzz/harfbuzz/issues/4059
2023-01-22 08:31:39 -07:00
Behdad Esfahbod 749df4ee84 [PairPosFormat1] One more 2023-01-21 16:00:54 -07:00
Behdad Esfahbod b648ceb72f [PairSet] Optimize last commit 2023-01-21 15:58:59 -07:00
Behdad Esfahbod 891623243c [PairSet] Unify get_size() 2023-01-21 15:57:18 -07:00
Behdad Esfahbod b63159e8bf [PairPosFormat1] Fix stride
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55287
and generally the lookup with MediumTypes.
2023-01-21 15:51:40 -07:00
Behdad Esfahbod be8a87c453 Move TRACE_DISPATCH after may_recurse()
Such that we don't get memory access issues if DEBUG_SANITIZE is
on and may_recurse() returns false.
2023-01-21 15:50:25 -07:00
Behdad Esfahbod 84b9a632ed [debug] Fix printf signness warnings 2023-01-21 14:37:34 -07:00
Behdad Esfahbod c54a7022fe [hb-view] Require cairo 1.17.5 for HB_DRAW=1 default again
Fixes https://github.com/harfbuzz/harfbuzz/issues/4051
2023-01-21 14:07:41 -07:00
Khaled Hosny 67e652cd5d [meson] Update Cairo subproject 2023-01-21 14:04:49 -07:00
Khaled Hosny ed68db2c01 [util] Fix MSVC warning
Apparently \e is non-standard extension not supported by MSVC. Use \033
instead.

Fixes:

warning C4129: 'e': unrecognized character escape sequence
2023-01-21 15:27:56 +02:00
Khaled Hosny c08e5d094a [hb-draw] Fix MSVC warning
warning C4305: 'initializing': truncation from 'double' to 'float'
2023-01-21 15:27:56 +02:00
Khaled Hosny e1a0705128 [meson] Enabled needlessly disabled MSVC warnings
We don’t seem to hot any of these warnings currently.
2023-01-21 15:27:56 +02:00
Khaled Hosny f96e32a0aa [meson] Try to make MSVC build less spammy
Enable exceptions in ragel subproject, and revert the exceptions part of:

commit 22cbd038d3
Author: Khaled Hosny <khaled@aliftype.com>
Date:   Tue Sep 14 12:34:25 2021 +0200

    [meson] Add ragel subproject

To get ride of the following warnings:

cl : Command line warning D9025 : overriding '/EHs' with '/EHs-'
2023-01-21 15:27:56 +02:00
Matthias Clasen 32f9b467d6
Merge pull request #4045 from harfbuzz/custom-palette-cairo
Custom palette cairo
2023-01-21 02:20:39 -05:00
Matthias Clasen 179c93c5c2
Merge pull request #4054 from harfbuzz/hb-info-color-format
[hb-info] Fix output for CPAL
2023-01-21 02:20:00 -05:00
Matthias Clasen 54d5321d13
Merge pull request #4056 from harfbuzz/fix-sweep-gradient-hang
[hb-cairo] Fixes for sweep gradients
2023-01-21 02:19:43 -05:00
Matthias Clasen 47baa1da6b [hb-cairo] Fixes for sweep gradients
Make reversed angles not infloop, and
cap the number of interval repetitions
at 1000.

Fixes: https://github.com/harfbuzz/harfbuzz/issues/4055
2023-01-20 23:38:22 -05:00
Matthias Clasen c574eda74b [hb-info] Fix output for CPAL
The output for palette names was mangled.
This commit makes things come out ok.

For flags, we use "Both" when both LIGHT
and DARK are set.
2023-01-20 22:06:47 -05:00
Behdad Esfahbod 7f59bed528 [hb-cairo] Round foreground color 2023-01-20 16:42:55 -07:00
Behdad Esfahbod 76b059cadb [hb-cairo] Simplify foreground color fetching 2023-01-20 16:41:47 -07:00
Behdad Esfahbod f70f7194de [hb-cairo] Remove unused prototype 2023-01-20 16:30:59 -07:00
Behdad Esfahbod 61719a8350 [hb-view] Support specifying color indices again 2023-01-20 15:52:09 -07:00
Qunxin Liu 89d332559e [instancer] add tests 2023-01-20 14:50:03 -08:00
Qunxin Liu 30058f489a [instancer] trim .notdef outline data after recalc bounds
If outline data present, we use it to recalc bounds and then trim it
accordingly
2023-01-20 14:50:03 -08:00
Qunxin Liu 0de7f83a9f [instancer] update maxp table 2023-01-20 14:50:03 -08:00
Qunxin Liu 94c390d078 [instancer] update head table 2023-01-20 14:50:03 -08:00
Qunxin Liu 2ecb1c31e9 [instancer] always recalculate bounds when --instance option enabled
But don't recompile glyph bytes if pinned at default
2023-01-20 14:50:03 -08:00
Qunxin Liu 1f948e7fd5 [instancer] store recalculated head/maxp info in subset plan 2023-01-20 14:49:54 -08:00
Qunxin Liu 92122421c9 [instancer] update vhea/hhea tables 2023-01-20 14:48:53 -08:00
Behdad Esfahbod ab7c914425 [hb-cairo] Macro shuffle again 2023-01-20 15:43:01 -07:00
Behdad Esfahbod 4759932bcf [hb-cairo] Round colors 2023-01-20 15:33:38 -07:00
Behdad Esfahbod 876675e090 [hb-cairo] Macro shuffling 2023-01-20 15:31:43 -07:00
Behdad Esfahbod 68a73e436a [hb-cairo] Macro hygiene 2023-01-20 15:30:07 -07:00
Khaled Hosny fcb5111cc6 [doc] Fix gtk-doc warning 2023-01-21 00:24:50 +02:00
Behdad Esfahbod 574d9344dc [hb-cairo] Fix build with old cairo 2023-01-20 15:22:50 -07:00
Behdad Esfahbod 4f19c3b3be [hb-cairo] Move color-cache to scaled-font 2023-01-20 15:15:52 -07:00
Behdad Esfahbod beba43eebe [hb-cairo] Fix color cache on not-found 2023-01-20 15:02:24 -07:00
Behdad Esfahbod cc9b55c794 [hb-cairo] Add a color cache 2023-01-20 14:57:57 -07:00
Behdad Esfahbod 10def9b3df meson fix 2023-01-20 14:06:18 -07:00
Behdad Esfahbod eb00088bcf [paint] Docs 2023-01-20 13:57:39 -07:00
Behdad Esfahbod f21b15dcc3 [hb-view] Update to alternative cairo custom-palette API 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 638e0ed4fd [paint] Overlay custom-palette on top of chosen palette
Got to agree this is more ergonomic.
2023-01-20 13:57:39 -07:00
Behdad Esfahbod 03e2e58642 [hb-view] Improve color parsing
Now supports 3, 4, 6, 8 digit colors.
2023-01-20 13:57:39 -07:00
Behdad Esfahbod dc4af478d1 [hb-view] Default background to white when parsing 2023-01-20 13:57:39 -07:00
Matthias Clasen b81db8d3d8 Avoid a compiler warning 2023-01-20 13:57:39 -07:00
Behdad Esfahbod e998cec1d9 [hb-view] Move palette options to --help-view 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 253b4cecae [hb-view] Simplify palette format 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 52b78d526b [hb-view] Fix leak 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 5847ec24ff Fix bots 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 4fe6ece425 [cairo] Don't fallback to CPAL if cairo doesn't support custom palette 2023-01-20 13:57:39 -07:00
Behdad Esfahbod 0bff570491 [hb-view] Use custom palette if any set 2023-01-20 13:57:39 -07:00
Matthias Clasen c41892a012 hb-view: Add a --custom-palette option 2023-01-20 13:57:39 -07:00
Matthias Clasen ab37ade7e4 Hook up custom palettes for cairo 2023-01-20 13:57:39 -07:00
Behdad Esfahbod cce7c441eb [name] Fix doc
That's part of an enum now.
2023-01-20 13:57:05 -07:00
Behdad Esfahbod 3711455154 [hb-info] Minor set parse hooks
Unused.
2023-01-20 12:32:41 -07:00
Behdad Esfahbod 89371419a9 [hb-info] Move code around 2023-01-20 12:20:38 -07:00
Behdad Esfahbod 32b42eb568 [hb-info] Add --show-face-count 2023-01-20 12:18:04 -07:00
Behdad Esfahbod fd84605b58 [hb-info] Add --show-technology 2023-01-20 12:10:03 -07:00
Behdad Esfahbod c05230256d [util] Add -y for --face-index
Ala ttx.
2023-01-20 12:08:31 -07:00
Behdad Esfahbod 6bf9237e5f [hb-info] Format --list-palettes 2023-01-20 11:54:08 -07:00
Behdad Esfahbod 64625ed85d [hb-info] Write palette flags 2023-01-20 11:48:01 -07:00
Behdad Esfahbod d811dcdbde [hb-info] Add --list-palettes 2023-01-20 11:42:51 -07:00
Behdad Esfahbod 2590578162 [hb-info] Add --get-baseline 2023-01-20 11:04:22 -07:00
Behdad Esfahbod b77baa31c3 [hb-info] Show whether --get-metric value is fallback 2023-01-20 10:13:21 -07:00
Behdad Esfahbod 2a8df82aca [hb-info] Add --get-metric 2023-01-20 09:57:28 -07:00
Behdad Esfahbod ba4f5e9f22 [hb-info] Add --ot-script and --ot-language 2023-01-20 09:29:39 -07:00
Behdad Esfahbod edec8946ed New API: hb_ot_layout_script_select_language2()
Variant that outputs chosen_language.

Not sure why the original API didn't have this. The script
counterpart has.
2023-01-20 09:28:59 -07:00
Behdad Esfahbod 2fd8e36ea5 [layout] Fix return value of chosen_script when matching fails 2023-01-20 09:09:14 -07:00
Behdad Esfahbod d06976e68f [glyf] Add an edge-count limit
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55246
2023-01-20 08:21:43 -07:00
Behdad Esfahbod 2cfd4133fb [hb-info] Print Zyyy for DFLT script 2023-01-20 07:11:33 -07:00
Khaled Hosny 178c5bed39 [ci] Use unique ccache cache keys per job 2023-01-20 10:28:44 +02:00
Khaled Hosny a0afde70c5 [ci] Re-enable coverage reporting on macOS 2023-01-20 10:28:44 +02:00
Khaled Hosny 8785d515d0 [ci] Don’t install glib-utils on macOS
Homebrew can’t make up their mind, they seem to have merged the glib
packages again.
2023-01-20 10:28:44 +02:00
Khaled Hosny 5ddb5fb847 [ci] Don’t install gtk-doc on macOS
We are not building the documentation here.
2023-01-20 10:28:44 +02:00
Khaled Hosny 48df846a41 [ci] Make homebrew do less work 2023-01-20 10:28:44 +02:00
Khaled Hosny 35f0184bfd [ci] Clean a bit and add some consistency 2023-01-20 10:28:44 +02:00
Behdad Esfahbod edd5a37e79 [hb-info] Implement script/language-sensitive --list-features
I'm not very confident in the implementation.
2023-01-19 18:39:32 -07:00
Behdad Esfahbod a67b6aad92 [hb-info] Format 2023-01-19 18:07:05 -07:00
Behdad Esfahbod 4927e215a4 [hb-info] Format 2023-01-19 18:03:31 -07:00
Behdad Esfahbod 9ca320d69e [hb-info] Format 2023-01-19 17:56:06 -07:00
Behdad Esfahbod b24c7add80 [hb-info] Write ISO/BCP script/language in --scripts 2023-01-19 17:53:07 -07:00
Behdad Esfahbod b8dacd46f5 [hb-info] Format 2023-01-19 17:46:24 -07:00
Behdad Esfahbod b9a2917c2e [hb-info] Simplify direction/script/language handling 2023-01-19 17:38:05 -07:00
Behdad Esfahbod e6544148b5 [hb-info] Enlarge name buffer 2023-01-19 17:28:41 -07:00
Behdad Esfahbod d759918d18 [hb-info] TODO 2023-01-19 17:26:00 -07:00
Behdad Esfahbod 4baf0ada69 [hb-info] Add --direction, --script, --language 2023-01-19 17:24:05 -07:00
Behdad Esfahbod 66692c82e9
Merge pull request #4048 from harfbuzz/hb-info
hb-info
2023-01-19 16:26:15 -07:00
Behdad Esfahbod e52a23c5f8 [hb-info] Add --show-extents 2023-01-19 16:01:29 -07:00
Behdad Esfahbod 1302a88b25 [hb-info] Add --dump-table 2023-01-19 15:51:46 -07:00
Behdad Esfahbod 148ee3e0c7 [hb-info] Make --show-style and --show-postscript-name show named-instance 2023-01-19 15:41:13 -07:00
Behdad Esfahbod 2a3903b37f [hb-info] TODO items 2023-01-19 15:34:14 -07:00
Behdad Esfahbod 5540367ee2 [hb-info] Add --show-version 2023-01-19 15:30:27 -07:00
Behdad Esfahbod 3c734f4479 [hb-info] Add --show-postscript-name 2023-01-19 15:27:13 -07:00
Behdad Esfahbod 895d3f9e3e [hb-info] Mark --show-all as default 2023-01-19 15:24:32 -07:00
Behdad Esfahbod dec320a463 [hb-info] Put back -l for --list-tables 2023-01-19 15:18:06 -07:00
Behdad Esfahbod 9395bbaa67 [hb-info] Format 2023-01-19 15:17:33 -07:00
Behdad Esfahbod d7cf69ede2 [hb-info] Format 2023-01-19 15:15:56 -07:00
Behdad Esfahbod 7af0624bdf [hb-info] Remove unintended short option 2023-01-19 15:11:55 -07:00
Behdad Esfahbod 2115140121 [hb-info] Add --show-unique-name and --show-full-name 2023-01-19 15:10:00 -07:00
Behdad Esfahbod 2d9ba17a53 [hb-info] Add --show-style 2023-01-19 15:06:21 -07:00
Behdad Esfahbod fecb2eeca0 [hb-info] Add --show-family 2023-01-19 15:05:00 -07:00
Behdad Esfahbod f25c03162b [hb-info] Change separator to === 2023-01-19 14:57:45 -07:00
Behdad Esfahbod 5b05edd221 [hb-info] Add --list-names 2023-01-19 14:57:30 -07:00
Behdad Esfahbod 67c9845301 [hb-info] Make -l list tables ala ttx 2023-01-19 14:45:04 -07:00
Behdad Esfahbod 972e3b76da [hb-info] Minor formatting 2023-01-19 14:42:18 -07:00
Behdad Esfahbod c1679e0266 [hb-info] Default to --show-all 2023-01-19 14:41:13 -07:00
Behdad Esfahbod 1eca2c88a2 [hb-info] Add a few short option forms 2023-01-19 14:38:12 -07:00
Behdad Esfahbod e5a07c883c [hb-info] --help format 2023-01-19 14:34:32 -07:00
Behdad Esfahbod b215f6a84f [hb-info] Add --show-unicode-count 2023-01-19 14:31:45 -07:00
Behdad Esfahbod 3189b614b1 [hb-info] Format 2023-01-19 14:24:26 -07:00
Behdad Esfahbod fd20a7e143 [hb-info] Add --show-glyph-count 2023-01-19 14:23:36 -07:00
Behdad Esfahbod 38c71cebd0 [hb-info] Add --show-upem --show-all --all 2023-01-19 14:19:05 -07:00
Behdad Esfahbod aee7454d05 [hb-info] Add --list-scripts 2023-01-19 14:09:45 -07:00
Behdad Esfahbod 9ca2f86fe0 [hb-info] Minor verbose print 2023-01-19 14:04:37 -07:00
Behdad Esfahbod 9a94c06052 [hb-info] Minor we have face available 2023-01-19 13:56:36 -07:00
Behdad Esfahbod 8921f593f9 [hb-info] Print "---" separator 2023-01-19 13:49:22 -07:00
Behdad Esfahbod f514f69724 [hb-info] Add --quiet 2023-01-19 13:35:15 -07:00
Behdad Esfahbod dc717ced8d [hb-info] Simplify 2023-01-19 13:16:34 -07:00
Behdad Esfahbod 1816d3664d [hb-info] Flesh out 2023-01-19 12:59:26 -07:00
Behdad Esfahbod ca903f7531 [hb-info] Start adding 2023-01-19 12:40:27 -07:00
Behdad Esfahbod f43ba351e8 [util] Limit chafa to one thread 2023-01-19 12:17:30 -07:00
Behdad Esfahbod 2b010d8017 [util] Minor hide --font-ptem sometimes 2023-01-19 12:14:50 -07:00
Behdad Esfahbod 06c064a351 [util] Use hb_font_glyph_to_string 2023-01-19 11:17:49 -07:00
Behdad Esfahbod 0c7d386748
Merge pull request #4044 from harfbuzz/custom-palette
Custom palette
2023-01-18 21:50:10 -07:00
Behdad Esfahbod 0b32cf9023 [COLR] Rename a variable 2023-01-18 21:16:38 -07:00
Behdad Esfahbod 1d58c8fb0e [paint] Typo 2023-01-18 21:14:24 -07:00
Behdad Esfahbod 7aca3b5090 [COLRv1] Hook up custom palette colors 2023-01-18 21:01:44 -07:00
Behdad Esfahbod d695cc8735 [paint] Docs 2023-01-18 20:45:19 -07:00
Behdad Esfahbod 53bd9039e7 [paint] Doc 2023-01-18 20:44:05 -07:00
Behdad Esfahbod 8afd3ccb10 [paint] Add HB_PAINT_PALETTE_INDEX_CUSTOM 2023-01-18 20:43:10 -07:00
Behdad Esfahbod 9a2f2b593e [font] Rename palette to palette_index 2023-01-18 20:39:36 -07:00
Behdad Esfahbod bd73314616 [paint] Add API for custom palettes 2023-01-18 20:37:21 -07:00
Behdad Esfahbod ea291493d2 [hb-shape/view] List variation sequences in --list-unicodes 2023-01-18 19:51:22 -07:00
Behdad Esfahbod 8564d2266b [hb-shape/view] Add --list-glyphs 2023-01-18 19:43:33 -07:00
Behdad Esfahbod bf8bb9fb83 [hb-shape/view] Add --list-unicodes 2023-01-18 19:40:09 -07:00
Behdad Esfahbod 13c70066de Shut up gcc 13 -Wdangling-reference
Fixes https://github.com/harfbuzz/harfbuzz/issues/4043
2023-01-18 17:29:26 -07:00
Khaled Hosny 1abcc32137 Revert "[ci] Use sccache with msys2"
This reverts commit b9646dfd62.

For some reason using sccache re-introduces the random CI crashes that
was previously fixed in 80dd751564.
2023-01-18 23:55:17 +02:00
Behdad Esfahbod eed5d5efdd [VarComposite] Implement RESET_UNSPECIFIED_AXES
Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/79
2023-01-18 14:13:12 -07:00
Behdad Esfahbod 4300a18b85 [arabic-fallback] Fix ligature code
Fixes https://github.com/harfbuzz/harfbuzz/issues/4042

This was broken in 20e9f0b.
2023-01-18 10:44:57 -07:00
Khaled Hosny b9646dfd62 [ci] Use sccache with msys2 2023-01-17 22:21:22 +02:00
Khaled Hosny 22a4fca375 [ci] Use sccache for msvc jobs
Meson will not use ccache with MSVC, so we use sccache here.
2023-01-17 22:21:22 +02:00
Khaled Hosny 582636bce0 [ci] Use ccache for linux and macos jobs 2023-01-17 22:21:22 +02:00
Khaled Hosny 99146e7609 [ci] We don’t need to install ragel on msys2 2023-01-17 22:21:22 +02:00
Khaled Hosny 842e26d32c [ci] Remove no longer needed workaround
Meson seems to take care of this itself now.
2023-01-17 22:21:22 +02:00
Behdad Esfahbod 4d86c65c7a [hb-cairo] Fix linear-gradient reduce_anchors 2023-01-17 07:35:01 -07:00
Khaled Hosny 910adc7e92 [test-paint] Update expectations 2023-01-17 15:43:09 +02:00
Khaled Hosny 4f4b6e03f4 [wrap] Add fallback source URL for zlib
Hopefully this fixes the intermittent CI failures due to download
failures.
2023-01-17 15:43:09 +02:00
Behdad Esfahbod c86bab3fb4 [test-paint] Use G_GNUC_PRINTF 2023-01-17 06:29:17 -07:00
Behdad Esfahbod 92d5ec2f16 [bit-page] Mark len() function static 2023-01-17 05:59:55 -07:00
Amir Masoud Abdol 0a3e4c12ac Replace the deprecated $<CONFIGURATION> with $<CONFIG> 2023-01-17 11:09:15 +02:00
Behdad Esfahbod f38e35ebc3 [cairo] Internal function renames 2023-01-16 18:07:39 -07:00
Behdad Esfahbod e4a41f5e16 [COLRv1] Implement recursive clip boxes
Tests need update.

hb-view test_glyphs-glyf_colr_1_variable.ttf -u f0c00
2023-01-16 16:27:04 -07:00
Behdad Esfahbod f02c4ebb40 [test-paint] Adjust condition for enabling ft backend 2023-01-16 14:17:44 -07:00
Sergei Trofimovich 7dfa672dac test/threads/hb-subset-threads.cc: add missing <cstdio> include
This week's `gcc-13` snapshot cleaned further up it's standard headers
and exposed missing declaration as a build failure:

    ../test/threads/hb-subset-threads.cc: In function 'void test_operation(operation_t, const char*, const test_input_t&)':
    ../test/threads/hb-subset-threads.cc:127:3: error: 'printf' was not declared in this scope

    ../test/threads/hb-subset-threads.cc: In function 'int main(int, char**)':
    ../test/threads/hb-subset-threads.cc:157:19: error: 'atoi' was not declared in this scope
2023-01-16 13:16:23 -07:00
Behdad Esfahbod f11271cc03 [cairo] Version-check the variations code 2023-01-16 13:14:58 -07:00
Behdad Esfahbod a180ae43ce [bit-set] Use for loop instead of memset for page clear
Produces faster code.
2023-01-16 13:06:30 -07:00
Behdad Esfahbod 8e8ca03b2a [hb-fc] Minor remove unused variable 2023-01-16 12:38:53 -07:00
Behdad Esfahbod e903397bc3 Whitespace 2023-01-16 12:33:17 -07:00
Behdad Esfahbod ca1de29e0a [set] Adjust hb_set_copy() 2023-01-16 12:08:11 -07:00
Behdad Esfahbod b7f1c30c20 [map] Adjust hb_map_copy() 2023-01-16 12:07:15 -07:00
Behdad Esfahbod e0883d60e4 Whitespace 2023-01-16 12:02:21 -07:00
Behdad Esfahbod 82a3b2dbb5 [util] Fix --named-instance 2023-01-16 11:18:22 -07:00
Behdad Esfahbod ad6b9c417d [util] Format --list-features 2023-01-16 11:07:03 -07:00
Behdad Esfahbod 0f4da85074 [util] Minor in --list-features clear feature set between GSUB/GPOS 2023-01-16 11:04:38 -07:00
Behdad Esfahbod f25e3696eb [hb-shape/hb-view] Better --list-features 2023-01-16 10:54:23 -07:00
Behdad Esfahbod 32d439596d [hb-shape/view] Print feature names in --list-features 2023-01-15 22:34:14 -07:00
303 changed files with 11900 additions and 5064 deletions

View File

@ -2,7 +2,7 @@
set -e
meson --cross-file=.ci/win32-cross-file.txt \
--wrap-mode=forcefallback \
--wrap-mode=default \
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \

View File

@ -2,7 +2,7 @@
set -e
meson --cross-file=.ci/win64-cross-file.txt \
--wrap-mode=forcefallback \
--wrap-mode=default \
-Dtests=disabled \
-Dcairo=enabled \
-Dcairo:fontconfig=disabled \

View File

@ -18,9 +18,9 @@ jobs:
xcode: "12.5.1"
steps:
- checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection gtk-doc ninja
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection ninja
- run: pip3 install meson --upgrade
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson setup build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson setup build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Ddocs=disabled
- run: meson compile -Cbuild
- run: meson test -Cbuild --print-errorlogs
- store_artifacts:
@ -123,7 +123,7 @@ jobs:
executor: win32-executor
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build gtk-doc-tools python3 python3-pip git g++-mingw-w64-i686 zip
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip git g++-mingw-w64-i686 zip
- run: pip3 install meson==0.60.0
- run: .ci/build-win32.sh
- store_artifacts:
@ -146,7 +146,7 @@ jobs:
executor: win64-executor
steps:
- checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build gtk-doc-tools python3 python3-pip git g++-mingw-w64-x86-64 zip
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip git g++-mingw-w64-x86-64 zip
- run: pip3 install meson==0.60.0
- run: bash .ci/build-win64.sh
- store_artifacts:

View File

@ -1,8 +1,10 @@
comment: off
comment: false
coverage:
status:
project:
default:
threshold: 1%
patch: off
informational: true
patch:
default:
informational: true

View File

@ -1,5 +1,9 @@
name: CIFuzz
on: [pull_request]
permissions:
contents: read
jobs:
Fuzzing:
runs-on: ubuntu-latest

View File

@ -15,43 +15,57 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: install dependencies
run: sudo apt-get update && sudo apt-get install pkg-config gcc gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-setuptools ninja-build gobject-introspection libgirepository1.0-dev
- run: sudo pip3 install fonttools meson==0.56.0 gcovr==5.0
- name: run
run: meson build -Db_coverage=true --auto-features=enabled -Dgraphite=enabled -Dchafa=disabled -Dragel_subproject=true -Doptimization=2
- name: ci
- name: Checkout
uses: actions/checkout@v3
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install \
gcc \
gobject-introspection \
gtk-doc-tools \
libcairo2-dev \
libfreetype6-dev \
libgirepository1.0-dev \
libglib2.0-dev \
libgraphite2-dev \
libicu-dev \
ninja-build \
pkg-config \
python3 \
python3-setuptools
- name: Install Python Dependencies
run: sudo pip3 install fonttools meson==0.56.0 gcovr==5.0
- name: Setup Meson
run: |
ccache --version
meson setup build \
-Dauto_features=enabled \
-Dchafa=disabled \
-Dgraphite=enabled \
-Doptimization=2 \
-Db_coverage=true \
-Ddoc_tests=true \
-Dragel_subproject=true
- name: Build
run: meson compile -Cbuild
- name: Test
run: meson test --print-errorlogs -Cbuild
- name: generate documentations
- name: Generate Documentations
run: ninja -Cbuild harfbuzz-doc
- name: deploy documentations
- name: Deploy Documentations
if: github.ref_type == 'tag'
run: .ci/deploy-docs.sh
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
REVISION: ${{ github.sha }}
# waiting for https://github.com/rhysd/github-action-benchmark/issues/36 to happen
# - name: benchmark
# run: build/perf/perf --benchmark_format=json > perf/result.json
# - name: store benchmark result
# uses: rhysd/github-action-benchmark@b2ee598
# if: github.event_name != 'pull_request'
# with:
# name: C++ Benchmark
# tool: 'googlecpp'
# output-file-path: perf/result.json
# gh-pages-branch: gh-pages
# github-token: ${{ secrets.PERSONAL_GITHUB_TOKEN }}
# auto-push: true
# alert-threshold: '150%'
# comment-on-alert: true
# fail-on-alert: true
- name: cov
- name: Generate Coverage
run: ninja -Cbuild coverage-xml
- uses: codecov/codecov-action@v3
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
file: build/meson-logs/coverage.xml

View File

@ -14,11 +14,47 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install meson pkg-config freetype glib glib-utils cairo icu4c graphite2 gobject-introspection gtk-doc ninja
- run: pip3 install fonttools
- name: run
run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Doptimization=2
- name: ci
- name: Checkout
uses: actions/checkout@v3
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
- name: Install Dependencies
run: |
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install \
cairo \
freetype \
glib \
gobject-introspection \
graphite2 \
icu4c \
meson \
ninja \
pkg-config
- name: Install Python Dependencies
run: pip3 install fonttools gcovr==5.0
- name: Setup Meson
run: |
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig"
ccache --version
meson setup build \
-Dauto_features=enabled \
-Ddocs=disabled \
-Dchafa=disabled \
-Dcoretext=enabled \
-Dgraphite=enabled \
-Doptimization=2 \
-Db_coverage=true \
- name: Build
run: meson compile -Cbuild
- name: Test
run: meson test --print-errorlogs -Cbuild
- name: Generate Coverage
run: ninja -Cbuild coverage-xml
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
file: build/meson-logs/coverage.xml

View File

@ -27,33 +27,35 @@ jobs:
name: ${{ matrix.name }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: ilammy/msvc-dev-cmd@v1
with:
arch : ${{ matrix.ARCH }}
- name: Upgrade pip
run: |
python -m pip install -U pip
- name: Install Dependencies
run: |
pip install --upgrade meson ninja fonttools
- name: Build
run: |
# This dir contains a pkg-config which meson will happily use and later fail, so remove it
$env:path = ($env:path.Split(';') | Where-Object { $_ -ne 'C:\Strawberry\perl\bin' }) -join ';'
meson setup build `
--wrap-mode=forcefallback `
--buildtype=release `
-Dglib=enabled `
-Dfreetype=enabled `
-Dgdi=enabled `
-Ddirectwrite=enabled
meson compile -C build
- name: Test
run: |
meson test --print-errorlogs --suite=harfbuzz -C build
- name: Checkout
uses: actions/checkout@v3
- name: Setup Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
variant: sccache
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.ARCH }}
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
with:
arch : ${{ matrix.ARCH }}
- name: Install Python Dependencies
run: |
pip install --upgrade meson ninja fonttools
- name: Setup Meson
run: |
sccache --version
meson setup build `
--wrap-mode=forcefallback `
--buildtype=release `
-Dglib=enabled `
-Dfreetype=enabled `
-Dgdi=enabled `
-Ddirectwrite=enabled
- name: Build
run: meson compile -Cbuild
- name: Test
run: meson test --print-errorlogs --suite=harfbuzz -Cbuild

View File

@ -32,44 +32,42 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v3
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.MSYSTEM }}
update: true
install: >-
mingw-w64-${{ matrix.MSYS2_ARCH }}-cairo
mingw-w64-${{ matrix.MSYS2_ARCH }}-freetype
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs
mingw-w64-${{ matrix.MSYS2_ARCH }}-gettext
mingw-w64-${{ matrix.MSYS2_ARCH }}-glib2
mingw-w64-${{ matrix.MSYS2_ARCH }}-gobject-introspection
mingw-w64-${{ matrix.MSYS2_ARCH }}-graphite2
mingw-w64-${{ matrix.MSYS2_ARCH }}-icu
mingw-w64-${{ matrix.MSYS2_ARCH }}-meson
mingw-w64-${{ matrix.MSYS2_ARCH }}-ninja
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkg-config
mingw-w64-${{ matrix.MSYS2_ARCH }}-python
mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip
mingw-w64-${{ matrix.MSYS2_ARCH }}-ragel
- name: Install Python Dependencies
run: |
pip install --upgrade fonttools
- name: Build
run: |
meson build \
--wrap-mode=nodownload \
--auto-features=enabled \
-Ddocs=disabled \
-Ddirectwrite=enabled \
-Dgdi=enabled \
-Dgraphite=enabled \
-Dchafa=disabled
ninja -C build
- name: Test
run: |
meson test \
--print-errorlogs \
--suite=harfbuzz \
-C build
- name: Checkout
uses: actions/checkout@v3
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.MSYSTEM }}
update: true
install: >-
mingw-w64-${{ matrix.MSYS2_ARCH }}-cairo
mingw-w64-${{ matrix.MSYS2_ARCH }}-freetype
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs
mingw-w64-${{ matrix.MSYS2_ARCH }}-gettext
mingw-w64-${{ matrix.MSYS2_ARCH }}-glib2
mingw-w64-${{ matrix.MSYS2_ARCH }}-gobject-introspection
mingw-w64-${{ matrix.MSYS2_ARCH }}-graphite2
mingw-w64-${{ matrix.MSYS2_ARCH }}-icu
mingw-w64-${{ matrix.MSYS2_ARCH }}-meson
mingw-w64-${{ matrix.MSYS2_ARCH }}-ninja
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkg-config
mingw-w64-${{ matrix.MSYS2_ARCH }}-python
mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip
- name: Install Python Dependencies
run: |
pip install --upgrade fonttools
- name: Setup Meson
run: |
meson setup build \
--wrap-mode=nodownload \
--auto-features=enabled \
-Ddocs=disabled \
-Ddirectwrite=enabled \
-Dgdi=enabled \
-Dgraphite=enabled \
-Dchafa=disabled
- name: Build
run: meson compile -Cbuild
- name: Test
run: meson test --print-errorlogs --suite=harfbuzz -Cbuild

View File

@ -566,7 +566,7 @@ if (HB_HAVE_INTROSPECTION)
# We need to account for the varying output directories
# when we build using Visual Studio projects
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
else ()
set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
endif ()
@ -816,7 +816,7 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
make_pkgconfig_pc_file("harfbuzz-gobject")
if (HB_HAVE_INTROSPECTION)
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
else ()
set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
endif ()

20
COPYING
View File

@ -2,19 +2,23 @@ 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,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc.
Copyright © 2018,2019,2020 Ebrahim Byagowi
Copyright © 2010-2022 Google, Inc.
Copyright © 2015-2020 Ebrahim Byagowi
Copyright © 2019,2020 Facebook, Inc.
Copyright © 2012 Mozilla Foundation
Copyright © 2012,2015 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 © 2011 Martin Hosken and SIL International
Copyright © 2007 Chris Wilson
Copyright © 2005,2006,2020,2021 Behdad Esfahbod
Copyright © 2005 David Turner
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
Copyright © 1998-2004 David Turner and Werner Lemberg
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
For full copyright notices consult the individual files in the package.

146
NEWS
View File

@ -1,3 +1,149 @@
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
====================================

View File

@ -17,7 +17,7 @@
- [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
- [ ] Search for REPLACEME on the repository and replace it with the chosen version for the release.
- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
- [ ] Make sure you have correct date and new version at the top of NEWS file.

20
SECURITY.md Normal file
View File

@ -0,0 +1,20 @@
# Security Policy
If you have discovered a security vulnerability in this project, please report it
privately. **Do not disclose it as a public issue.** This gives me time to work with you
to fix the issue before public exposure, reducing the chance that the exploit will be
used before a patch is released.
You may submit the report in the following ways:
- send an email to behdad@behdad.org and harfbuzz-admin@googlegroups.com; and/or
- send me a [private vulnerability report](https://github.com/harfbuzz/harfbuzz/security/advisories/new)
Please provide the following information in your report:
- A description of the vulnerability and its impact
- How to reproduce the issue
This project is mostly maintained by two developers, working on a reasonable effort
basis. As such, we ask that you give us 90 days to work on a fix before public
disclosure.

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[6.0.0],
[7.1.0],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])

View File

@ -56,6 +56,7 @@
<xi:include href="xml/hb-blob.xml"/>
<xi:include href="xml/hb-buffer.xml"/>
<xi:include href="xml/hb-common.xml"/>
<xi:include href="xml/hb-features.xml"/>
<xi:include href="xml/hb-draw.xml"/>
<xi:include href="xml/hb-paint.xml"/>
<xi:include href="xml/hb-deprecated.xml"/>
@ -119,6 +120,8 @@
<index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
<index id="deprecated-api-index"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
<index id="api-index-7-1-0"><title>Index of new symbols in 7.1.0</title><xi:include href="xml/api-index-7.1.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-7-0-0"><title>Index of new symbols in 7.0.0</title><xi:include href="xml/api-index-7.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-6-0-0"><title>Index of new symbols in 6.0.0</title><xi:include href="xml/api-index-6.0.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-5-3-0"><title>Index of new symbols in 5.3.0</title><xi:include href="xml/api-index-5.3.0.xml"><xi:fallback /></xi:include></index>
<index id="api-index-5-0-0"><title>Index of new symbols in 5.0.0</title><xi:include href="xml/api-index-5.0.0.xml"><xi:fallback /></xi:include></index>

View File

@ -1,3 +1,4 @@
<SECTION>
<SUBSECTION Private>
HB_H_IN
HB_OT_H_IN
@ -166,15 +167,6 @@ HB_TAG_MAX_SIGNED
HB_LANGUAGE_INVALID
HB_FEATURE_GLOBAL_END
HB_FEATURE_GLOBAL_START
HB_HAS_CAIRO
HB_HAS_CORETEXT
HB_HAS_DIRECTWRITE
HB_HAS_FREETYPE
HB_HAS_GDI
HB_HAS_GLIB
HB_HAS_GRAPHITE
HB_HAS_ICU
HB_HAS_UNISCRIBE
<SUBSECTION Private>
HB_BEGIN_DECLS
HB_END_DECLS
@ -193,6 +185,20 @@ HB_DEPRECATED
HB_DEPRECATED_FOR
</SECTION>
<SECTION>
<FILE>hb-features</FILE>
HB_HAS_CAIRO
HB_HAS_CORETEXT
HB_HAS_DIRECTWRITE
HB_HAS_FREETYPE
HB_HAS_GDI
HB_HAS_GLIB
HB_HAS_GOBJECT
HB_HAS_GRAPHITE
HB_HAS_ICU
HB_HAS_UNISCRIBE
</SECTION>
<SECTION>
<FILE>hb-draw</FILE>
hb_draw_funcs_create
@ -270,6 +276,8 @@ hb_paint_push_group_func_t
hb_paint_funcs_set_push_group_func
hb_paint_pop_group_func_t
hb_paint_funcs_set_pop_group_func
hb_paint_custom_palette_color_func_t
hb_paint_funcs_set_custom_palette_color_func
hb_paint_push_transform
hb_paint_pop_transform
@ -283,6 +291,7 @@ hb_paint_radial_gradient
hb_paint_sweep_gradient
hb_paint_push_group
hb_paint_pop_group
hb_paint_custom_palette_color
</SECTION>
<SECTION>
@ -408,9 +417,12 @@ hb_font_set_ptem
hb_font_get_ptem
hb_font_set_scale
hb_font_get_scale
hb_font_get_synthetic_bold
hb_font_set_synthetic_bold
hb_font_set_synthetic_slant
hb_font_get_synthetic_slant
hb_font_set_variations
hb_font_set_variation
HB_FONT_NO_VAR_NAMED_INSTANCE
hb_font_set_var_named_instance
hb_font_get_var_named_instance
@ -594,8 +606,8 @@ hb_ot_name_list_names
hb_ot_name_get_utf16
hb_ot_name_get_utf32
hb_ot_name_get_utf8
HB_OT_NAME_ID_INVALID
hb_ot_name_id_t
hb_ot_name_id_predefined_t
hb_ot_name_entry_t
</SECTION>
@ -635,6 +647,7 @@ hb_ot_layout_lookup_would_substitute
hb_ot_layout_script_find_language
hb_ot_layout_script_get_language_tags
hb_ot_layout_script_select_language
hb_ot_layout_script_select_language2
hb_ot_layout_table_find_feature_variations
hb_ot_layout_table_get_feature_tags
hb_ot_layout_table_get_script_tags
@ -768,6 +781,7 @@ hb_set_t
<FILE>hb-shape</FILE>
hb_shape
hb_shape_full
hb_shape_justify
hb_shape_list_shapers
</SECTION>

View File

@ -36,6 +36,7 @@ html_images = [
]
ignore_headers = [
'hb-features.h',
'hb-gobject.h',
'hb-gobject-enums.h',
'hb-gobject-enums-tmp.h',
@ -58,4 +59,6 @@ gnome.gtkdoc('harfbuzz',
html_assets: html_images,
ignore_headers: ignore_headers,
dependencies: [libharfbuzz_dep],
install: true)
install: true,
check: get_option('doc_tests'),
)

View File

@ -182,8 +182,7 @@
</para>
<itemizedlist>
<listitem>
<para><emphasis>Level 0</emphasis> is the default and
reproduces the behavior of the old HarfBuzz library.
<para><emphasis>Level 0</emphasis> is the default.
</para>
<para>
The distinguishing feature of level 0 behavior is that, at
@ -194,7 +193,7 @@
as well as the <emphasis>Zero Width Joiner</emphasis> and
<emphasis>Zero Width Non-Joiner</emphasis> code points, are
assigned the cluster value of the closest preceding code
point from <emphasis>different</emphasis> category.
point from <emphasis>different</emphasis> category.
</para>
<para>
In essence, whenever a base character is followed by a mark
@ -206,6 +205,11 @@
url="https://www.unicode.org/reports/tr29/#Regex_Definitions">Unicode
Technical Report 29</ulink>.
</para>
<para>
This cluster level is suitable for code that likes to use
HarfBuzz cluster values as an approximation of the Unicode
Grapheme Cluster Boundaries as well.
</para>
<para>
Client programs can specify level 0 behavior for a buffer by
setting its <literal>cluster_level</literal> to
@ -220,13 +224,13 @@
implement backward compatibility with the old HarfBuzz.
</para>
<para>
Level 1 differs from level 0 by not merging the
<emphasis>Level 1</emphasis> differs from level 0 by not merging the
clusters of marks and other modifier code points with the
preceding "base" code point's cluster. By preserving the
separate cluster values of these marks and modifier code
points, script shapers can perform additional operations
that might lead to improved results (for example, reordering
a sequence of marks).
that might lead to improved results (for example, coloring
mark glyphs differently than their base).
</para>
<para>
Client programs can specify level 1 behavior for a buffer by
@ -242,7 +246,7 @@
</para>
<para>
This difference can be seen most clearly when HarfBuzz processes
ligature substitutions and glyph decompositions. In level 0
ligature substitutions and glyph decompositions. In level 0
and level 1, ligatures and glyph decomposition both involve
merging clusters; in level 2, neither of these operations
triggers a merge.
@ -259,7 +263,7 @@
assign initial cluster values in a buffer by reusing the indices
of the code points in the input text. This gives a sequence of
cluster values that is monotonically increasing (for example,
0,1,2,3,4).
0,1,2,3,4).
</para>
<para>
It is not <emphasis>required</emphasis> that the cluster values
@ -314,7 +318,7 @@
</listitem>
</itemizedlist>
</section>
<section id="a-clustering-example-for-levels-0-and-1">
<title>A clustering example for levels 0 and 1</title>
<para>

View File

@ -473,7 +473,7 @@
</para>
</section>
<section>
<section id="glyphs-and-rendering">
<title>Glyphs and rendering</title>
<para>

View File

@ -174,7 +174,9 @@
<para>
HarfBuzz provides integration points with FreeType at the
face-object and font-object level and for the font-functions
virtual-method structure of a font object. To use the
virtual-method structure of a font object. These functions
make it easy for clients that use FreeType for rasterization
or font-loading, to use HarfBuzz for shaping. To use the
FreeType-integration API, include the
<filename>hb-ft.h</filename> header.
</para>

View File

@ -1,8 +1,9 @@
project('harfbuzz', 'c', 'cpp',
meson_version: '>= 0.55.0',
version: '6.0.0',
version: '7.1.0',
default_options: [
'cpp_rtti=false', # Just to support msvc, we are passing -fno-exceptions also anyway
'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway
'cpp_rtti=false', # Just to support msvc, we are passing -fno-rtti also anyway
'cpp_std=c++11',
'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
],
@ -27,17 +28,12 @@ if cpp.get_argument_syntax() == 'msvc'
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
# NOTE: Only add warnings here if you are sure they're spurious
msvc_args = [
'/wd4018', # implicit signed/unsigned conversion
'/wd4146', # unary minus on unsigned (beware INT_MIN)
'/wd4244', # lossy type conversion (e.g. double -> int)
'/wd4305', # truncating type conversion (e.g. double -> float)
cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
]
add_project_arguments(msvc_args, language: ['c', 'cpp'])
# Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
# noseh_link_args = ['/SAFESEH:NO']
# disable exception handling
add_project_arguments(['/EHs-', '/EHc-'], language: 'cpp')
endif
add_project_link_arguments(cpp.get_supported_link_arguments([
@ -209,10 +205,19 @@ endif
if cairo_dep.found()
conf.set('HAVE_CAIRO', 1)
check_cairo_funcs = [
['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}],
['cairo_font_options_get_custom_palette_color', {'deps': cairo_dep}],
['cairo_user_scaled_font_get_foreground_source', {'deps': cairo_dep}],
]
if cairo_dep.type_name() == 'internal'
conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
foreach func: check_cairo_funcs
name = func[0]
conf.set('HAVE_@0@'.format(name.to_upper()), 1)
endforeach
else
check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
check_funcs += check_cairo_funcs
endif
endif
@ -368,7 +373,10 @@ foreach check : check_funcs
endforeach
subdir('src')
subdir('util')
if not get_option('utilities').disabled()
subdir('util')
endif
if not get_option('tests').disabled()
subdir('test')
@ -384,6 +392,9 @@ endif
configure_file(output: 'config.h', configuration: conf)
alias_target('lib', libharfbuzz)
alias_target('libs', libharfbuzz, libharfbuzz_subset)
build_summary = {
'Directories':
{'prefix': get_option('prefix'),
@ -398,7 +409,8 @@ build_summary = {
'ICU': conf.get('HAVE_ICU', 0) == 1,
},
'Font callbacks (the more the merrier)':
{'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
{'Builtin' : true,
'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
},
'Dependencies used for command-line utilities':
{'Cairo': conf.get('HAVE_CAIRO', 0) == 1,
@ -415,6 +427,7 @@ build_summary = {
'Other features':
{'Documentation': conf.get('HAVE_GTK_DOC', 0) == 1,
'GObject bindings': conf.get('HAVE_GOBJECT', 0) == 1,
'Cairo integration': conf.get('HAVE_CAIRO', 0) == 1,
'Introspection': conf.get('HAVE_INTROSPECTION', 0) == 1,
'Experimental APIs': conf.get('HB_EXPERIMENTAL_API', 0) == 1,
},

View File

@ -29,6 +29,10 @@ option('introspection', type: 'feature', value: 'auto', yield: true,
description: 'Generate gobject-introspection bindings (.gir/.typelib files)')
option('docs', type: 'feature', value: 'auto', yield: true,
description: 'Generate documentation with gtk-doc')
option('doc_tests', type: 'boolean', value: false,
description: 'Run gtkdoc-check tests')
option('utilities', type: 'feature', value: 'enabled', yield: true,
description: 'Build harfbuzz utils')
option('benchmark', type: 'feature', value: 'disabled',
description: 'Enable benchmark tests')

View File

@ -254,6 +254,9 @@ hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS)
--template $^ | \
sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
|| ($(RM) "$@"; false)
HB_HAS_GOBJECT_DEF = define HB_HAS_GOBJECT 1
else
HB_HAS_GOBJECT_DEF = undef HB_HAS_GOBJECT
endif
EXTRA_DIST += \
harfbuzz-gobject.pc.in \
@ -275,6 +278,7 @@ hb-features.h: hb-features.h.in $(top_builddir)/config.status
-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
-e 's/mesondefine HB_HAS_GRAPHITE/$(HB_HAS_GRAPHITE_DEF)/' \
-e 's/mesondefine HB_HAS_GLIB/$(HB_HAS_GLIB_DEF)/' \
-e 's/mesondefine HB_HAS_GOBJECT/$(HB_HAS_GOBJECT_DEF)/' \
-e 's/mesondefine HB_HAS_UNISCRIBE/$(HB_HAS_UNISCRIBE_DEF)/' \
-e 's/mesondefine HB_HAS_DIRECTWRITE/$(HB_HAS_DIRECTWRITE_DEF)/' \
-e 's/mesondefine HB_HAS_CORETEXT/$(HB_HAS_CORETEXT_DEF)/' \
@ -378,6 +382,7 @@ noinst_PROGRAMS = \
test-ot-name \
test-ot-glyphname \
test-gpos-size-params \
test-gsub-get-alternates \
test-gsub-would-substitute \
test-use-table \
$(NULL)
@ -415,6 +420,10 @@ test_gpos_size_params_SOURCES = test-gpos-size-params.cc
test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
test_gsub_get_alternates_SOURCES = test-gsub-get-alternates.cc
test_gsub_get_alternates_CPPFLAGS = $(HBCFLAGS)
test_gsub_get_alternates_LDADD = libharfbuzz.la $(HBLIBS)
test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)

View File

@ -85,6 +85,8 @@ HB_BASE_sources = \
hb-ot-layout-common.hh \
hb-ot-layout-gdef-table.hh \
hb-ot-layout-gpos-table.hh \
hb-outline.hh \
hb-outline.cc \
hb-paint.cc \
hb-paint.hh \
hb-paint-extents.cc \
@ -112,6 +114,7 @@ HB_BASE_sources = \
OT/Layout/Common/CoverageFormat1.hh \
OT/Layout/Common/CoverageFormat2.hh \
OT/Layout/Common/RangeRecord.hh \
OT/Layout/GDEF/GDEF.hh \
OT/Layout/GPOS/AnchorFormat1.hh \
OT/Layout/GPOS/AnchorFormat2.hh \
OT/Layout/GPOS/AnchorFormat3.hh \
@ -166,6 +169,7 @@ HB_BASE_sources = \
OT/Layout/GSUB/SingleSubst.hh \
OT/Layout/GSUB/SubstLookup.hh \
OT/Layout/GSUB/SubstLookupSubTable.hh \
OT/name/name.hh \
hb-ot-layout-gsubgpos.hh \
hb-ot-layout-jstf-table.hh \
hb-ot-layout.cc \
@ -221,6 +225,7 @@ HB_BASE_sources = \
hb-ot-tag.cc \
hb-ot-var-avar-table.hh \
hb-ot-var-common.hh \
hb-ot-var-cvar-table.hh \
hb-ot-var-fvar-table.hh \
hb-ot-var-gvar-table.hh \
hb-ot-var-hvar-table.hh \
@ -256,7 +261,8 @@ HB_BASE_sources = \
HB_BASE_RAGEL_GENERATED_sources = \
hb-buffer-deserialize-json.hh \
hb-buffer-deserialize-text.hh \
hb-buffer-deserialize-text-glyphs.hh \
hb-buffer-deserialize-text-unicode.hh \
hb-number-parser.hh \
hb-ot-shaper-indic-machine.hh \
hb-ot-shaper-khmer-machine.hh \
@ -265,7 +271,8 @@ HB_BASE_RAGEL_GENERATED_sources = \
$(NULL)
HB_BASE_RAGEL_sources = \
hb-buffer-deserialize-json.rl \
hb-buffer-deserialize-text.rl \
hb-buffer-deserialize-text-glyphs.rl \
hb-buffer-deserialize-text-unicode.rl \
hb-number-parser.rl \
hb-ot-shaper-indic-machine.rl \
hb-ot-shaper-khmer-machine.rl \
@ -351,6 +358,7 @@ HB_SUBSET_sources = \
hb-subset-cff2.hh \
hb-subset-input.cc \
hb-subset-input.hh \
hb-subset-instancer-solver.cc \
hb-subset-accelerator.hh \
hb-subset-plan.cc \
hb-subset-plan.hh \

View File

@ -30,7 +30,6 @@
#include "../../../hb.hh"
#include "../../../hb-open-type.hh"
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-ot-var-common.hh"
#include "../../../hb-paint.hh"
#include "../../../hb-paint-extents.hh"
@ -41,7 +40,6 @@
*/
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
namespace OT {
struct hb_paint_context_t;
}
@ -67,7 +65,7 @@ public:
hb_paint_funcs_t *funcs;
void *data;
hb_font_t *font;
unsigned int palette;
unsigned int palette_index;
hb_color_t foreground;
VarStoreInstancer &instancer;
int depth_left = HB_MAX_NESTING_LEVEL;
@ -84,7 +82,7 @@ public:
funcs (funcs_),
data (data_),
font (font_),
palette (palette_),
palette_index (palette_),
foreground (foreground_),
instancer (instancer_)
{ }
@ -97,10 +95,14 @@ public:
if (color_index != 0xffff)
{
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
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);
}
hb_ot_color_palette_get_colors (face, palette, color_index, &clen, &color);
*is_foreground = false;
}
@ -239,10 +241,15 @@ struct Variable
void closurev1 (hb_colrv1_closure_context_t* c) const
{ value.closurev1 (c); }
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
if (!value.subset (c)) return_trace (false);
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));
}
@ -293,10 +300,11 @@ struct NoVariable
void closurev1 (hb_colrv1_closure_context_t* c) const
{ value.closurev1 (c); }
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
return_trace (value.subset (c));
return_trace (value.subset (c, instancer, varIdxBase));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -334,11 +342,20 @@ struct ColorStop
void closurev1 (hb_colrv1_closure_context_t* c) const
{ c->add_palette_index (paletteIndex); }
bool subset (hb_subset_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->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));
}
@ -387,7 +404,8 @@ struct ColorLine
stop.closurev1 (c);
}
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -399,7 +417,7 @@ struct ColorLine
for (const auto& stop : stops.iter ())
{
if (!stop.subset (c)) return_trace (false);
if (!stop.subset (c, instancer)) return_trace (false);
}
return_trace (true);
}
@ -520,6 +538,25 @@ struct Affine2x3
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,
@ -545,7 +582,8 @@ struct PaintColrLayers
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
@ -576,11 +614,20 @@ struct PaintSolid
void closurev1 (hb_colrv1_closure_context_t* c) const
{ c->add_palette_index (paletteIndex); }
bool subset (hb_subset_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->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));
}
@ -615,13 +662,28 @@ struct PaintLinearGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_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);
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
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
@ -666,13 +728,28 @@ struct PaintRadialGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_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);
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
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
@ -717,13 +794,26 @@ struct PaintSweepGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_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);
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
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
@ -743,8 +833,8 @@ struct PaintSweepGradient
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) * (float) M_PI,
(endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
(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) */
@ -763,7 +853,8 @@ struct PaintGlyph
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
@ -773,7 +864,7 @@ struct PaintGlyph
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
return_trace (out->paint.serialize_subset (c, paint, this));
return_trace (out->paint.serialize_subset (c, paint, this, instancer));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -804,7 +895,8 @@ struct PaintColrGlyph
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
@ -833,13 +925,16 @@ struct PaintTransform
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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_copy (c->serializer, transform, this)) return_trace (false);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -868,13 +963,24 @@ struct PaintTranslate
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -905,13 +1011,24 @@ struct PaintScale
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -942,13 +1059,26 @@ struct PaintScaleAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -987,13 +1117,21 @@ struct PaintScaleUniform
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1022,13 +1160,25 @@ struct PaintScaleUniformAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1065,13 +1215,21 @@ struct PaintRotate
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1100,13 +1258,25 @@ struct PaintRotateAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1143,13 +1313,24 @@ struct PaintSkew
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1180,13 +1361,26 @@ struct PaintSkewAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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);
return_trace (out->src.serialize_subset (c, src, this));
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
@ -1225,14 +1419,15 @@ struct PaintComposite
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_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)) return_trace (false);
return_trace (out->backdrop.serialize_subset (c, backdrop, this));
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
@ -1280,6 +1475,28 @@ struct ClipBoxFormat1
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;
@ -1307,21 +1524,22 @@ struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
struct ClipBox
{
ClipBox* copy (hb_serialize_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SERIALIZE (this);
TRACE_SUBSET (this);
switch (u.format) {
case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1)));
case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2)));
default:return_trace (nullptr);
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);
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, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
@ -1364,13 +1582,15 @@ struct ClipRecord
int cmp (hb_codepoint_t g) const
{ return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
bool subset (hb_subset_context_t *c,
const void *base,
const VarStoreInstancer &instancer) const
{
TRACE_SERIALIZE (this);
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
return_trace (out);
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
@ -1397,7 +1617,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
struct ClipList
{
unsigned serialize_clip_records (hb_serialize_context_t *c,
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
{
@ -1429,7 +1650,7 @@ struct ClipList
record.endGlyphID = prev_gid;
record.clipBox = prev_offset;
if (!c->copy (record, this)) return_trace (0);
if (!record.subset (c, this, instancer)) return_trace (0);
count++;
start_gid = _;
@ -1443,13 +1664,14 @@ struct ClipList
record.startGlyphID = start_gid;
record.endGlyphID = prev_gid;
record.clipBox = prev_offset;
if (!c->copy (record, this)) return_trace (0);
if (!record.subset (c, this, instancer)) return_trace (0);
count++;
}
return_trace (count);
}
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
@ -1474,7 +1696,7 @@ struct ClipList
}
}
unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
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));
}
@ -1523,8 +1745,8 @@ struct Paint
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);
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.paintformat1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
@ -1608,7 +1830,8 @@ struct BaseGlyphPaintRecord
{ 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
const void* src_base, hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SERIALIZE (this);
auto *out = s->embed (this);
@ -1617,7 +1840,7 @@ struct BaseGlyphPaintRecord
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
return_trace (out->paint.serialize_subset (c, paint, src_base));
return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
@ -1636,7 +1859,8 @@ struct BaseGlyphPaintRecord
struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
{
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -1648,7 +1872,7 @@ struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
unsigned gid = _.glyphId;
if (!glyphset->has (gid)) continue;
if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
else return_trace (false);
}
@ -1667,7 +1891,8 @@ struct LayerList : Array32OfOffset32To<Paint>
const Paint& get_paint (unsigned i) const
{ return this+(*this)[i]; }
bool subset (hb_subset_context_t *c) const
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -1678,7 +1903,7 @@ struct LayerList : Array32OfOffset32To<Paint>
{
auto *o = out->serialize_append (c->serializer);
if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
return_trace (false);
}
return_trace (true);
@ -1880,7 +2105,6 @@ struct COLR
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;
@ -1951,7 +2175,12 @@ struct COLR
auto snap = c->serializer->snapshot ();
if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
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
@ -1961,10 +2190,13 @@ struct COLR
if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
colr_prime->layerList.serialize_subset (c, layerList, this);
colr_prime->clipList.serialize_subset (c, clipList, this);
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);
//TODO: subset varStore once it's implemented in fonttools
colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
return_trace (true);
}
@ -1981,19 +2213,18 @@ struct COLR
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,
VarStoreInstancer instancer (&(this+varStore),
&(this+varIdxMap),
hb_array (font->coords, font->num_coords));
if ((this+clipList).get_extents (glyph,
extents,
instancer))
if (get_clip (glyph, extents, instancer))
{
font->scale_glyph_extents (extents);
return true;
@ -2001,16 +2232,27 @@ struct COLR
auto *extents_funcs = hb_paint_extents_get_funcs ();
hb_paint_extents_context_t extents_data;
paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
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 ();
extents->x_bearing = e.xmin;
extents->y_bearing = e.ymax;
extents->width = e.xmax - e.xmin;
extents->height = e.ymin - e.ymax;
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 true;
return ret;
}
#endif
bool
has_paint_for_glyph (hb_codepoint_t glyph) const
@ -2025,13 +2267,23 @@ struct COLR
return false;
}
bool
paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground, bool clip = true) const
bool get_clip (hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
const VarStoreInstancer instancer) const
{
VarStoreInstancer instancer (this+varStore,
this+varIdxMap,
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, foreground, instancer);
hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
if (version == 1)
{
@ -2040,17 +2292,15 @@ struct COLR
{
// COLRv1 glyph
VarStoreInstancer instancer (this+varStore,
this+varIdxMap,
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 ((this+clipList).get_extents (glyph,
&extents,
instancer))
if (get_clip (glyph, &extents, instancer))
{
font->scale_glyph_extents (&extents);
c.funcs->push_clip_rectangle (c.data,
@ -2066,7 +2316,7 @@ struct COLR
paint_glyph (font, glyph,
extents_funcs, &extents_data,
palette, foreground,
palette_index, foreground,
false);
hb_extents_t extents = extents_data.get_extents ();
@ -2113,6 +2363,7 @@ struct COLR
return false;
}
#endif
protected:
HBUINT16 version; /* Table version number (starts at 0). */
@ -2163,9 +2414,21 @@ 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);
// TODO apply clipbox
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 */

View File

@ -28,7 +28,6 @@
#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
#include "../../../hb-open-type.hh"
#include "../../../hb-ot-layout-common.hh"
#include "COLR.hh"
/*

View File

@ -73,6 +73,30 @@ struct CPALV1Tail
}
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,
@ -95,13 +119,10 @@ struct CPALV1Tail
if (colorLabelsZ)
{
c->push ();
for (const auto _ : colorLabels)
for (unsigned i = 0; i < color_count; i++)
{
const hb_codepoint_t *v;
if (!color_index_map->has (_, &v)) continue;
NameID new_color_idx;
new_color_idx = *v;
if (!c->copy<NameID> (new_color_idx))
if (!color_index_map->has (i)) continue;
if (!c->copy<NameID> (colorLabels[i]))
{
c->pop_discard ();
return_trace (false);
@ -189,6 +210,13 @@ struct CPAL
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
{

View File

@ -29,7 +29,6 @@
#define OT_COLOR_SBIX_SBIX_HH
#include "../../../hb-open-type.hh"
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-paint.hh"
/*

918
src/OT/Layout/GDEF/GDEF.hh Normal file
View File

@ -0,0 +1,918 @@
/*
* 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 */

View File

@ -19,8 +19,8 @@ struct CursivePos
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);
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, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());

View File

@ -22,8 +22,8 @@ struct MarkBasePos
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -90,6 +90,25 @@ struct MarkBasePosFormat1_2
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);
@ -97,48 +116,54 @@ struct MarkBasePosFormat1_2
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 */
/* 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.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
{
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
return_trace (false);
}
/* 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 */
if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
(skippy_iter.idx == 0 ||
_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
_hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1
))
break;
skippy_iter.reject ();
} while (true);
/* 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)
if (c->last_base_until > buffer->idx)
{
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
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);
}
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
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

View File

@ -22,8 +22,8 @@ struct MarkLigPos
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -100,24 +100,41 @@ struct MarkLigPosFormat1_2
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.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
if (c->last_base_until > buffer->idx)
{
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
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);
}
/* 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 idx = (unsigned) c->last_base;
unsigned int j = skippy_iter.idx;
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
/* 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 (skippy_iter.idx, buffer->idx + 1);
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
return_trace (false);
}
@ -128,7 +145,7 @@ struct MarkLigPosFormat1_2
unsigned int comp_count = lig_attach.rows;
if (unlikely (!comp_count))
{
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
return_trace (false);
}
@ -137,7 +154,7 @@ struct MarkLigPosFormat1_2
* 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 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)
@ -145,7 +162,7 @@ struct MarkLigPosFormat1_2
else
comp_index = comp_count - 1;
return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
}
bool subset (hb_subset_context_t *c) const

View File

@ -22,8 +22,8 @@ struct MarkMarkPos
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -25,8 +25,8 @@ struct PairPos
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);
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, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

View File

@ -43,7 +43,7 @@ struct PairPosFormat1_3
{
valueFormat,
len1,
1 + len1 + len2
PairSet::get_size (len1, len2)
};
return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
@ -55,7 +55,7 @@ struct PairPosFormat1_3
if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
{
for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
for (hb_codepoint_t g : glyphs->iter())
{
unsigned i = cov.get_coverage (g);
if ((this+pairSet[i]).intersects (glyphs, valueFormat))
@ -177,9 +177,7 @@ struct PairPosFormat1_3
hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
{
unsigned len1 = valueFormat[0].get_len ();
unsigned len2 = valueFormat[1].get_len ();
unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
unsigned record_size = PairSet::get_size (valueFormat);
unsigned format1 = 0;
unsigned format2 = 0;

View File

@ -49,7 +49,7 @@ struct PairPosFormat2_4
unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len ();
unsigned int stride = len1 + len2;
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,

View File

@ -24,11 +24,22 @@ struct PairSet
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; /* 1 + len1 + len2 */
unsigned int stride; /* bytes */
};
bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
@ -37,7 +48,6 @@ struct PairSet
if (!(c->check_struct (this)
&& c->check_range (&firstPairValueRecord,
len,
HBUINT16::static_size,
closure->stride))) return_trace (false);
unsigned int count = len;
@ -49,9 +59,7 @@ struct PairSet
bool intersects (const hb_set_t *glyphs,
const ValueFormat *valueFormats) const
{
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
unsigned record_size = get_size (valueFormats);
const PairValueRecord *record = &firstPairValueRecord;
unsigned int count = len;
@ -67,9 +75,7 @@ struct PairSet
void collect_glyphs (hb_collect_glyphs_context_t *c,
const ValueFormat *valueFormats) const
{
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
unsigned record_size = get_size (valueFormats);
const PairValueRecord *record = &firstPairValueRecord;
c->input->add_array (&record->secondGlyph, len, record_size);
@ -78,9 +84,7 @@ struct PairSet
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
const ValueFormat *valueFormats) const
{
unsigned len1 = valueFormats[0].get_len ();
unsigned len2 = valueFormats[1].get_len ();
unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
unsigned record_size = get_size (valueFormats);
const PairValueRecord *record = &firstPairValueRecord;
unsigned count = len;
@ -101,7 +105,7 @@ struct PairSet
hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
unsigned record_size = get_size (len1, len2);
const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
&firstPairValueRecord,
@ -168,7 +172,7 @@ struct PairSet
unsigned len1 = valueFormats[0].get_len ();
unsigned len2 = valueFormats[1].get_len ();
unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
unsigned record_size = get_size (len1, len2);
typename PairValueRecord::context_t context =
{

View File

@ -72,8 +72,8 @@ struct SinglePos
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);
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, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

View File

@ -28,7 +28,15 @@ struct SinglePosFormat1
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

View File

@ -371,7 +371,7 @@ struct ValueFormat : HBUINT16
for (unsigned int i = 0; i < count; i++) {
if (!sanitize_value_devices (c, base, values))
return_trace (false);
values += stride;
values = &StructAtOffset<const Value> (values, stride);
}
return_trace (true);

View File

@ -23,8 +23,8 @@ struct AlternateSubst
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -29,6 +29,9 @@ struct Ligature
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;

View File

@ -34,6 +34,18 @@ struct LigatureSet
;
}
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)

View File

@ -23,8 +23,8 @@ struct LigatureSubst
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -130,7 +130,7 @@ struct LigatureSubstFormat1_2
+ hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
| hb_filter (glyphset, hb_first)
| hb_filter ([&] (const LigatureSet<Types>& _) {
return _.intersects (&glyphset);
return _.intersects_lig_glyph (&glyphset);
}, hb_second)
| hb_map (hb_first)
| hb_sink (new_coverage);

View File

@ -24,8 +24,8 @@ struct MultipleSubst
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);
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, std::forward<Ts> (ds)...));
#ifndef HB_NO_BEYOND_64K

View File

@ -20,8 +20,8 @@ struct ReverseChainSingleSubst
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);
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, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());

View File

@ -27,8 +27,8 @@ struct SingleSubst
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);
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, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

View File

@ -25,7 +25,15 @@ struct SingleSubstFormat1_3
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
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
@ -87,6 +95,34 @@ struct SingleSubstFormat1_3
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);

View File

@ -75,6 +75,31 @@ struct SingleSubstFormat2_4
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);

View File

@ -87,27 +87,34 @@ struct CompositeGlyphRecord
}
}
void transform_points (contour_point_vector_t &points) const
void transform_points (contour_point_vector_t &points,
const float (&matrix)[4],
const contour_point_t &trans) const
{
float matrix[4];
contour_point_t trans;
if (get_transformation (matrix, trans))
if (scaled_offsets ())
{
if (scaled_offsets ())
{
points.translate (trans);
points.transform (matrix);
}
else
{
points.transform (matrix);
points.translate (trans);
}
points.translate (trans);
points.transform (matrix);
}
else
{
points.transform (matrix);
points.translate (trans);
}
}
unsigned compile_with_deltas (const contour_point_t &p_delta,
char *out) const
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
@ -121,18 +128,17 @@ struct CompositeGlyphRecord
unsigned len_before_val = (const char *)p - (const char *)this;
if (flags & ARG_1_AND_2_ARE_WORDS)
{
// no overflow, copy and update value with deltas
// no overflow, copy value
hb_memcpy (out, this, len);
const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
o[0] = px[0] + roundf (p_delta.x);
o[1] = px[1] + roundf (p_delta.y);
o[0] = roundf (point.x);
o[1] = roundf (point.y);
}
else
{
int new_x = p[0] + roundf (p_delta.x);
int new_y = p[1] + roundf (p_delta.y);
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)
{
@ -143,7 +149,7 @@ struct CompositeGlyphRecord
}
else
{
// int8 overflows after deltas applied
// new point value has an int8 overflow
hb_memcpy (out, this, len_before_val);
//update flags
@ -171,6 +177,7 @@ struct CompositeGlyphRecord
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;
@ -225,7 +232,6 @@ struct CompositeGlyphRecord
return tx || ty;
}
public:
hb_codepoint_t get_gid () const
{
#ifndef HB_NO_BEYOND_64K
@ -246,6 +252,27 @@ struct CompositeGlyphRecord
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;
@ -304,7 +331,7 @@ struct CompositeGlyph
}
bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
const contour_point_vector_t &deltas,
const contour_point_vector_t &points_with_deltas,
hb_bytes_t &dest_bytes /* OUT */)
{
if (source_bytes.length <= GlyphHeader::static_size ||
@ -319,7 +346,7 @@ struct CompositeGlyph
/* 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 + source_len/2, sizeof (char));
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);
@ -329,8 +356,11 @@ struct CompositeGlyph
unsigned i = 0, source_comp_len = 0;
for (const auto &component : it)
{
/* last 4 points in deltas are phantom points and should not be included */
if (i >= deltas.length - 4) return false;
/* 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 ())
@ -340,7 +370,7 @@ struct CompositeGlyph
}
else
{
unsigned new_len = component.compile_with_deltas (deltas[i], p);
unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
p += new_len;
}
i++;

View File

@ -29,7 +29,14 @@ enum phantom_point_index_t
struct Glyph
{
enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
enum glyph_type_t {
EMPTY,
SIMPLE,
COMPOSITE,
#ifndef HB_NO_VAR_COMPOSITES
VAR_COMPOSITE,
#endif
};
public:
composite_iter_t get_composite_iterator () const
@ -39,15 +46,23 @@ struct Glyph
}
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;
}
}
@ -55,38 +70,54 @@ struct Glyph
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;
default: 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;
default: 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;
default: return;
case EMPTY: return;
}
}
void update_mtx (const hb_subset_plan_t *plan,
int xMin, int yMax,
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;
@ -97,6 +128,9 @@ struct Glyph
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;
@ -109,7 +143,7 @@ struct Glyph
hb_bytes_t &dest_bytes /* OUT */) const
{
GlyphHeader *glyph_header = nullptr;
if (type != EMPTY && all_points.length > 4)
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;
@ -133,18 +167,33 @@ struct Glyph
yMax = hb_max (yMax, y);
}
update_mtx (plan, roundf (xMin), roundf (yMax), all_points);
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);
/*for empty glyphs: all_points only include phantom points.
*just update metrics and then return */
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 = roundf (xMin);
glyph_header->yMin = roundf (yMin);
glyph_header->xMax = roundf (xMax);
glyph_header->yMax = roundf (yMax);
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;
@ -156,35 +205,64 @@ struct Glyph
hb_bytes_t &dest_start, /* IN/OUT */
hb_bytes_t &dest_end /* OUT */)
{
contour_point_vector_t all_points, deltas;
if (!get_points (font, glyf, all_points, &deltas, false, false))
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;
switch (type) {
case COMPOSITE:
if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
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;
default:
/* set empty bytes for empty glyph
* do not use source glyph's pointers */
dest_start = hb_bytes_t ();
dest_end = hb_bytes_t ();
break;
}
//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))
@ -202,14 +280,26 @@ struct Glyph
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 *deltas = nullptr, /* 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) const
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);
@ -221,14 +311,17 @@ struct Glyph
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:
{
/* pseudo component points for each component in composite glyph */
unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ());
if (unlikely (!points.resize (num_points))) return false;
for (auto &item : get_composite_iterator ())
if (unlikely (!item.get_points (points))) return false;
break;
}
#ifndef HB_NO_VAR_COMPOSITES
@ -238,7 +331,7 @@ struct Glyph
if (unlikely (!item.get_points (points))) return false;
}
#endif
default:
case EMPTY:
break;
}
@ -266,17 +359,11 @@ struct Glyph
#endif
;
phantoms[PHANTOM_LEFT].x = h_delta;
phantoms[PHANTOM_RIGHT].x = h_adv + 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;
}
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
{
if (unlikely (!deltas->resize (points.length))) return false;
deltas->copy_vector (points);
}
#ifndef HB_NO_VAR
glyf_accelerator.gvar->apply_deltas_to_points (gid,
coords,
@ -285,17 +372,16 @@ struct Glyph
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
// with child glyphs' points
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
{
for (unsigned i = 0 ; i < points.length; i++)
{
deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x;
deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y;
}
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;
@ -306,17 +392,19 @@ struct Glyph
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,
deltas,
points_with_deltas,
head_maxp_info,
composite_contours,
shift_points_hori,
use_my_metrics,
phantom_only,
coords,
depth + 1)))
depth + 1,
edge_count)))
return false;
/* Copy phantom points from component if USE_MY_METRICS flag set */
@ -324,11 +412,12 @@ struct Glyph
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
/* Apply component transformation & translation */
item.transform_points (comp_points);
float matrix[4];
contour_point_t default_trans;
item.get_transformation (matrix, default_trans);
/* Apply translation from gvar */
comp_points.translate (points[comp_index]);
/* Apply component transformation & translation (with deltas applied) */
item.transform_points (comp_points, matrix, points[comp_index]);
if (item.is_anchored ())
{
@ -352,6 +441,13 @@ struct Glyph
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
@ -365,19 +461,26 @@ struct Glyph
comp_points.reset ();
coord_setter_t coord_setter (hb_array (font->coords, font->num_coords));
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,
deltas,
points_with_deltas,
head_maxp_info,
nullptr,
shift_points_hori,
use_my_metrics,
phantom_only,
coord_setter.get_coords (),
depth + 1)))
depth + 1,
edge_count)))
return false;
/* Apply component transformation */
@ -398,7 +501,7 @@ struct Glyph
all_points.extend (phantoms);
} break;
#endif
default:
case EMPTY:
all_points.extend (phantoms);
break;
}
@ -424,6 +527,8 @@ struct Glyph
}
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> ()),
@ -439,7 +544,9 @@ struct Glyph
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 */
}
@ -447,7 +554,7 @@ struct Glyph
hb_bytes_t bytes;
const GlyphHeader *header;
hb_codepoint_t gid;
unsigned type;
glyph_type_t type;
};

View File

@ -20,7 +20,7 @@ struct SimpleGlyph
FLAG_X_SAME = 0x10,
FLAG_Y_SAME = 0x20,
FLAG_OVERLAP_SIMPLE = 0x40,
FLAG_RESERVED2 = 0x80
FLAG_CUBIC = 0x80
};
const GlyphHeader &header;
@ -34,6 +34,11 @@ struct SimpleGlyph
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 ();
@ -94,6 +99,7 @@ struct SimpleGlyph
/* 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;
}

View File

@ -18,23 +18,21 @@ struct SubsetGlyph
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,
hb_font_t *font)
const hb_subset_plan_t *plan)
{
TRACE_SERIALIZE (this);
if (font)
{
const OT::glyf_accelerator_t &glyf = *font->face->table.glyf;
if (!this->compile_bytes_with_deltas (plan, font, glyf))
return_trace (false);
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;
}
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
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);
@ -48,13 +46,68 @@ struct SubsetGlyph
if (unlikely (!dest_glyph.length)) return_trace (true);
/* update components gids */
/* 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 ();
@ -68,12 +121,18 @@ struct SubsetGlyph
bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
hb_font_t *font,
const glyf_accelerator_t &glyf)
{ return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); }
{
allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
return allocated;
}
void free_compiled_bytes ()
{
dest_start.fini ();
dest_end.fini ();
if (likely (allocated)) {
allocated = false;
dest_start.fini ();
dest_end.fini ();
}
}
void drop_hints_bytes ()

View File

@ -27,8 +27,9 @@ struct VarCompositeGlyphRecord
HAVE_SKEW_Y = 0x0200,
HAVE_TCENTER_X = 0x0400,
HAVE_TCENTER_Y = 0x0800,
GID_IS_24 = 0x1000,
GID_IS_24BIT = 0x1000,
AXES_HAVE_VARIATION = 0x2000,
RESET_UNSPECIFIED_AXES = 0x4000,
};
public:
@ -42,7 +43,7 @@ struct VarCompositeGlyphRecord
// gid
size += 2;
if (flags & GID_IS_24) size += 1;
if (flags & GID_IS_24BIT) size += 1;
if (flags & HAVE_TRANSLATE_X) size += 2;
if (flags & HAVE_TRANSLATE_Y) size += 2;
@ -60,15 +61,24 @@ struct VarCompositeGlyphRecord
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_24)
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;
@ -143,7 +153,7 @@ struct VarCompositeGlyphRecord
float rotation)
{
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
rotation = rotation * float (M_PI);
rotation = rotation * HB_PI;
float c = cosf (rotation);
float s = sinf (rotation);
float other[6] = {c, s, -s, c, 0.f, 0.f};
@ -154,8 +164,8 @@ struct VarCompositeGlyphRecord
float skewX, float skewY)
{
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
skewX = skewX * float (M_PI);
skewY = skewY * float (M_PI);
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);
}
@ -178,7 +188,7 @@ struct VarCompositeGlyphRecord
unsigned axes_size = numAxes * axis_width;
const F2DOT14 *q = (const F2DOT14 *) (axes_size +
(flags & GID_IS_24 ? 3 : 2) +
(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 - get_num_points ());
@ -306,8 +316,8 @@ struct VarCompositeGlyphRecord
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_24 ? 3 : 2));
const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
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)));
@ -342,6 +352,13 @@ struct VarCompositeGlyph
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);
}
};

View File

@ -44,6 +44,20 @@ _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
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);

View File

@ -31,6 +31,12 @@ struct glyf
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);
@ -43,14 +49,13 @@ struct glyf
bool serialize (hb_serialize_context_t *c,
Iterator it,
bool use_short_loca,
const hb_subset_plan_t *plan,
hb_font_t *font)
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, font)))
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
@ -73,62 +78,82 @@ struct glyf
{
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_vector_t<glyf_impl::SubsetGlyph> glyphs;
_populate_subset_glyphs (c->plan, glyphs);
hb_font_t *font = nullptr;
if (!c->plan->pinned_at_default)
if (c->plan->normalized_coords)
{
font = _create_font_for_instancing (c->plan);
if (unlikely (!font)) return false;
}
auto padded_offsets =
+ hb_iter (glyphs)
| hb_map (&glyf_impl::SubsetGlyph::padded_size)
;
bool use_short_loca = false;
if (likely (!c->plan->force_long_loca))
hb_vector_t<unsigned> padded_offsets;
unsigned num_glyphs = c->plan->num_output_glyphs ();
if (unlikely (!padded_offsets.resize (num_glyphs)))
{
unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
use_short_loca = max_offset < 0x1FFFF;
hb_font_destroy (font);
return false;
}
glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan, font);
if (!use_short_loca) {
padded_offsets =
+ hb_iter (glyphs)
| hb_map (&glyf_impl::SubsetGlyph::length)
;
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
if (!_populate_subset_glyphs (c->plan, font, glyphs))
{
hb_font_destroy (font);
return false;
}
if (font)
{
_free_compiled_subset_glyphs (&glyphs);
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,
padded_offsets.iter (),
use_short_loca)));
}
void
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
void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs) const
{
for (auto _ : *glyphs)
_.free_compiled_bytes ();
for (unsigned i = 0; i < glyphs.length; i++)
glyphs[i].free_compiled_bytes ();
}
protected:
@ -156,7 +181,7 @@ struct glyf_accelerator_t
vmtx = nullptr;
#endif
const OT::head &head = *face->table.head;
if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
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;
@ -194,7 +219,7 @@ struct glyf_accelerator_t
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, true, true, phantom_only)))
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 ())
@ -216,6 +241,8 @@ struct glyf_accelerator_t
return true;
}
public:
#ifndef HB_NO_VAR
struct points_aggregator_t
{
@ -279,7 +306,6 @@ struct glyf_accelerator_t
contour_point_t *get_phantoms_sink () { return phantoms; }
};
public:
unsigned
get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
{
@ -321,6 +347,15 @@ struct glyf_accelerator_t
}
#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
{
@ -390,13 +425,14 @@ struct glyf_accelerator_t
};
inline void
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;
if (!glyphs.resize (num_glyphs)) return false;
for (auto p : plan->glyph_map->iter ())
{
@ -406,7 +442,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
if (unlikely (new_gid == 0 &&
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
plan->pinned_at_default)
!plan->normalized_coords)
subset_glyph.source_glyph = glyf_impl::Glyph ();
else
{
@ -419,7 +455,19 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
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 *
@ -430,7 +478,10 @@ glyf::_create_font_for_instancing (const hb_subset_plan_t *plan) const
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)
{

View File

@ -26,22 +26,29 @@ struct path_builder_t
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, last_offcurve;
} 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 = last_offcurve = optional_point_t ();
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 */
* 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)
{
@ -52,7 +59,12 @@ struct path_builder_t
}
else
{
if (first_offcurve)
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;
@ -69,16 +81,41 @@ struct path_builder_t
{
if (is_on_curve)
{
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
p.x, p.y);
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
{
optional_point_t mid = last_offcurve.lerp (p, .5f);
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
last_offcurve = p;
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
@ -94,19 +131,40 @@ struct path_builder_t
{
if (first_offcurve && last_offcurve)
{
optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
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 */
}
/* now check the rest */
if (first_offcurve && first_oncurve)
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
{
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)
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
{
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)
@ -117,7 +175,7 @@ struct path_builder_t
}
/* Getting ready for the next contour */
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
draw_session->close_path ();
}
}

589
src/OT/name/name.hh Normal file
View File

@ -0,0 +1,589 @@
/*
* 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 */

View File

@ -19,7 +19,8 @@ symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re
if '--experimental-api' not in sys.argv:
# Move these to harfbuzz-sections.txt when got stable
experimental_symbols = \
"""hb_subset_repack_or_fail
"""hb_shape_justify
hb_subset_repack_or_fail
hb_subset_input_override_name_table
""".splitlines ()
symbols = [x for x in symbols if x not in experimental_symbols]

View File

@ -700,6 +700,9 @@ struct graph_t
}
}
if (in_error ())
return false;
if (!made_changes)
return false;
@ -833,7 +836,11 @@ struct graph_t
if (index_map.has (node_idx))
return;
index_map.set (node_idx, duplicate (node_idx));
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);
}

View File

@ -12,13 +12,17 @@ list(GET _harfbuzz_version_info 2
_harfbuzz_age)
unset(_harfbuzz_version_info)
if (APPLE)
set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}")
elseif (UNIX)
set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}")
if ("@default_library@" MATCHES "static")
set(_harfbuzz_lib_suffix ".a")
else ()
# Unsupported.
set(harfbuzz_FOUND 0)
if (APPLE)
set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}")
elseif (UNIX)
set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}")
else ()
# Unsupported.
set(harfbuzz_FOUND 0)
endif ()
endif ()
# Add the libraries.

View File

@ -41,6 +41,7 @@
#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"
@ -53,6 +54,7 @@
#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"

View File

@ -46,6 +46,7 @@
#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"

View File

@ -464,7 +464,8 @@ enum { DELETED_GLYPH = 0xFFFF };
template <typename T>
struct Entry
{
bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
// 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.
@ -492,7 +493,8 @@ struct Entry
template <>
struct Entry<void>
{
bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const
// 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));

View File

@ -110,9 +110,10 @@ struct BEInt<Type, 2>
constexpr operator Type () const
{
#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
defined(__BYTE_ORDER) && \
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
(__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
@ -155,9 +156,10 @@ struct BEInt<Type, 4>
struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
constexpr operator Type () const {
#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
defined(__BYTE_ORDER) && \
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
(__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
@ -598,13 +600,17 @@ template <typename T>
static inline unsigned int
hb_popcount (T v)
{
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
#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
@ -641,13 +647,17 @@ hb_bit_storage (T v)
{
if (unlikely (!v)) return 0;
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
#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
@ -715,13 +725,17 @@ hb_ctz (T v)
{
if (unlikely (!v)) return 8 * sizeof (T);
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
#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
@ -875,7 +889,7 @@ hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
static inline bool
hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
{
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
#if hb_has_builtin(__builtin_mul_overflow)
unsigned stack_result;
if (!result)
result = &stack_result;
@ -1330,4 +1344,62 @@ struct
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 */

View File

@ -304,6 +304,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
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>

View File

@ -38,6 +38,10 @@
/*
* Atomic integers and pointers.
*
* hb_atomic_int_t and hb_atomic_ptr_t are typedefs to the actual
* atomic type. They are guaranteed to be at least 32 bits wide.
* hb_atomic_int_t is signed.
*/
@ -84,11 +88,11 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#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<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_release))
#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<int> const *> (AI)->load (std::memory_order_relaxed))
#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<int> const *> (AI)->load (std::memory_order_acquire))
#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))
@ -111,10 +115,15 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#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
/* This we always use std::atomic for; and should never be disabled...
* except that MSVC gives me an internal compiler error on it. */
#if !defined(_MSC_VER)
#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
@ -145,15 +154,35 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#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;

View File

@ -42,7 +42,16 @@ 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 clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); }
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
@ -80,10 +89,10 @@ struct hb_vector_size_t
struct hb_bit_page_t
{
void init0 () { v.clear (); }
void init1 () { v.clear (0xFF); }
void init0 () { v.init0 (); }
void init1 () { v.init1 (); }
constexpr unsigned len () const
static inline constexpr unsigned len ()
{ return ARRAY_LENGTH_CONST (v); }
bool is_empty () const

View File

@ -194,7 +194,7 @@ struct hb_bit_set_t
unsigned int end = major_start (m + 1);
do
{
if (v || page) /* The v check is to optimize out the page check if v is true. */
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);
@ -238,7 +238,7 @@ struct hb_bit_set_t
if (g < last_g) return false;
last_g = g;
if (v || page) /* The v check is to optimize out the page check if v is true. */
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);

View File

@ -676,7 +676,7 @@ fail_without_close:
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)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
{
CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 };
ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
@ -697,7 +697,7 @@ fail_without_close:
if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
{
LARGE_INTEGER length;
GetFileSizeEx (fd, &length);
@ -710,7 +710,7 @@ fail_without_close:
#endif
if (unlikely (!file->mapping)) goto fail;
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#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);

View File

@ -63,7 +63,7 @@ HB_BEGIN_DECLS
* HarfBuzz and doing that just once (no reuse!),
*
* - If the font is mmap()ed, it's okay to use
* @HB_MEMORY_READONLY_MAY_MAKE_WRITABLE, however, using that mode
* @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, however, using that mode
* correctly is very tricky. Use @HB_MEMORY_MODE_READONLY instead.
**/
typedef enum {

View File

@ -35,34 +35,34 @@
#line 33 "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, 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, 93u,
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
};
static const char _deserialize_json_key_spans[] = {
0, 115, 26, 21, 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, 1, 50,
49, 117, 117, 1, 50, 49, 59, 117,
59, 117, 117, 1, 50, 49, 117, 85,
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
};
static const short _deserialize_json_index_offsets[] = {
0, 0, 116, 143, 165, 168, 170, 221,
271, 282, 400, 518, 636, 638, 689, 739,
750, 868, 986, 988, 990, 1041, 1091, 1209,
1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680,
1682, 1733, 1783, 1794, 1912, 2030, 2032, 2034,
2085, 2135, 2253, 2371, 2373, 2424, 2474, 2534,
2652, 2712, 2830, 2948, 2950, 3001, 3051, 3169,
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
};
@ -131,41 +131,52 @@ 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, 1, 1, 1, 24, 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, 25, 1, 25,
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,
26, 1, 26, 26, 26, 26, 26, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 26, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 27, 1,
1, 28, 29, 29, 29, 29, 29, 29,
29, 29, 29, 1, 30, 31, 31, 31,
31, 31, 31, 31, 31, 31, 1, 32,
32, 32, 32, 32, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 32, 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, 33, 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,
@ -175,39 +186,39 @@ 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, 1, 34, 1, 32, 32, 32,
32, 32, 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,
33, 1, 1, 1, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 34, 1, 35, 1, 36, 1, 36,
36, 36, 36, 36, 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,
37, 1, 37, 37, 37, 37, 37, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 37, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 38, 39, 39, 39, 39, 39, 39,
39, 39, 39, 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, 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,
@ -217,14 +228,14 @@ 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, 1, 1, 1, 1, 45, 1,
43, 43, 43, 43, 43, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
42, 1, 40, 40, 40, 40, 40, 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, 40, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 41, 1, 1,
1, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 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,
@ -232,186 +243,163 @@ 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, 1, 1, 1, 1, 42, 1,
44, 45, 1, 46, 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, 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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 47, 1,
47, 47, 47, 47, 47, 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, 48, 1, 1, 49,
50, 50, 50, 50, 50, 50, 50, 50,
50, 1, 51, 52, 52, 52, 52, 52,
52, 52, 52, 52, 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, 1,
1, 1, 1, 1, 1, 1, 1, 1,
54, 1, 1, 1, 1, 1, 1, 1,
1, 1, 49, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 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,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 55, 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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 54, 1,
1, 1, 52, 52, 52, 52, 52, 52,
52, 52, 52, 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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 55,
1, 56, 1, 56, 56, 56, 56, 56,
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, 57, 1, 57, 57,
57, 57, 57, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 57, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 58, 1, 1, 59, 60, 60,
60, 60, 60, 60, 60, 60, 60, 1,
61, 62, 62, 62, 62, 62, 62, 62,
62, 62, 1, 63, 63, 63, 63, 63,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 63, 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,
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, 65,
1, 63, 63, 63, 63, 63, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
63, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 64, 1, 1, 1,
62, 62, 62, 62, 62, 62, 62, 62,
62, 62, 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,
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, 1, 1, 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, 1, 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, 65, 1, 66,
1, 67, 1, 67, 67, 67, 67, 67,
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, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 67, 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, 68, 1, 68, 68,
68, 68, 68, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 68, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 69, 70, 70,
70, 70, 70, 70, 70, 70, 70, 1,
71, 71, 71, 71, 71, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 71,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 72, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 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, 73, 1, 71, 71,
71, 71, 71, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 71, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 72, 1, 1, 1, 74, 74, 74,
74, 74, 74, 74, 74, 74, 74, 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,
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, 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, 1, 1,
1, 1, 1, 71, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 73, 1, 75, 1, 75, 75,
75, 75, 75, 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, 75, 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, 76,
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, 77, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
78, 79, 79, 79, 79, 79, 79, 79,
79, 79, 1, 81, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 82, 80, 83,
83, 83, 83, 83, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 83, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 84, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 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, 85, 1, 80, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 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, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 80,
1, 86, 86, 86, 86, 86, 1, 1,
1, 1, 1, 1, 1, 79, 1, 79,
79, 79, 79, 79, 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, 1, 1, 1, 1,
86, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 87, 1, 1, 1,
1, 1, 1, 1, 86, 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,
@ -420,42 +408,64 @@ 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, 1, 1, 1, 88, 1, 86,
86, 86, 86, 86, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 86, 1,
1, 88, 1, 83, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 87, 1, 1, 1, 89, 89,
89, 89, 89, 89, 89, 89, 89, 89,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 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, 1,
1, 1, 1, 88, 1, 90, 1, 90,
90, 90, 90, 90, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 90, 1,
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, 91, 91, 91, 91, 91, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 91, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 92, 93, 93, 93, 93, 93, 93,
93, 93, 93, 1, 86, 86, 86, 86,
86, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 86, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 87,
1, 1, 1, 94, 94, 94, 94, 94,
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, 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, 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, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@ -463,17 +473,7 @@ 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,
88, 1, 95, 95, 95, 95, 95, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 95, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 96, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 97, 1,
1, 1, 1, 1, 1, 1, 91, 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,
@ -492,39 +492,39 @@ static const char _deserialize_json_indicies[] = {
};
static const char _deserialize_json_trans_targs[] = {
1, 0, 2, 2, 3, 4, 18, 24,
37, 43, 51, 5, 12, 6, 7, 8,
9, 11, 9, 11, 10, 2, 55, 10,
55, 13, 14, 15, 16, 17, 16, 17,
10, 2, 55, 19, 20, 21, 22, 23,
10, 2, 55, 23, 25, 31, 26, 27,
28, 29, 30, 29, 30, 10, 2, 55,
32, 33, 34, 35, 36, 35, 36, 10,
2, 55, 38, 39, 40, 41, 42, 10,
2, 55, 42, 44, 45, 46, 49, 50,
46, 47, 48, 10, 2, 55, 10, 2,
55, 50, 52, 53, 49, 54, 54, 55,
56, 57
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
};
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, 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
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
};
static const int deserialize_json_start = 1;
static const int deserialize_json_first_final = 55;
static const int deserialize_json_first_final = 56;
static const int deserialize_json_error = 0;
static const int deserialize_json_en_main = 1;
@ -548,21 +548,19 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer,
while (p < pe && ISSPACE (*p))
p++;
if (p < pe && *p == (buffer->len ? ',' : '['))
{
*end_ptr = ++p;
}
const char *tok = nullptr;
int cs;
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
#line 554 "hb-buffer-deserialize-json.hh"
#line 552 "hb-buffer-deserialize-json.hh"
{
cs = deserialize_json_start;
}
#line 557 "hb-buffer-deserialize-json.hh"
#line 555 "hb-buffer-deserialize-json.hh"
{
int _slen;
int _trans;
@ -774,7 +772,7 @@ _resume:
*end_ptr = p;
}
break;
#line 735 "hb-buffer-deserialize-json.hh"
#line 733 "hb-buffer-deserialize-json.hh"
}
_again:
@ -786,7 +784,7 @@ _again:
_out: {}
}
#line 139 "hb-buffer-deserialize-json.rl"
#line 137 "hb-buffer-deserialize-json.rl"
*end_ptr = p;

View File

@ -106,7 +106,7 @@ item =
@add_item
;
main := space* item (comma item)* space* (','|']')?;
main := space* item (comma item)* space* (','|']');
}%%
@ -125,9 +125,7 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer,
while (p < pe && ISSPACE (*p))
p++;
if (p < pe && *p == (buffer->len ? ',' : '['))
{
*end_ptr = ++p;
}
const char *tok = nullptr;
int cs;

View File

@ -0,0 +1,692 @@
#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 */

View File

@ -24,14 +24,14 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
#define HB_BUFFER_DESERIALIZE_TEXT_HH
#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#include "hb.hh"
%%{
machine deserialize_text;
machine deserialize_text_glyphs;
alphtype unsigned char;
write data;
@ -52,9 +52,6 @@ action tok {
tok = p;
}
action ensure_glyphs { if (unlikely (!buffer->ensure_glyphs ())) return false; }
action ensure_unicode { if (unlikely (!buffer->ensure_unicode ())) return false; }
action parse_glyph {
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
@ -63,8 +60,6 @@ action parse_glyph {
return false;
}
action parse_hexdigits {if (!parse_hex (tok, p, &info.codepoint )) return false; }
action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; }
action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; }
action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
@ -93,45 +88,45 @@ glyph_item =
glyphflags?
)
>clear_item
@ensure_glyphs
%add_item
;
unicode = 'U' '+' xdigit+ >tok %parse_hexdigits;
glyphs = glyph_item (space* '|' space* glyph_item)* space*;
unicode_item =
(
unicode
cluster?
)
>clear_item
@ensure_unicode
%add_item
;
glyphs = glyph_item (space* '|' space* glyph_item)* space* ('|'|']')?;
unicodes = unicode_item (space* '|' space* unicode_item)* space* ('|'|'>')?;
main := space* ( ('[' glyphs) | ('<' unicodes) );
main := space* glyphs;
}%%
static hb_bool_t
_hb_buffer_deserialize_text (hb_buffer_t *buffer,
_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;
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 *eof = pe, *tok = nullptr;
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};
@ -140,9 +135,16 @@ _hb_buffer_deserialize_text (hb_buffer_t *buffer,
write exec;
}%%
if (pe < orig_pe && *pe == ']')
{
pe++;
if (p == pe)
p++;
}
*end_ptr = p;
return p == pe && *(p-1) != ']';
return p == pe;
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */

View File

@ -0,0 +1,332 @@
#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 */

View File

@ -0,0 +1,129 @@
/*
* 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"
%%{
machine deserialize_text_unicode;
alphtype unsigned char;
write data;
action clear_item {
hb_memset (&info, 0, sizeof (info));
}
action add_item {
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
if (buffer->have_positions)
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
action tok {
tok = p;
}
action parse_hexdigits {if (!parse_hex (tok, p, &info.codepoint )) return false; }
action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; }
unum = '0' | [1-9] digit*;
num = '-'? unum;
cluster = '=' (unum >tok %parse_cluster);
unicode = [Uu] '+'? xdigit+ >tok %parse_hexdigits;
unicode_item =
(
unicode
cluster?
)
>clear_item
%add_item
;
unicodes = unicode_item (space* '|' space* unicode_item)* space*;
main := space* unicodes;
}%%
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};
%%{
write init;
write exec;
}%%
if (pe < orig_pe && *pe == '>')
{
pe++;
if (p == pe)
p++;
}
*end_ptr = p;
return p == pe;
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */

View File

@ -1,917 +0,0 @@
#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.hh"
#line 33 "hb-buffer-deserialize-text.hh"
static const unsigned char _deserialize_text_trans_keys[] = {
0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 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, 0u, 0u, 9u, 85u,
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, 9u, 124u, 9u, 124u, 9u, 124u,
0
};
static const char _deserialize_text_key_spans[] = {
0, 83, 1, 1, 55, 77, 10, 10,
13, 10, 13, 10, 10, 13, 10, 1,
13, 10, 14, 82, 116, 116, 0, 77,
116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116
};
static const short _deserialize_text_index_offsets[] = {
0, 0, 84, 86, 88, 144, 222, 233,
244, 258, 269, 283, 294, 305, 319, 330,
332, 346, 357, 372, 455, 572, 689, 690,
768, 885, 1002, 1119, 1236, 1353, 1470, 1587,
1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523
};
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,
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, 3, 1, 4, 1, 5,
1, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 1, 1, 1, 1, 1,
1, 1, 6, 6, 6, 6, 6, 6,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 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,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 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, 1, 8,
9, 9, 9, 9, 9, 9, 9, 9,
9, 1, 10, 11, 11, 11, 11, 11,
11, 11, 11, 11, 1, 12, 1, 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,
23, 23, 23, 23, 23, 23, 23, 23,
23, 1, 24, 1, 1, 25, 26, 26,
26, 26, 26, 26, 26, 26, 26, 1,
27, 28, 28, 28, 28, 28, 28, 28,
28, 28, 1, 29, 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, 29, 1,
1, 1, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 1, 35, 35, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 35,
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, 35, 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, 35, 1,
36, 36, 36, 36, 36, 1, 1, 1,
1, 1, 1, 1, 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, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 1, 1, 1, 38, 39, 1, 1,
37, 37, 37, 37, 37, 37, 1, 1,
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, 37, 37, 37, 37, 37, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 40, 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, 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, 1,
43, 1, 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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 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,
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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 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, 46, 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, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 1,
1, 1, 1, 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, 46, 1, 49, 49, 49, 49, 49,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 49, 48, 48, 50, 48, 48,
48, 48, 48, 48, 48, 51, 1, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 52,
48, 48, 53, 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, 48, 48, 54, 55,
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, 48, 48, 48, 48, 48, 56, 48,
57, 57, 57, 57, 57, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 57,
35, 35, 58, 35, 35, 35, 35, 35,
35, 35, 59, 1, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 60, 35, 35, 61,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 62, 63, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 64, 35, 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, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
67, 1, 68, 68, 68, 68, 68, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 68, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 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,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 69, 1, 70,
70, 70, 70, 70, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 70, 48,
48, 50, 48, 48, 48, 48, 48, 48,
48, 51, 1, 48, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 52, 48, 48, 53, 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,
48, 48, 54, 55, 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, 48, 48, 48,
48, 48, 56, 48, 71, 71, 71, 71,
71, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 71, 1, 1, 72, 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, 1, 1, 1, 1, 1, 1,
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, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 75,
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, 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,
1, 1, 1, 1, 1, 78, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 79, 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,
77, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 21, 21, 21,
21, 21, 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, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 78, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 79, 1, 71, 71, 71, 71, 71,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 71, 1, 1, 72, 1, 1,
1, 1, 1, 1, 1, 1, 73, 1,
1, 1, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 75, 1,
80, 80, 80, 80, 80, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 80,
1, 1, 81, 1, 1, 1, 1, 1,
1, 1, 82, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 83,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 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, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 84, 1, 85, 85, 85,
85, 85, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 85, 1, 1, 86,
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, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 88, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
89, 1, 85, 85, 85, 85, 85, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 85, 1, 1, 86, 1, 1, 1,
1, 1, 1, 1, 87, 1, 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, 88, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 89, 1, 80,
80, 80, 80, 80, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 80, 1,
1, 81, 1, 1, 1, 1, 1, 1,
1, 82, 1, 1, 1, 1, 90, 90,
90, 90, 90, 90, 90, 90, 90, 90,
1, 1, 1, 1, 1, 1, 83, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 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, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 84, 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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 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, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 67,
1, 0
};
static const char _deserialize_text_trans_targs[] = {
1, 0, 2, 26, 3, 4, 20, 5,
24, 25, 28, 39, 9, 31, 34, 31,
34, 11, 32, 33, 32, 33, 35, 38,
14, 15, 18, 15, 18, 16, 17, 36,
37, 36, 37, 27, 21, 20, 6, 22,
23, 21, 22, 23, 21, 22, 23, 25,
27, 27, 7, 8, 12, 13, 19, 22,
30, 27, 7, 8, 12, 13, 19, 22,
30, 29, 22, 30, 29, 30, 30, 29,
7, 10, 22, 30, 29, 7, 22, 30,
29, 7, 8, 13, 30, 29, 7, 8,
22, 30, 38, 39
};
static const char _deserialize_text_trans_actions[] = {
0, 0, 0, 0, 1, 0, 2, 0,
2, 2, 3, 3, 4, 3, 3, 5,
5, 4, 3, 3, 5, 5, 3, 3,
4, 4, 4, 0, 0, 6, 4, 3,
3, 5, 5, 5, 7, 8, 9, 7,
7, 0, 0, 0, 10, 10, 10, 8,
12, 13, 14, 14, 14, 14, 15, 11,
11, 17, 18, 18, 18, 18, 0, 16,
16, 19, 19, 19, 0, 0, 13, 20,
21, 21, 20, 20, 22, 23, 22, 22,
10, 24, 24, 24, 10, 25, 26, 26,
25, 25, 5, 5
};
static const char _deserialize_text_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 0, 0, 0,
10, 10, 11, 16, 19, 0, 11, 20,
22, 22, 20, 10, 25, 25, 10, 19
};
static const int deserialize_text_start = 1;
static const int deserialize_text_first_final = 20;
static const int deserialize_text_error = 0;
static const int deserialize_text_en_main = 1;
#line 117 "hb-buffer-deserialize-text.rl"
static hb_bool_t
_hb_buffer_deserialize_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, nullptr);
while (p < pe && ISSPACE (*p))
p++;
const char *eof = pe, *tok = nullptr;
int cs;
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
#line 457 "hb-buffer-deserialize-text.hh"
{
cs = deserialize_text_start;
}
#line 460 "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 1:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
break;
case 4:
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
break;
case 5:
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
break;
case 8:
#line 56 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_unicode ())) return false; }
break;
case 18:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
break;
case 9:
#line 66 "hb-buffer-deserialize-text.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
break;
case 24:
#line 68 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
break;
case 6:
#line 69 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
break;
case 26:
#line 70 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
break;
case 21:
#line 71 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
break;
case 23:
#line 72 "hb-buffer-deserialize-text.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
break;
case 15:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
break;
case 3:
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
break;
case 2:
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 56 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_unicode ())) return false; }
break;
case 16:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 7:
#line 66 "hb-buffer-deserialize-text.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 10:
#line 68 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 25:
#line 70 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 20:
#line 71 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 22:
#line 72 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 19:
#line 73 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 12:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
break;
case 14:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
break;
case 17:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 11:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 13:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 55 "hb-buffer-deserialize-text.rl"
{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 715 "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 16:
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 7:
#line 66 "hb-buffer-deserialize-text.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 10:
#line 68 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 25:
#line 70 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 20:
#line 71 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 22:
#line 72 "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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 19:
#line 73 "hb-buffer-deserialize-text.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 11:
#line 38 "hb-buffer-deserialize-text.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text.rl"
{
tok = p;
}
#line 58 "hb-buffer-deserialize-text.rl"
{
/* TODO Unescape delimiters. */
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 (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 825 "hb-buffer-deserialize-text.hh"
}
}
_out: {}
}
#line 141 "hb-buffer-deserialize-text.rl"
*end_ptr = p;
return p == pe && *(p-1) != ']';
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */

View File

@ -721,7 +721,8 @@ parse_hex (const char *pp, const char *end, uint32_t *pv)
}
#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
#include "hb-buffer-deserialize-text-glyphs.hh"
#include "hb-buffer-deserialize-text-unicode.hh"
/**
* hb_buffer_deserialize_glyphs:
@ -736,7 +737,8 @@ parse_hex (const char *pp, const char *end, uint32_t *pv)
* Deserializes glyphs @buffer from textual representation in the format
* produced by hb_buffer_serialize_glyphs().
*
* Return value: `true` if @buf is not fully consumed, `false` otherwise.
* Return value: `true` if parse was successful, `false` if an error
* occurred.
*
* Since: 0.9.7
**/
@ -779,9 +781,9 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr,
font);
return _hb_buffer_deserialize_text_glyphs (buffer,
buf, buf_len, end_ptr,
font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_deserialize_json (buffer,
@ -808,7 +810,8 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
* Deserializes Unicode @buffer from textual representation in the format
* produced by hb_buffer_serialize_unicode().
*
* Return value: `true` if @buf is not fully consumed, `false` otherwise.
* Return value: `true` if parse was successful, `false` if an error
* occurred.
*
* Since: 2.7.3
**/
@ -849,9 +852,9 @@ hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr,
font);
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,

View File

@ -40,6 +40,11 @@
* 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.
**/
@ -522,15 +527,17 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
cluster = hb_min (cluster, info[i].cluster);
/* Extend end */
while (end < len && info[end - 1].cluster == info[end].cluster)
end++;
if (cluster != info[end - 1].cluster)
while (end < len && info[end - 1].cluster == info[end].cluster)
end++;
/* Extend start */
while (idx < start && info[start - 1].cluster == info[start].cluster)
start--;
if (cluster != info[start].cluster)
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)
if (idx == start && info[start].cluster != cluster)
for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
set_cluster (out_info[i - 1], cluster);

View File

@ -581,21 +581,59 @@ struct hb_buffer_t
unsigned int cluster,
hb_mask_t mask)
{
for (unsigned int i = start; i < end; i++)
if (cluster != infos[i].cluster)
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;
}
}
}
static unsigned
unsigned
_infos_find_min_cluster (const hb_glyph_info_t *infos,
unsigned start, unsigned end,
unsigned cluster = UINT_MAX)
{
for (unsigned int i = start; i < end; i++)
cluster = hb_min (cluster, infos[i].cluster);
return cluster;
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)

View File

@ -30,7 +30,19 @@
#include "hb.hh"
/* Implements a lockfree cache for int->int functions. */
/* 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,
@ -39,7 +51,9 @@ template <unsigned int key_bits=16,
struct hb_cache_t
{
using item_t = typename std::conditional<thread_safe,
hb_atomic_int_t,
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
@ -48,8 +62,9 @@ struct hb_cache_t
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 fini () {}
void clear ()
{

View File

@ -1,5 +1,6 @@
/*
* Copyright © 2022 Red Hat, Inc
* Copyright © 2021, 2022 Black Foundry
*
* This is part of HarfBuzz, a text shaping library.
*
@ -32,9 +33,13 @@
#include <cairo.h>
#define PREALLOCATED_COLOR_STOPS 16
/* 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 _2_M_PIf (2.f * float (M_PI))
#define PREALLOCATED_COLOR_STOPS 16
typedef struct {
float r, g, b, a;
@ -91,14 +96,16 @@ _hb_cairo_destroy_blob (void *p)
}
hb_bool_t
hb_cairo_paint_glyph_image (cairo_t *cr,
hb_blob_t *blob,
unsigned width,
unsigned height,
hb_tag_t format,
float slant,
hb_glyph_extents_t *extents)
_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;
@ -212,7 +219,7 @@ _hb_cairo_reduce_anchors (float x0, float y0,
q2x = x2 - x0;
q2y = y2 - y0;
q1x = y1 - x0;
q1x = x1 - x0;
q1y = y1 - y0;
s = q2x * q2x + q2y * q2y;
@ -272,28 +279,60 @@ _hb_cairo_normalize_color_line (hb_color_stop_t *stops,
*omax = max;
}
void
hb_cairo_paint_linear_gradient (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0,
float x1, float y1,
float x2, float y2)
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_;
unsigned int len;
float xx0, yy0, xx1, yy1;
float xxx0, yyy0, xxx1, yyy1;
float min, max;
cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
if (len > PREALLOCATED_COLOR_STOPS)
stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t));
hb_color_line_get_color_stops (color_line, 0, &len, stops);
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);
_hb_cairo_normalize_color_line (stops, len, &min, &max);
xxx0 = xx0 + min * (xx1 - xx0);
yyy0 = yy0 + min * (yy1 - yy0);
@ -318,28 +357,27 @@ hb_cairo_paint_linear_gradient (cairo_t *cr,
cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
hb_free (stops);
}
void
hb_cairo_paint_radial_gradient (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0, float r0,
float x1, float y1, float r1)
_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_;
unsigned int len;
float min, max;
float xx0, yy0, xx1, yy1;
float rr0, rr1;
cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
if (len > PREALLOCATED_COLOR_STOPS)
stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t));
hb_color_line_get_color_stops (color_line, 0, &len, stops);
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);
@ -368,7 +406,7 @@ hb_cairo_paint_radial_gradient (cairo_t *cr,
cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
hb_free (stops);
}
typedef struct {
@ -485,7 +523,7 @@ _hb_cairo_add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cair
cairo_mesh_pattern_end_patch (pattern);
}
#define MAX_ANGLE ((float) M_PI / 8.f)
#define MAX_ANGLE (HB_PI / 8.f)
static void
_hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
@ -526,8 +564,8 @@ _hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
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.33333)), radius));
patch.c1 = _hb_cairo_sum (center, _hb_cairo_scale (_hb_cairo_sum (C1, _hb_cairo_scale (_hb_cairo_difference (C1, p1), 0.33333)), radius));
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);
@ -553,249 +591,254 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
hb_cairo_color_t color0, color1;
if (start_angle == end_angle)
{
if (extend == CAIRO_EXTEND_PAD)
{
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 < _2_M_PIf)
{
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,
_2_M_PIf, &c,
pattern);
}
}
return;
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)
{
float angle = end_angle;
end_angle = start_angle;
start_angle = angle;
{
hb_swap (start_angle, end_angle);
for (unsigned i = 0; i < n_stops - 1 - i; i++)
{
hb_color_stop_t stop = stops[i];
stops[i] = stops[n_stops - 1 - i];
stops[n_stops - 1 - i] = stop;
}
}
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 *) malloc (sizeof (float) * n_stops);
colors = (hb_cairo_color_t *) malloc (sizeof (hb_cairo_color_t) * n_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.;
}
{
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++)
{
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,
_2_M_PIf, &color0,
pattern);
goto done;
}
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,
angles[pos], &colors[pos],
0., &color0,
HB_2_PI, &color0,
pattern);
for (pos++; pos < n_stops; pos++)
{
if (angles[pos] <= _2_M_PIf)
{
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
angles[pos - 1], &colors[pos-1],
angles[pos], &colors[pos],
pattern);
}
else
{
float k = (_2_M_PIf - 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],
_2_M_PIf, &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,
_2_M_PIf, &color0,
pattern);
goto done;
}
goto done;
}
else
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
0., &color0,
angles[pos], &colors[pos],
pattern);
for (pos++; pos < n_stops; pos++)
{
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);
for (unsigned l = k; 1; 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 >= _2_M_PIf)
{
hb_cairo_color_t color;
float f = (_2_M_PIf - a0)/(a1 - a0);
_hb_cairo_interpolate_colors (c0, c1, f, &color);
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
a0, c0,
_2_M_PIf, &color,
pattern);
goto done;
}
else
{
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
a0, c0,
a1, c1,
pattern);
}
}
}
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_)
free (angles);
hb_free (angles);
if (colors != colors_)
free (colors);
hb_free (colors);
}
void
hb_cairo_paint_sweep_gradient (cairo_t *cr,
hb_color_line_t *color_line,
float cx, float cy,
float start_angle,
float end_angle)
_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)
{
unsigned int len;
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;
@ -803,10 +846,8 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr,
float max_x, max_y, radius;
cairo_pattern_t *pattern;
len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
if (len > PREALLOCATED_COLOR_STOPS)
stops = (hb_color_stop_t *) malloc (len * sizeof (hb_color_stop_t));
hb_color_line_get_color_stops (color_line, 0, &len, stops);
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);
@ -827,7 +868,7 @@ hb_cairo_paint_sweep_gradient (cairo_t *cr,
cairo_pattern_destroy (pattern);
if (stops != stops_)
free (stops);
hb_free (stops);
}
#endif

View File

@ -31,8 +31,15 @@
#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)
_hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
{
switch (mode)
{
@ -69,32 +76,32 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
}
HB_INTERNAL hb_bool_t
hb_cairo_paint_glyph_image (cairo_t *cr,
hb_blob_t *blob,
unsigned width,
unsigned height,
hb_tag_t format,
float slant,
hb_glyph_extents_t *extents);
_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 (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0,
float x1, float y1,
float x2, float y2);
_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 (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0, float r0,
float x1, float y1, float r1);
_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 (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0,
float start_angle, float end_angle);
_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 */

View File

@ -36,9 +36,6 @@
#include "hb-utf.hh"
/* TODO Error handling in cairo set_user_data calls? */
/**
* SECTION:hb-cairo
* @title: hb-cairo
@ -146,7 +143,9 @@ hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
float dx, float dy,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_matrix_t m;
cairo_save (cr);
@ -161,7 +160,8 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_restore (cr);
}
@ -173,7 +173,8 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_font_t *font,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr);
cairo_new_path (cr);
@ -188,7 +189,8 @@ hb_cairo_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED,
float xmin, float ymin, float xmax, float ymax,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr);
cairo_rectangle (cr,
@ -202,7 +204,8 @@ hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_restore (cr);
}
@ -212,7 +215,8 @@ hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr);
cairo_push_group (cr);
@ -224,10 +228,11 @@ hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_paint_composite_mode_t mode,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
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_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode));
cairo_paint (cr);
cairo_restore (cr);
@ -240,13 +245,26 @@ hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_color_t color,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
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.);
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);
}
@ -261,9 +279,9 @@ hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
return hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents);
return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
}
static void
@ -275,9 +293,9 @@ hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x2, float y2,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *)paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
hb_cairo_paint_linear_gradient (cr, color_line, x0, y0, x1, y1, x2, y2);
_hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
}
static void
@ -288,9 +306,9 @@ hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x1, float y1, float r1,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *)paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
hb_cairo_paint_radial_gradient (cr, color_line, x0, y0, r0, x1, y1, r1);
_hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
}
static void
@ -301,9 +319,72 @@ hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float start_angle, float end_angle,
void *user_data HB_UNUSED)
{
cairo_t *cr = (cairo_t *) paint_data;
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle);
_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 ();
@ -326,6 +407,7 @@ static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<
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);
@ -346,12 +428,6 @@ hb_cairo_paint_get_funcs ()
{
return static_cairo_paint_funcs.get_unconst ();
}
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);
#endif
static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
@ -379,6 +455,7 @@ hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
&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
@ -397,6 +474,7 @@ hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
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);
@ -437,6 +515,15 @@ hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
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;
}
@ -512,19 +599,17 @@ hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
#endif
hb_color_t color = HB_COLOR (0, 0, 0, 255);
cairo_pattern_t *pattern = cairo_get_source (cr);
if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
{
double r, g, b, a;
cairo_pattern_get_rgba (pattern, &r, &g, &b, &a);
color = HB_COLOR ((int)(b * 255.), (int)(g * 255.), (int) (r * 255.), (int)(a * 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_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), cr, palette, color);
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;
}
@ -545,10 +630,11 @@ user_font_face_create (hb_face_t *face)
cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph);
#endif
cairo_font_face_set_user_data (cairo_face,
&hb_cairo_face_user_data_key,
(void *) hb_face_reference (face),
hb_cairo_face_destroy);
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;
}
@ -565,7 +651,7 @@ user_font_face_create (hb_face_t *face)
*
* Returns: (transfer full): a newly created #cairo_font_face_t
*
* Since: REPLACEME
* Since: 7.0.0
*/
cairo_font_face_t *
hb_cairo_font_face_create_for_font (hb_font_t *font)
@ -574,10 +660,11 @@ hb_cairo_font_face_create_for_font (hb_font_t *font)
auto *cairo_face = user_font_face_create (font->face);
cairo_font_face_set_user_data (cairo_face,
&hb_cairo_font_user_data_key,
(void *) hb_font_reference (font),
hb_cairo_font_destroy);
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;
}
@ -590,7 +677,7 @@ hb_cairo_font_face_create_for_font (hb_font_t *font)
*
* Returns: (nullable) (transfer none): the #hb_font_t that @font_face was created from
*
* Since: REPLACEME
* Since: 7.0.0
*/
hb_font_t *
hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
@ -608,7 +695,7 @@ hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
*
* Returns: (transfer full): a newly created #cairo_font_face_t
*
* Since: REPLACEME
* Since: 7.0.0
*/
cairo_font_face_t *
hb_cairo_font_face_create_for_face (hb_face_t *face)
@ -626,7 +713,7 @@ hb_cairo_font_face_create_for_face (hb_face_t *face)
*
* Returns: (nullable) (transfer none): the #hb_face_t associated with @font_face
*
* Since: REPLACEME
* Since: 7.0.0
*/
hb_face_t *
hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
@ -646,7 +733,7 @@ hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
* face created using hb_cairo_font_face_create_for_face()
* creates an #hb_font_t for a #cairo_scaled_font_t.
*
* Since: REPLACEME
* Since: 7.0.0
*/
void
hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
@ -658,10 +745,17 @@ hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
&hb_cairo_font_init_func_user_data_key,
(void *) func,
nullptr);
cairo_font_face_set_user_data (font_face,
&hb_cairo_font_init_user_data_user_data_key,
(void *) user_data,
destroy);
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);
}
}
/**
@ -672,7 +766,7 @@ hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
*
* Returns: (nullable) (transfer none): the #hb_font_t associated with @scaled_font
*
* Since: REPLACEME
* Since: 7.0.0
*/
hb_font_t *
hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
@ -720,7 +814,7 @@ hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
* (because you set the scale of the #hb_font_t yourself), use
* the conversion rate involved.
*
* Since: REPLACEME
* Since: 7.0.0
*/
void
hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
@ -741,7 +835,7 @@ hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
*
* Returns: the scale factor of @font_face
*
* Since: REPLACEME
* Since: 7.0.0
*/
unsigned int
hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
@ -774,7 +868,7 @@ hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
* 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
* 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,
@ -783,11 +877,11 @@ hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
* 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
* 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
* 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
@ -804,7 +898,7 @@ hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
* 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: REPLACEME
* Since: 7.0.0
*/
void
hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,

View File

@ -57,7 +57,7 @@ hb_cairo_font_face_get_face (cairo_font_face_t *font_face);
*
* Return value: the #hb_font_t value to use; in most cases same as @font
*
* Since: REPLACEME
* Since: 7.0.0
*/
typedef hb_font_t * (*hb_cairo_font_init_func_t) (hb_font_t *font,
cairo_scaled_font_t *scaled_font,

View File

@ -35,10 +35,8 @@ using namespace OT;
/* an opstr and the parsed out dict value(s) */
struct dict_val_t : op_str_t
{
void init () { single_val.set_int (0); }
void init () {}
void fini () {}
number_t single_val;
};
typedef dict_val_t num_dict_val_t;

View File

@ -29,32 +29,6 @@
#include "hb.hh"
#include "hb-machinery.hh"
#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
/**
* SECTION:hb-common
@ -658,6 +632,7 @@ hb_script_get_horizontal_direction (hb_script_t script)
case HB_SCRIPT_OLD_HUNGARIAN:
case HB_SCRIPT_OLD_ITALIC:
case HB_SCRIPT_RUNIC:
case HB_SCRIPT_TIFINAGH:
return HB_DIRECTION_INVALID;
}

View File

@ -37,6 +37,7 @@
#ifndef HB_EXPERIMENTAL_API
#define HB_NO_BEYOND_64K
#define HB_NO_CUBIC_GLYF
#define HB_NO_VAR_COMPOSITES
#endif
@ -135,6 +136,10 @@
#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

View File

@ -142,9 +142,9 @@ _hb_debug_msg_va (const char *what,
fprintf (stderr, "%-10s", what ? what : "");
if (obj)
fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
fprintf (stderr, "(%*p) ", (int) (2 * sizeof (void *)), obj);
else
fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
fprintf (stderr, " %*s ", (int) (2 * sizeof (void *)), "");
if (indented) {
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
@ -306,7 +306,7 @@ struct hb_auto_trace_t
}
_hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
"return %s (line %d)",
"return %s (line %u)",
hb_printer_t<hb_decay<decltype (v)>>().print (v), line);
if (plevel) --*plevel;
plevel = nullptr;
@ -373,6 +373,10 @@ struct hb_no_trace_t {
#define HB_DEBUG_FT (HB_DEBUG+0)
#endif
#ifndef HB_DEBUG_JUSTIFY
#define HB_DEBUG_JUSTIFY (HB_DEBUG+0)
#endif
#ifndef HB_DEBUG_OBJECT
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
#endif
@ -396,7 +400,7 @@ 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 %d gid %u lookup %d", \
"idx %u 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
@ -454,7 +458,7 @@ struct hb_no_trace_t {
#define TRACE_DISPATCH(this, format) \
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"format %d", (int) format)
"format %u", (unsigned) format)
#else
#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
#endif

View File

@ -207,7 +207,7 @@ DEFINE_NULL_INSTANCE (hb_draw_funcs_t) =
*
* Return value: (transfer full): The empty draw-functions structure
*
* Since: REPLACEME
* Since: 7.0.0
**/
hb_draw_funcs_t *
hb_draw_funcs_get_empty ()
@ -276,7 +276,7 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
*
* Return value: `true` if success, `false` otherwise
*
* Since: REPLACEME
* Since: 7.0.0
**/
hb_bool_t
hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
@ -298,7 +298,7 @@ hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
*
* Return value: (transfer none): A pointer to the user data
*
* Since: REPLACEME
* Since: 7.0.0
**/
void *
hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,

View File

@ -47,6 +47,12 @@
* 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.
**/
@ -197,7 +203,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
* a face index into that blob.
*
* The face index is used for blobs of file formats such as TTC and
* and DFont that can contain more than one face. Face indices within
* 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
@ -604,12 +610,12 @@ hb_face_collect_unicodes (hb_face_t *face,
* 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
* @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: REPLACEME
* Since: 7.0.0
*/
void
hb_face_collect_nominal_glyph_mapping (hb_face_t *face,

View File

@ -76,7 +76,7 @@ struct hb_face_t
if (unlikely (!reference_table_func))
return hb_blob_get_empty ();
blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
blob = reference_table_func (/*Oh, well.*/const_cast<hb_face_t *> (this), tag, user_data);
if (unlikely (!blob))
return hb_blob_get_empty ();

View File

@ -27,6 +27,14 @@
HB_BEGIN_DECLS
/**
* SECTION: hb-features
* @title: hb-features
* @short_description: Feature detection
* @include: hb-features.h
*
* Macros for detecting optional HarfBuzz features at build time.
**/
/**
* HB_HAS_CAIRO:
@ -70,6 +78,13 @@ HB_BEGIN_DECLS
*/
#mesondefine HB_HAS_GLIB
/**
* HB_HAS_GOBJECT:
*
* Defined if Harfbuzz has been built with GObject support.
*/
#mesondefine HB_HAS_GOBJECT
/**
* HB_HAS_GRAPHITE:
*

View File

@ -59,6 +59,11 @@
*
* 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.
**/
@ -1061,7 +1066,8 @@ hb_font_get_nominal_glyph (hb_font_t *font,
* @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.
* 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
*
@ -1343,6 +1349,9 @@ hb_font_get_glyph_contour_point (hb_font_t *font,
*
* Fetches the glyph-name string for a glyph ID in the specified @font.
*
* 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
*
* Since: 0.9.2
@ -1383,7 +1392,7 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/**
* hb_font_get_glyph_shape:
* @font: #hb_font_t to work upon
* @glyph: : The glyph ID
* @glyph: The glyph ID
* @dfuncs: #hb_draw_funcs_t to draw to
* @draw_data: User data to pass to draw callbacks
*
@ -1392,6 +1401,7 @@ hb_font_get_glyph_from_name (hb_font_t *font,
* 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,
@ -1404,7 +1414,7 @@ hb_font_get_glyph_shape (hb_font_t *font,
/**
* hb_font_draw_glyph:
* @font: #hb_font_t to work upon
* @glyph: : The glyph ID
* @glyph: The glyph ID
* @dfuncs: #hb_draw_funcs_t to draw to
* @draw_data: User data to pass to draw callbacks
*
@ -1413,7 +1423,7 @@ hb_font_get_glyph_shape (hb_font_t *font,
* The outline is returned by way of calls to the callbacks of the @dfuncs
* objects, with @draw_data passed to them.
*
* Since: REPLACEME
* Since: 7.0.0
**/
void
hb_font_draw_glyph (hb_font_t *font,
@ -1429,7 +1439,7 @@ hb_font_draw_glyph (hb_font_t *font,
* @glyph: The glyph ID
* @pfuncs: #hb_paint_funcs_t to paint with
* @paint_data: User data to pass to paint callbacks
* @palette: The index of the font's color palette to use
* @palette_index: The index of the font's color palette to use
* @foreground: The foreground color, unpremultipled
*
* Paints the glyph.
@ -1439,19 +1449,19 @@ hb_font_draw_glyph (hb_font_t *font,
* to them.
*
* If the font has color palettes (see hb_ot_color_has_palettes()),
* then @palette selects the palette to use. If the font doesn't
* have palettes, passing 0 is fine.
* then @palette_index selects the palette to use. If the font only
* has one palette, this will be 0.
*
* Since: REPLACEME
* 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,
unsigned int palette_index,
hb_color_t foreground)
{
font->paint_glyph (glyph, pfuncs, paint_data, palette, foreground);
font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
}
/* A bit higher-level, and with fallback */
@ -1712,6 +1722,9 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
* If the glyph ID has no name in @font, a string of the form `gidDDD` is
* generated, with `DDD` being the glyph ID.
*
* 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
@ -1765,8 +1778,13 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */
1000, /* y_scale */
0., /* slant */
0., /* slant_xy; */
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 */
@ -1804,6 +1822,7 @@ _hb_font_create (hb_face_t *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;
@ -1888,6 +1907,9 @@ hb_font_create_sub_font (hb_font_t *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;
@ -2435,6 +2457,76 @@ 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;
}
/**
* hb_font_set_synthetic_slant:
* @font: #hb_font_t to work upon
@ -2562,6 +2654,79 @@ hb_font_set_variations (hb_font_t *font,
_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;
if (unlikely (coords_length && !(normalized && design_coords)))
{
hb_free (normalized);
hb_free (design_coords);
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_font_set_var_coords_design:
* @font: #hb_font_t to work upon
@ -2637,7 +2802,7 @@ hb_font_set_var_named_instance (hb_font_t *font,
*
* Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE.
*
* Since: REPLACEME
* Since: 7.0.0
**/
unsigned int
hb_font_get_var_named_instance (hb_font_t *font)

View File

@ -497,8 +497,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* Since: 4.0.0
*
* Deprecated: REPLACEME: Use #hb_font_draw_glyph_func_t instead
* 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,
@ -516,7 +515,7 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* Since: REPLACEME
* Since: 7.0.0
*
**/
typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
@ -531,18 +530,18 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
* @glyph: The glyph ID to query
* @paint_funcs: The paint functions to use
* @paint_data: The data accompanying the paint functions
* @palette: The color palette to use
* @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: REPLACEME
* 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,
unsigned int palette_index,
hb_color_t foreground,
void *user_data);
@ -815,8 +814,7 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
* which is the same as #hb_font_draw_glyph_func_t.
*
* Since: 4.0.0
*
* Deprecated: REPLACEME: Use hb_font_funcs_set_draw_glyph_func() instead
* 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,
@ -833,7 +831,7 @@ hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
* Sets the implementation function for #hb_font_draw_glyph_func_t,
* which is the same as #hb_font_get_glyph_shape_func_t.
*
* Since: REPLACEME
* Since: 7.0.0
**/
HB_EXTERN void
hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs,
@ -849,7 +847,7 @@ hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs,
*
* Sets the implementation function for #hb_font_paint_glyph_func_t.
*
* Since: REPLACEME
* Since: 7.0.0
*/
HB_EXTERN void
hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs,
@ -950,7 +948,7 @@ 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,
unsigned int palette_index,
hb_color_t foreground);
/* high-level funcs, with fallback */
@ -1131,6 +1129,16 @@ hb_font_set_ptem (hb_font_t *font, float ptem);
HB_EXTERN float
hb_font_get_ptem (hb_font_t *font);
HB_EXTERN void
hb_font_set_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);
@ -1142,6 +1150,11 @@ 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,
@ -1167,7 +1180,7 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
* named-instance index set. This is the default of
* a font.
*
* Since: REPLACEME
* Since: 7.0.0
*/
#define HB_FONT_NO_VAR_NAMED_INSTANCE 0xFFFFFFFF

Some files were not shown because too many files have changed in this diff Show More