Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen 262bfa025f hb-shape: Print table version where relevant
When listing tables with --list-tables, show
the version for CPAL and COLR tables.
2023-01-15 21:47:50 -05:00
303 changed files with 5064 additions and 11891 deletions

View File

@ -2,7 +2,7 @@
set -e
meson --cross-file=.ci/win32-cross-file.txt \
--wrap-mode=default \
--wrap-mode=forcefallback \
-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=default \
--wrap-mode=forcefallback \
-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 ninja
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection gtk-doc 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 -Ddocs=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
- 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 python3 python3-pip git g++-mingw-w64-i686 zip
- 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: 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 python3 python3-pip git g++-mingw-w64-x86-64 zip
- 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: pip3 install meson==0.60.0
- run: bash .ci/build-win64.sh
- store_artifacts:

View File

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

View File

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

View File

@ -15,57 +15,43 @@ jobs:
runs-on: ubuntu-20.04
steps:
- 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
- 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
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 }}
- name: Generate Coverage
# 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
run: ninja -Cbuild coverage-xml
- name: Upload Coverage
uses: codecov/codecov-action@v3
- uses: codecov/codecov-action@v3
with:
file: build/meson-logs/coverage.xml

View File

@ -14,47 +14,11 @@ jobs:
runs-on: macos-latest
steps:
- 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
- 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
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,35 +27,33 @@ jobs:
name: ${{ matrix.name }}
steps:
- 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
- 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

View File

@ -32,42 +32,44 @@ jobs:
run:
shell: msys2 {0}
steps:
- 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
- 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

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}/$<CONFIG>")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
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}/$<CONFIG>")
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
else ()
set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
endif ()

20
COPYING
View File

@ -2,23 +2,19 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
For parts of HarfBuzz that are licensed under different licenses see individual
files names COPYING in subdirectories where applicable.
Copyright © 2010-2022 Google, Inc.
Copyright © 2015-2020 Ebrahim Byagowi
Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc.
Copyright © 2018,2019,2020 Ebrahim Byagowi
Copyright © 2019,2020 Facebook, Inc.
Copyright © 2012,2015 Mozilla Foundation
Copyright © 2012 Mozilla Foundation
Copyright © 2011 Codethink Limited
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright © 2009 Keith Stribley
Copyright © 2011 Martin Hosken and SIL International
Copyright © 2009 Martin Hosken and SIL International
Copyright © 2007 Chris Wilson
Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod
Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.
Copyright © 1998-2005 David Turner and Werner Lemberg
Copyright © 2016 Igalia S.L.
Copyright © 2022 Matthias Clasen
Copyright © 2018,2021 Khaled Hosny
Copyright © 2018,2019,2020 Adobe, Inc
Copyright © 2013-2015 Alexei Podtelezhnikov
Copyright © 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
For full copyright notices consult the individual files in the package.

146
NEWS
View File

@ -1,149 +1,3 @@
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 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
- [ ] Search for REPLACEME on the repository and replace it with the chosen version for the release.
- [ ] Make sure you have correct date and new version at the top of NEWS file.

View File

@ -1,20 +0,0 @@
# 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],
[7.1.0],
[6.0.0],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])

View File

@ -56,7 +56,6 @@
<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"/>
@ -120,8 +119,6 @@
<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,4 +1,3 @@
<SECTION>
<SUBSECTION Private>
HB_H_IN
HB_OT_H_IN
@ -167,6 +166,15 @@ 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
@ -185,20 +193,6 @@ 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
@ -276,8 +270,6 @@ 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
@ -291,7 +283,6 @@ hb_paint_radial_gradient
hb_paint_sweep_gradient
hb_paint_push_group
hb_paint_pop_group
hb_paint_custom_palette_color
</SECTION>
<SECTION>
@ -417,12 +408,9 @@ 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
@ -606,8 +594,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>
@ -647,7 +635,6 @@ 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
@ -781,7 +768,6 @@ hb_set_t
<FILE>hb-shape</FILE>
hb_shape
hb_shape_full
hb_shape_justify
hb_shape_list_shapers
</SECTION>

View File

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

View File

@ -182,7 +182,8 @@
</para>
<itemizedlist>
<listitem>
<para><emphasis>Level 0</emphasis> is the default.
<para><emphasis>Level 0</emphasis> is the default and
reproduces the behavior of the old HarfBuzz library.
</para>
<para>
The distinguishing feature of level 0 behavior is that, at
@ -193,7 +194,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
@ -205,11 +206,6 @@
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
@ -224,13 +220,13 @@
implement backward compatibility with the old HarfBuzz.
</para>
<para>
<emphasis>Level 1</emphasis> differs from level 0 by not merging the
Level 1 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, coloring
mark glyphs differently than their base).
that might lead to improved results (for example, reordering
a sequence of marks).
</para>
<para>
Client programs can specify level 1 behavior for a buffer by
@ -246,7 +242,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.
@ -263,7 +259,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
@ -318,7 +314,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 id="glyphs-and-rendering">
<section>
<title>Glyphs and rendering</title>
<para>

View File

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

View File

@ -1,9 +1,8 @@
project('harfbuzz', 'c', 'cpp',
meson_version: '>= 0.55.0',
version: '7.1.0',
version: '6.0.0',
default_options: [
'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_rtti=false', # Just to support msvc, we are passing -fno-exceptions also anyway
'cpp_std=c++11',
'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
],
@ -28,12 +27,17 @@ 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([
@ -205,19 +209,10 @@ 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'
foreach func: check_cairo_funcs
name = func[0]
conf.set('HAVE_@0@'.format(name.to_upper()), 1)
endforeach
conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
else
check_funcs += check_cairo_funcs
check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
endif
endif
@ -373,10 +368,7 @@ foreach check : check_funcs
endforeach
subdir('src')
if not get_option('utilities').disabled()
subdir('util')
endif
subdir('util')
if not get_option('tests').disabled()
subdir('test')
@ -392,9 +384,6 @@ 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'),
@ -409,8 +398,7 @@ build_summary = {
'ICU': conf.get('HAVE_ICU', 0) == 1,
},
'Font callbacks (the more the merrier)':
{'Builtin' : true,
'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
{'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
},
'Dependencies used for command-line utilities':
{'Cairo': conf.get('HAVE_CAIRO', 0) == 1,
@ -427,7 +415,6 @@ 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,10 +29,6 @@ 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,9 +254,6 @@ 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 \
@ -278,7 +275,6 @@ 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)/' \
@ -382,7 +378,6 @@ noinst_PROGRAMS = \
test-ot-name \
test-ot-glyphname \
test-gpos-size-params \
test-gsub-get-alternates \
test-gsub-would-substitute \
test-use-table \
$(NULL)
@ -420,10 +415,6 @@ 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,8 +85,6 @@ 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 \
@ -114,7 +112,6 @@ 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 \
@ -169,7 +166,6 @@ 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 \
@ -225,7 +221,6 @@ 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 \
@ -261,8 +256,7 @@ HB_BASE_sources = \
HB_BASE_RAGEL_GENERATED_sources = \
hb-buffer-deserialize-json.hh \
hb-buffer-deserialize-text-glyphs.hh \
hb-buffer-deserialize-text-unicode.hh \
hb-buffer-deserialize-text.hh \
hb-number-parser.hh \
hb-ot-shaper-indic-machine.hh \
hb-ot-shaper-khmer-machine.hh \
@ -271,8 +265,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
$(NULL)
HB_BASE_RAGEL_sources = \
hb-buffer-deserialize-json.rl \
hb-buffer-deserialize-text-glyphs.rl \
hb-buffer-deserialize-text-unicode.rl \
hb-buffer-deserialize-text.rl \
hb-number-parser.rl \
hb-ot-shaper-indic-machine.rl \
hb-ot-shaper-khmer-machine.rl \
@ -358,7 +351,6 @@ 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,6 +30,7 @@
#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"
@ -40,6 +41,7 @@
*/
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
namespace OT {
struct hb_paint_context_t;
}
@ -65,7 +67,7 @@ public:
hb_paint_funcs_t *funcs;
void *data;
hb_font_t *font;
unsigned int palette_index;
unsigned int palette;
hb_color_t foreground;
VarStoreInstancer &instancer;
int depth_left = HB_MAX_NESTING_LEVEL;
@ -82,7 +84,7 @@ public:
funcs (funcs_),
data (data_),
font (font_),
palette_index (palette_),
palette (palette_),
foreground (foreground_),
instancer (instancer_)
{ }
@ -95,14 +97,10 @@ public:
if (color_index != 0xffff)
{
if (!funcs->custom_palette_color (data, color_index, &color))
{
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
}
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
hb_ot_color_palette_get_colors (face, palette, color_index, &clen, &color);
*is_foreground = false;
}
@ -241,15 +239,10 @@ struct Variable
void closurev1 (hb_colrv1_closure_context_t* c) const
{ value.closurev1 (c); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
if (!value.subset (c, instancer, varIdxBase)) return_trace (false);
if (c->plan->all_axes_pinned)
return_trace (true);
//TODO: update varIdxBase for partial-instancing
if (!value.subset (c)) return_trace (false);
return_trace (c->serializer->embed (varIdxBase));
}
@ -300,11 +293,10 @@ struct NoVariable
void closurev1 (hb_colrv1_closure_context_t* c) const
{ value.closurev1 (c); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
return_trace (value.subset (c, instancer, varIdxBase));
return_trace (value.subset (c));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -342,20 +334,11 @@ struct ColorStop
void closurev1 (hb_colrv1_closure_context_t* c) const
{ c->add_palette_index (paletteIndex); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) 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));
}
@ -404,8 +387,7 @@ struct ColorLine
stop.closurev1 (c);
}
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -417,7 +399,7 @@ struct ColorLine
for (const auto& stop : stops.iter ())
{
if (!stop.subset (c, instancer)) return_trace (false);
if (!stop.subset (c)) return_trace (false);
}
return_trace (true);
}
@ -538,25 +520,6 @@ 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,
@ -582,8 +545,7 @@ struct PaintColrLayers
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer HB_UNUSED) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
@ -614,20 +576,11 @@ struct PaintSolid
void closurev1 (hb_colrv1_closure_context_t* c) const
{ c->add_palette_index (paletteIndex); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) 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));
}
@ -662,28 +615,13 @@ struct PaintLinearGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2));
out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3));
out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4));
out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5));
}
if (format == 5 && c->plan->all_axes_pinned)
out->format = 4;
return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -728,28 +666,13 @@ struct PaintRadialGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2));
out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3));
out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4));
out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5));
}
if (format == 7 && c->plan->all_axes_pinned)
out->format = 6;
return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -794,26 +717,13 @@ struct PaintSweepGradient
void closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+colorLine).closurev1 (c); }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0));
out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1));
out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2)));
out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3)));
}
if (format == 9 && c->plan->all_axes_pinned)
out->format = 8;
return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -833,8 +743,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) * HB_PI,
(endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * HB_PI);
(startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI,
(endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
}
HBUINT8 format; /* format = 8(noVar) or 9 (Var) */
@ -853,8 +763,7 @@ struct PaintGlyph
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
@ -864,7 +773,7 @@ struct PaintGlyph
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
return_trace (out->paint.serialize_subset (c, paint, this, instancer));
return_trace (out->paint.serialize_subset (c, paint, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -895,8 +804,7 @@ struct PaintColrGlyph
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer HB_UNUSED) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
@ -925,16 +833,13 @@ struct PaintTransform
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false);
if (format == 13 && c->plan->all_axes_pinned)
out->format = 12;
return_trace (out->src.serialize_subset (c, src, this, instancer));
if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -963,24 +868,13 @@ struct PaintTranslate
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
}
if (format == 15 && c->plan->all_axes_pinned)
out->format = 14;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1011,24 +905,13 @@ struct PaintScale
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
}
if (format == 17 && c->plan->all_axes_pinned)
out->format = 16;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1059,26 +942,13 @@ struct PaintScaleAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
}
if (format == 19 && c->plan->all_axes_pinned)
out->format = 18;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1117,21 +987,13 @@ struct PaintScaleUniform
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
if (format == 21 && c->plan->all_axes_pinned)
out->format = 20;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1160,25 +1022,13 @@ struct PaintScaleUniformAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
}
if (format == 23 && c->plan->all_axes_pinned)
out->format = 22;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1215,21 +1065,13 @@ struct PaintRotate
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
if (format == 25 && c->plan->all_axes_pinned)
out->format = 24;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1258,25 +1100,13 @@ struct PaintRotateAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
}
if (format ==27 && c->plan->all_axes_pinned)
out->format = 26;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1313,24 +1143,13 @@ struct PaintSkew
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
}
if (format == 29 && c->plan->all_axes_pinned)
out->format = 28;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1361,26 +1180,13 @@ struct PaintSkewAroundCenter
{
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
uint32_t varIdxBase) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
{
out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
}
if (format == 31 && c->plan->all_axes_pinned)
out->format = 30;
return_trace (out->src.serialize_subset (c, src, this, instancer));
return_trace (out->src.serialize_subset (c, src, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1419,15 +1225,14 @@ struct PaintComposite
{
void closurev1 (hb_colrv1_closure_context_t* c) const;
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
if (!out->src.serialize_subset (c, src, this)) return_trace (false);
return_trace (out->backdrop.serialize_subset (c, backdrop, this));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1475,28 +1280,6 @@ 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;
@ -1524,22 +1307,21 @@ struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
struct ClipBox
{
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
ClipBox* copy (hb_serialize_context_t *c) const
{
TRACE_SUBSET (this);
TRACE_SERIALIZE (this);
switch (u.format) {
case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION));
case 2: return_trace (u.format2.subset (c, instancer));
default:return_trace (c->default_return_value ());
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);
}
}
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)...));
@ -1582,15 +1364,13 @@ struct ClipRecord
int cmp (hb_codepoint_t g) const
{ return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
bool subset (hb_subset_context_t *c,
const void *base,
const VarStoreInstancer &instancer) const
ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer));
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);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
@ -1617,8 +1397,7 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
struct ClipList
{
unsigned serialize_clip_records (hb_subset_context_t *c,
const VarStoreInstancer &instancer,
unsigned serialize_clip_records (hb_serialize_context_t *c,
const hb_set_t& gids,
const hb_map_t& gid_offset_map) const
{
@ -1650,7 +1429,7 @@ struct ClipList
record.endGlyphID = prev_gid;
record.clipBox = prev_offset;
if (!record.subset (c, this, instancer)) return_trace (0);
if (!c->copy (record, this)) return_trace (0);
count++;
start_gid = _;
@ -1664,14 +1443,13 @@ struct ClipList
record.startGlyphID = start_gid;
record.endGlyphID = prev_gid;
record.clipBox = prev_offset;
if (!record.subset (c, this, instancer)) return_trace (0);
if (!c->copy (record, this)) return_trace (0);
count++;
}
return_trace (count);
}
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
@ -1696,7 +1474,7 @@ struct ClipList
}
}
unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map);
unsigned count = serialize_clip_records (c->serializer, 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));
}
@ -1745,8 +1523,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)...));
@ -1830,8 +1608,7 @@ 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 VarStoreInstancer &instancer) const
const void* src_base, hb_subset_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = s->embed (this);
@ -1840,7 +1617,7 @@ struct BaseGlyphPaintRecord
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
return_trace (out->paint.serialize_subset (c, paint, src_base));
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
@ -1859,8 +1636,7 @@ struct BaseGlyphPaintRecord
struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
{
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -1872,7 +1648,7 @@ struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
unsigned gid = _.glyphId;
if (!glyphset->has (gid)) continue;
if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
else return_trace (false);
}
@ -1891,8 +1667,7 @@ struct LayerList : Array32OfOffset32To<Paint>
const Paint& get_paint (unsigned i) const
{ return this+(*this)[i]; }
bool subset (hb_subset_context_t *c,
const VarStoreInstancer &instancer) const
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
@ -1903,7 +1678,7 @@ struct LayerList : Array32OfOffset32To<Paint>
{
auto *o = out->serialize_append (c->serializer);
if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
return_trace (false);
}
return_trace (true);
@ -2105,6 +1880,7 @@ 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;
@ -2175,12 +1951,7 @@ struct COLR
auto snap = c->serializer->snapshot ();
if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
varIdxMap ? &(this+varIdxMap) : nullptr,
c->plan->normalized_coords.as_array ());
if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
{
if (c->serializer->in_error ()) return_trace (false);
//no more COLRv1 glyphs: downgrade to version 0
@ -2190,13 +1961,10 @@ 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, instancer);
colr_prime->clipList.serialize_subset (c, clipList, this, instancer);
if (!varStore || c->plan->all_axes_pinned)
return_trace (true);
colr_prime->layerList.serialize_subset (c, layerList, this);
colr_prime->clipList.serialize_subset (c, clipList, this);
colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
//TODO: subset varStore once it's implemented in fonttools
return_trace (true);
}
@ -2213,18 +1981,19 @@ 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 (get_clip (glyph, extents, instancer))
if ((this+clipList).get_extents (glyph,
extents,
instancer))
{
font->scale_glyph_extents (extents);
return true;
@ -2232,27 +2001,16 @@ struct COLR
auto *extents_funcs = hb_paint_extents_get_funcs ();
hb_paint_extents_context_t extents_data;
bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
hb_extents_t e = extents_data.get_extents ();
if (e.is_void ())
{
extents->x_bearing = 0;
extents->y_bearing = 0;
extents->width = 0;
extents->height = 0;
}
else
{
extents->x_bearing = e.xmin;
extents->y_bearing = e.ymax;
extents->width = e.xmax - e.xmin;
extents->height = e.ymin - e.ymax;
}
extents->x_bearing = e.xmin;
extents->y_bearing = e.ymax;
extents->width = e.xmax - e.xmin;
extents->height = e.ymin - e.ymax;
return ret;
return true;
}
#endif
bool
has_paint_for_glyph (hb_codepoint_t glyph) const
@ -2267,23 +2025,13 @@ struct COLR
return false;
}
bool get_clip (hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
const VarStoreInstancer instancer) const
{
return (this+clipList).get_extents (glyph,
extents,
instancer);
}
#ifndef HB_NO_PAINT
bool
paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
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
{
VarStoreInstancer instancer (&(this+varStore),
&(this+varIdxMap),
VarStoreInstancer instancer (this+varStore,
this+varIdxMap,
hb_array (font->coords, font->num_coords));
hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
hb_paint_context_t c (this, funcs, data, font, palette, foreground, instancer);
if (version == 1)
{
@ -2292,15 +2040,17 @@ 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 (get_clip (glyph, &extents, instancer))
if ((this+clipList).get_extents (glyph,
&extents,
instancer))
{
font->scale_glyph_extents (&extents);
c.funcs->push_clip_rectangle (c.data,
@ -2316,7 +2066,7 @@ struct COLR
paint_glyph (font, glyph,
extents_funcs, &extents_data,
palette_index, foreground,
palette, foreground,
false);
hb_extents_t extents = extents_data.get_extents ();
@ -2363,7 +2113,6 @@ struct COLR
return false;
}
#endif
protected:
HBUINT16 version; /* Table version number (starts at 0). */
@ -2414,21 +2163,9 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
const COLR *colr_table = c->get_colr_table ();
const Paint *paint = colr_table->get_base_glyph_paint (gid);
hb_glyph_extents_t extents = {0};
bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
if (has_clip_box)
c->funcs->push_clip_rectangle (c->data,
extents.x_bearing,
extents.y_bearing + extents.height,
extents.x_bearing + extents.width,
extents.y_bearing);
// TODO apply clipbox
if (paint)
c->recurse (*paint);
if (has_clip_box)
c->funcs->pop_clip (c->data);
}
} /* namespace OT */

View File

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

View File

@ -73,30 +73,6 @@ 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,
@ -119,10 +95,13 @@ struct CPALV1Tail
if (colorLabelsZ)
{
c->push ();
for (unsigned i = 0; i < color_count; i++)
for (const auto _ : colorLabels)
{
if (!color_index_map->has (i)) continue;
if (!c->copy<NameID> (colorLabels[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))
{
c->pop_discard ();
return_trace (false);
@ -210,13 +189,6 @@ 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,6 +29,7 @@
#define OT_COLOR_SBIX_SBIX_HH
#include "../../../hb-open-type.hh"
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-paint.hh"
/*

View File

@ -1,918 +0,0 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
* Copyright © 2010,2011,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
* Google Author(s): Behdad Esfahbod
*/
#ifndef OT_LAYOUT_GDEF_GDEF_HH
#define OT_LAYOUT_GDEF_GDEF_HH
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-font.hh"
namespace OT {
/*
* Attachment List Table
*/
/* Array of contour point indices--in increasing numerical order */
struct AttachPoint : Array16Of<HBUINT16>
{
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out)) return_trace (false);
return_trace (out->serialize (c->serializer, + iter ()));
}
};
struct AttachList
{
unsigned int get_attach_points (hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{
unsigned int index = (this+coverage).get_coverage (glyph_id);
if (index == NOT_COVERED)
{
if (point_count)
*point_count = 0;
return 0;
}
const AttachPoint &points = this+attachPoint[index];
if (point_count)
{
+ points.as_array ().sub_array (start_offset, point_count)
| hb_sink (hb_array (point_array, *point_count))
;
}
return points.len;
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, attachPoint)
| hb_filter (glyphset, hb_first)
| hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
}
protected:
Offset16To<Coverage>
coverage; /* Offset to Coverage table -- from
* beginning of AttachList table */
Array16OfOffset16To<AttachPoint>
attachPoint; /* Array of AttachPoint tables
* in Coverage Index order */
public:
DEFINE_SIZE_ARRAY (4, attachPoint);
};
/*
* Ligature Caret Table
*/
struct CaretValueFormat1
{
friend struct CaretValue;
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
return_trace (true);
}
private:
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
{
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
protected:
HBUINT16 caretValueFormat; /* Format identifier--format = 1 */
FWORD coordinate; /* X or Y value, in design units */
public:
DEFINE_SIZE_STATIC (4);
};
struct CaretValueFormat2
{
friend struct CaretValue;
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
return_trace (true);
}
private:
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
{
hb_position_t x, y;
font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
protected:
HBUINT16 caretValueFormat; /* Format identifier--format = 2 */
HBUINT16 caretValuePoint; /* Contour point index on glyph */
public:
DEFINE_SIZE_STATIC (4);
};
struct CaretValueFormat3
{
friend struct CaretValue;
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
const VariationStore &var_store) const
{
return HB_DIRECTION_IS_HORIZONTAL (direction) ?
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out)) return_trace (false);
if (!c->serializer->embed (caretValueFormat)) return_trace (false);
if (!c->serializer->embed (coordinate)) return_trace (false);
unsigned varidx = (this+deviceTable).get_variation_index ();
if (c->plan->layout_variation_idx_delta_map.has (varidx))
{
int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
if (delta != 0)
{
if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
}
}
if (c->plan->all_axes_pinned)
return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
if (!c->serializer->embed (deviceTable))
return_trace (false);
return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map));
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{ (this+deviceTable).collect_variation_indices (c); }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
}
protected:
HBUINT16 caretValueFormat; /* Format identifier--format = 3 */
FWORD coordinate; /* X or Y value, in design units */
Offset16To<Device>
deviceTable; /* Offset to Device table for X or Y
* value--from beginning of CaretValue
* table */
public:
DEFINE_SIZE_STATIC (6);
};
struct CaretValue
{
hb_position_t get_caret_value (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph_id,
const VariationStore &var_store) const
{
switch (u.format) {
case 1: return u.format1.get_caret_value (font, direction);
case 2: return u.format2.get_caret_value (font, direction, glyph_id);
case 3: return u.format3.get_caret_value (font, direction, var_store);
default:return 0;
}
}
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
TRACE_DISPATCH (this, u.format);
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{
switch (u.format) {
case 1:
case 2:
return;
case 3:
u.format3.collect_variation_indices (c);
return;
default: return;
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 1: return_trace (u.format1.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
case 3: return_trace (u.format3.sanitize (c));
default:return_trace (true);
}
}
protected:
union {
HBUINT16 format; /* Format identifier */
CaretValueFormat1 format1;
CaretValueFormat2 format2;
CaretValueFormat3 format3;
} u;
public:
DEFINE_SIZE_UNION (2, format);
};
struct LigGlyph
{
unsigned get_lig_carets (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph_id,
const VariationStore &var_store,
unsigned start_offset,
unsigned *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const
{
if (caret_count)
{
+ carets.as_array ().sub_array (start_offset, caret_count)
| hb_map (hb_add (this))
| hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
| hb_sink (hb_array (caret_array, *caret_count))
;
}
return carets.len;
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ hb_iter (carets)
| hb_apply (subset_offset_array (c, out->carets, this))
;
return_trace (bool (out->carets));
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{
for (const Offset16To<CaretValue>& offset : carets.iter ())
(this+offset).collect_variation_indices (c);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (carets.sanitize (c, this));
}
protected:
Array16OfOffset16To<CaretValue>
carets; /* Offset array of CaretValue tables
* --from beginning of LigGlyph table
* --in increasing coordinate order */
public:
DEFINE_SIZE_ARRAY (2, carets);
};
struct LigCaretList
{
unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph_id,
const VariationStore &var_store,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const
{
unsigned int index = (this+coverage).get_coverage (glyph_id);
if (index == NOT_COVERED)
{
if (caret_count)
*caret_count = 0;
return 0;
}
const LigGlyph &lig_glyph = this+ligGlyph[index];
return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ligGlyph)
| hb_filter (glyphset, hb_first)
| hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage));
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{
+ hb_zip (this+coverage, ligGlyph)
| hb_filter (c->glyph_set, hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
| hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
;
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
}
protected:
Offset16To<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of LigCaretList table */
Array16OfOffset16To<LigGlyph>
ligGlyph; /* Array of LigGlyph tables
* in Coverage Index order */
public:
DEFINE_SIZE_ARRAY (4, ligGlyph);
};
struct MarkGlyphSetsFormat1
{
bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
bool ret = true;
for (const Offset32To<Coverage>& offset : coverage.iter ())
{
auto *o = out->coverage.serialize_append (c->serializer);
if (unlikely (!o))
{
ret = false;
break;
}
//not using o->serialize_subset (c, offset, this, out) here because
//OTS doesn't allow null offset.
//See issue: https://github.com/khaledhosny/ots/issues/172
c->serializer->push ();
c->dispatch (this+offset);
c->serializer->add_link (*o, c->serializer->pop_pack ());
}
return_trace (ret && out->coverage.len);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (coverage.sanitize (c, this));
}
protected:
HBUINT16 format; /* Format identifier--format = 1 */
Array16Of<Offset32To<Coverage>>
coverage; /* Array of long offsets to mark set
* coverage tables */
public:
DEFINE_SIZE_ARRAY (4, coverage);
};
struct MarkGlyphSets
{
bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
{
switch (u.format) {
case 1: return u.format1.covers (set_index, glyph_id);
default:return false;
}
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
switch (u.format) {
case 1: return_trace (u.format1.subset (c));
default:return_trace (false);
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 1: return_trace (u.format1.sanitize (c));
default:return_trace (true);
}
}
protected:
union {
HBUINT16 format; /* Format identifier */
MarkGlyphSetsFormat1 format1;
} u;
public:
DEFINE_SIZE_UNION (2, format);
};
/*
* GDEF -- Glyph Definition
* https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
*/
template <typename Types>
struct GDEFVersion1_2
{
friend struct GDEF;
protected:
FixedVersion<>version; /* Version of the GDEF table--currently
* 0x00010003u */
typename Types::template OffsetTo<ClassDef>
glyphClassDef; /* Offset to class definition table
* for glyph type--from beginning of
* GDEF header (may be Null) */
typename Types::template OffsetTo<AttachList>
attachList; /* Offset to list of glyphs with
* attachment points--from beginning
* of GDEF header (may be Null) */
typename Types::template OffsetTo<LigCaretList>
ligCaretList; /* Offset to list of positioning points
* for ligature carets--from beginning
* of GDEF header (may be Null) */
typename Types::template OffsetTo<ClassDef>
markAttachClassDef; /* Offset to class definition table for
* mark attachment type--from beginning
* of GDEF header (may be Null) */
typename Types::template OffsetTo<MarkGlyphSets>
markGlyphSetsDef; /* Offset to the table of mark set
* definitions--from beginning of GDEF
* header (may be NULL). Introduced
* in version 0x00010002. */
Offset32To<VariationStore>
varStore; /* Offset to the table of Item Variation
* Store--from beginning of GDEF
* header (may be NULL). Introduced
* in version 0x00010003. */
public:
DEFINE_SIZE_MIN (4 + 4 * Types::size);
unsigned int get_size () const
{
return min_size +
(version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
(version.to_int () >= 0x00010003u ? varStore.static_size : 0);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (version.sanitize (c) &&
glyphClassDef.sanitize (c, this) &&
attachList.sanitize (c, this) &&
ligCaretList.sanitize (c, this) &&
markAttachClassDef.sanitize (c, this) &&
(version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
(version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
bool subset_markglyphsetsdef = false;
if (version.to_int () >= 0x00010002u)
{
subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
}
bool subset_varstore = false;
if (version.to_int () >= 0x00010003u)
{
if (c->plan->all_axes_pinned)
out->varStore = 0;
else
subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
}
if (subset_varstore)
{
out->version.minor = 3;
} else if (subset_markglyphsetsdef) {
out->version.minor = 2;
} else {
out->version.minor = 0;
}
return_trace (subset_glyphclassdef || subset_attachlist ||
subset_ligcaretlist || subset_markattachclassdef ||
(out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
(out->version.to_int () >= 0x00010003u && subset_varstore));
}
};
struct GDEF
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
enum GlyphClasses {
UnclassifiedGlyph = 0,
BaseGlyph = 1,
LigatureGlyph = 2,
MarkGlyph = 3,
ComponentGlyph = 4
};
unsigned int get_size () const
{
switch (u.version.major) {
case 1: return u.version1.get_size ();
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.get_size ();
#endif
default: return u.version.static_size;
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!u.version.sanitize (c))) return_trace (false);
switch (u.version.major) {
case 1: return_trace (u.version1.sanitize (c));
#ifndef HB_NO_BEYOND_64K
case 2: return_trace (u.version2.sanitize (c));
#endif
default: return_trace (true);
}
}
bool subset (hb_subset_context_t *c) const
{
switch (u.version.major) {
case 1: return u.version1.subset (c);
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.subset (c);
#endif
default: return false;
}
}
bool has_glyph_classes () const
{
switch (u.version.major) {
case 1: return u.version1.glyphClassDef != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.glyphClassDef != 0;
#endif
default: return false;
}
}
const ClassDef &get_glyph_class_def () const
{
switch (u.version.major) {
case 1: return this+u.version1.glyphClassDef;
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.glyphClassDef;
#endif
default: return Null(ClassDef);
}
}
bool has_attach_list () const
{
switch (u.version.major) {
case 1: return u.version1.attachList != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.attachList != 0;
#endif
default: return false;
}
}
const AttachList &get_attach_list () const
{
switch (u.version.major) {
case 1: return this+u.version1.attachList;
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.attachList;
#endif
default: return Null(AttachList);
}
}
bool has_lig_carets () const
{
switch (u.version.major) {
case 1: return u.version1.ligCaretList != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.ligCaretList != 0;
#endif
default: return false;
}
}
const LigCaretList &get_lig_caret_list () const
{
switch (u.version.major) {
case 1: return this+u.version1.ligCaretList;
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.ligCaretList;
#endif
default: return Null(LigCaretList);
}
}
bool has_mark_attachment_types () const
{
switch (u.version.major) {
case 1: return u.version1.markAttachClassDef != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.markAttachClassDef != 0;
#endif
default: return false;
}
}
const ClassDef &get_mark_attach_class_def () const
{
switch (u.version.major) {
case 1: return this+u.version1.markAttachClassDef;
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.markAttachClassDef;
#endif
default: return Null(ClassDef);
}
}
bool has_mark_glyph_sets () const
{
switch (u.version.major) {
case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.markGlyphSetsDef != 0;
#endif
default: return false;
}
}
const MarkGlyphSets &get_mark_glyph_sets () const
{
switch (u.version.major) {
case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.markGlyphSetsDef;
#endif
default: return Null(MarkGlyphSets);
}
}
bool has_var_store () const
{
switch (u.version.major) {
case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
#ifndef HB_NO_BEYOND_64K
case 2: return u.version2.varStore != 0;
#endif
default: return false;
}
}
const VariationStore &get_var_store () const
{
switch (u.version.major) {
case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore);
#ifndef HB_NO_BEYOND_64K
case 2: return this+u.version2.varStore;
#endif
default: return Null(VariationStore);
}
}
bool has_data () const { return u.version.to_int (); }
unsigned int get_glyph_class (hb_codepoint_t glyph) const
{ return get_glyph_class_def ().get_class (glyph); }
void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
{ get_glyph_class_def ().collect_class (glyphs, klass); }
unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
{ return get_mark_attach_class_def ().get_class (glyph); }
unsigned int get_attach_points (hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{ return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const
{ return get_lig_caret_list ().get_lig_carets (font,
direction, glyph_id, get_var_store(),
start_offset, caret_count, caret_array); }
bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
{ return get_mark_glyph_sets ().covers (set_index, glyph_id); }
/* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
* glyph class and other bits, and high 8-bit the mark attachment type (if any).
* Not to be confused with lookup_props which is very similar. */
unsigned int get_glyph_props (hb_codepoint_t glyph) const
{
unsigned int klass = get_glyph_class (glyph);
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
switch (klass) {
default: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
case MarkGlyph:
klass = get_mark_attachment_type (glyph);
return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
}
}
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const;
struct accelerator_t
{
accelerator_t (hb_face_t *face)
{
table = hb_sanitize_context_t ().reference_table<GDEF> (face);
if (unlikely (table->is_blocklisted (table.get_blob (), face)))
{
hb_blob_destroy (table.get_blob ());
table = hb_blob_get_empty ();
}
}
~accelerator_t () { table.destroy (); }
hb_blob_ptr_t<GDEF> table;
};
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{ get_lig_caret_list ().collect_variation_indices (c); }
void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
{
if (!has_var_store ()) return;
if (layout_variation_indices->is_empty ()) return;
unsigned new_major = 0, new_minor = 0;
unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
for (unsigned idx : layout_variation_indices->iter ())
{
uint16_t major = idx >> 16;
if (major >= get_var_store ().get_sub_table_count ()) break;
if (major != last_major)
{
new_minor = 0;
++new_major;
}
unsigned new_idx = (new_major << 16) + new_minor;
if (!layout_variation_idx_delta_map->has (idx))
continue;
int delta = hb_second (layout_variation_idx_delta_map->get (idx));
layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
++new_minor;
last_major = major;
}
}
protected:
union {
FixedVersion<> version; /* Version identifier */
GDEFVersion1_2<SmallTypes> version1;
#ifndef HB_NO_BEYOND_64K
GDEFVersion1_2<MediumTypes> version2;
#endif
} u;
public:
DEFINE_SIZE_MIN (4);
};
struct GDEF_accelerator_t : GDEF::accelerator_t {
GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
};
} /* namespace OT */
#endif /* OT_LAYOUT_GDEF_GDEF_HH */

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,25 +90,6 @@ 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);
@ -116,54 +97,48 @@ 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.
* We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
/* 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);
if (c->last_base_until > buffer->idx)
{
c->last_base_until = 0;
c->last_base = -1;
}
unsigned j;
for (j = buffer->idx; j > c->last_base_until; j--)
{
auto match = skippy_iter.match (buffer->info[j - 1]);
if (match == skippy_iter.MATCH)
do {
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
{
// 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;
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
return_trace (false);
}
if (match == skippy_iter.MATCH)
{
c->last_base = (signed) j - 1;
break;
}
}
c->last_base_until = buffer->idx;
if (c->last_base == -1)
{
buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
return_trace (false);
}
unsigned idx = (unsigned) c->last_base;
/* 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[idx])) { return_trace (false); }
//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[idx].codepoint);
unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint);
if (base_index == NOT_COVERED)
{
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
}
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx));
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.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,41 +100,24 @@ 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);
if (c->last_base_until > buffer->idx)
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
{
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);
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
return_trace (false);
}
unsigned idx = (unsigned) c->last_base;
/* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
//if (!_hb_glyph_info_is_ligature (&buffer->info[idx])) { return_trace (false); }
//if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[idx].codepoint);
unsigned int j = skippy_iter.idx;
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
if (lig_index == NOT_COVERED)
{
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
}
@ -145,7 +128,7 @@ struct MarkLigPosFormat1_2
unsigned int comp_count = lig_attach.rows;
if (unlikely (!comp_count))
{
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
}
@ -154,7 +137,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[idx]);
unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
if (lig_id && lig_id == mark_id && mark_comp > 0)
@ -162,7 +145,7 @@ struct MarkLigPosFormat1_2
else
comp_index = comp_count - 1;
return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
}
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,
PairSet::get_size (len1, len2)
1 + 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 : glyphs->iter())
for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
{
unsigned i = cov.get_coverage (g);
if ((this+pairSet[i]).intersects (glyphs, valueFormat))
@ -177,7 +177,9 @@ struct PairPosFormat1_3
hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
{
unsigned record_size = PairSet::get_size (valueFormat);
unsigned len1 = valueFormat[0].get_len ();
unsigned len2 = valueFormat[1].get_len ();
unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
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 = HBUINT16::static_size * (len1 + len2);
unsigned int stride = len1 + len2;
unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
return_trace (c->check_range ((const void *) values,

View File

@ -24,22 +24,11 @@ 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; /* bytes */
unsigned int stride; /* 1 + len1 + len2 */
};
bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
@ -48,6 +37,7 @@ struct PairSet
if (!(c->check_struct (this)
&& c->check_range (&firstPairValueRecord,
len,
HBUINT16::static_size,
closure->stride))) return_trace (false);
unsigned int count = len;
@ -59,7 +49,9 @@ struct PairSet
bool intersects (const hb_set_t *glyphs,
const ValueFormat *valueFormats) const
{
unsigned record_size = get_size (valueFormats);
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = &firstPairValueRecord;
unsigned int count = len;
@ -75,7 +67,9 @@ struct PairSet
void collect_glyphs (hb_collect_glyphs_context_t *c,
const ValueFormat *valueFormats) const
{
unsigned record_size = get_size (valueFormats);
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = &firstPairValueRecord;
c->input->add_array (&record->secondGlyph, len, record_size);
@ -84,7 +78,9 @@ struct PairSet
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
const ValueFormat *valueFormats) const
{
unsigned record_size = get_size (valueFormats);
unsigned len1 = valueFormats[0].get_len ();
unsigned len2 = valueFormats[1].get_len ();
unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = &firstPairValueRecord;
unsigned count = len;
@ -105,7 +101,7 @@ struct PairSet
hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned record_size = get_size (len1, len2);
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
&firstPairValueRecord,
@ -172,7 +168,7 @@ struct PairSet
unsigned len1 = valueFormats[0].get_len ();
unsigned len2 = valueFormats[1].get_len ();
unsigned record_size = get_size (len1, len2);
unsigned record_size = HBUINT16::static_size + Value::static_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,15 +28,7 @@ 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 = &StructAtOffset<const Value> (values, stride);
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,9 +29,6 @@ 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,18 +34,6 @@ 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_lig_glyph (&glyphset);
return _.intersects (&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,15 +25,7 @@ struct SingleSubstFormat1_3
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
coverage.sanitize (c, this) &&
/* The coverage table may use a range to represent a set
* of glyphs, which means a small number of bytes can
* generate a large glyph set. Manually modify the
* sanitizer max ops to take this into account.
*
* Note: This check *must* be right after coverage sanitize. */
c->check_ops ((this + coverage).get_population () >> 1));
return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
}
hb_codepoint_t get_mask () const
@ -95,34 +87,6 @@ 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,31 +75,6 @@ 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,34 +87,27 @@ struct CompositeGlyphRecord
}
}
void transform_points (contour_point_vector_t &points,
const float (&matrix)[4],
const contour_point_t &trans) const
{
if (scaled_offsets ())
{
points.translate (trans);
points.transform (matrix);
}
else
{
points.transform (matrix);
points.translate (trans);
}
}
bool get_points (contour_point_vector_t &points) const
void transform_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;
if (get_transformation (matrix, trans))
{
if (scaled_offsets ())
{
points.translate (trans);
points.transform (matrix);
}
else
{
points.transform (matrix);
points.translate (trans);
}
}
}
unsigned compile_with_point (const contour_point_t &point,
char *out) const
unsigned compile_with_deltas (const contour_point_t &p_delta,
char *out) const
{
const HBINT8 *p = &StructAfter<const HBINT8> (flags);
#ifndef HB_NO_BEYOND_64K
@ -128,17 +121,18 @@ struct CompositeGlyphRecord
unsigned len_before_val = (const char *)p - (const char *)this;
if (flags & ARG_1_AND_2_ARE_WORDS)
{
// no overflow, copy value
// no overflow, copy and update value with deltas
hb_memcpy (out, this, len);
const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
o[0] = roundf (point.x);
o[1] = roundf (point.y);
o[0] = px[0] + roundf (p_delta.x);
o[1] = px[1] + roundf (p_delta.y);
}
else
{
int new_x = roundf (point.x);
int new_y = roundf (point.y);
int new_x = p[0] + roundf (p_delta.x);
int new_y = p[1] + roundf (p_delta.y);
if (new_x <= 127 && new_x >= -128 &&
new_y <= 127 && new_y >= -128)
{
@ -149,7 +143,7 @@ struct CompositeGlyphRecord
}
else
{
// new point value has an int8 overflow
// int8 overflows after deltas applied
hb_memcpy (out, this, len_before_val);
//update flags
@ -177,7 +171,6 @@ 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;
@ -232,6 +225,7 @@ struct CompositeGlyphRecord
return tx || ty;
}
public:
hb_codepoint_t get_gid () const
{
#ifndef HB_NO_BEYOND_64K
@ -252,27 +246,6 @@ 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;
@ -331,7 +304,7 @@ struct CompositeGlyph
}
bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
const contour_point_vector_t &points_with_deltas,
const contour_point_vector_t &deltas,
hb_bytes_t &dest_bytes /* OUT */)
{
if (source_bytes.length <= GlyphHeader::static_size ||
@ -346,7 +319,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 * 2, sizeof (char));
char *o = (char *) hb_calloc (source_len + source_len/2, sizeof (char));
if (unlikely (!o)) return false;
const CompositeGlyphRecord *c = reinterpret_cast<const CompositeGlyphRecord *> (source_bytes.arrayZ + GlyphHeader::static_size);
@ -356,11 +329,8 @@ struct CompositeGlyph
unsigned i = 0, source_comp_len = 0;
for (const auto &component : it)
{
/* last 4 points in points_with_deltas are phantom points and should not be included */
if (i >= points_with_deltas.length - 4) {
free (o);
return false;
}
/* last 4 points in deltas are phantom points and should not be included */
if (i >= deltas.length - 4) return false;
unsigned comp_len = component.get_size ();
if (component.is_anchored ())
@ -370,7 +340,7 @@ struct CompositeGlyph
}
else
{
unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
unsigned new_len = component.compile_with_deltas (deltas[i], p);
p += new_len;
}
i++;

View File

@ -29,14 +29,7 @@ enum phantom_point_index_t
struct Glyph
{
enum glyph_type_t {
EMPTY,
SIMPLE,
COMPOSITE,
#ifndef HB_NO_VAR_COMPOSITES
VAR_COMPOSITE,
#endif
};
enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
public:
composite_iter_t get_composite_iterator () const
@ -46,23 +39,15 @@ 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;
}
}
@ -70,54 +55,38 @@ 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;
case EMPTY: return;
default: return;
}
}
void set_overlaps_flag ()
{
switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
case VAR_COMPOSITE: return; // No overlaps flag
#endif
case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
case EMPTY: return;
default: return;
}
}
void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
{
switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
case VAR_COMPOSITE: return; // No hinting
#endif
case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
case SIMPLE: SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
case EMPTY: return;
default: return;
}
}
void update_mtx (const hb_subset_plan_t *plan,
int xMin, int xMax,
int yMin, int yMax,
int xMin, 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;
@ -128,9 +97,6 @@ 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;
@ -143,7 +109,7 @@ struct Glyph
hb_bytes_t &dest_bytes /* OUT */) const
{
GlyphHeader *glyph_header = nullptr;
if (!plan->pinned_at_default && type != EMPTY && all_points.length >= 4)
if (type != EMPTY && all_points.length > 4)
{
glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
if (unlikely (!glyph_header)) return false;
@ -167,33 +133,18 @@ struct Glyph
yMax = hb_max (yMax, y);
}
update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
int rounded_xMin = roundf (xMin);
int rounded_xMax = roundf (xMax);
int rounded_yMin = roundf (yMin);
int rounded_yMax = roundf (yMax);
update_mtx (plan, roundf (xMin), roundf (yMax), all_points);
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 */
/*for empty glyphs: all_points only include phantom points.
*just update metrics and then return */
if (!glyph_header)
return true;
glyph_header->numberOfContours = header->numberOfContours;
glyph_header->xMin = rounded_xMin;
glyph_header->yMin = rounded_yMin;
glyph_header->xMax = rounded_xMax;
glyph_header->yMax = rounded_yMax;
glyph_header->xMin = roundf (xMin);
glyph_header->yMin = roundf (yMin);
glyph_header->xMax = roundf (xMax);
glyph_header->yMax = roundf (yMax);
dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
return true;
@ -205,64 +156,35 @@ struct Glyph
hb_bytes_t &dest_start, /* IN/OUT */
hb_bytes_t &dest_end /* OUT */)
{
contour_point_vector_t all_points, points_with_deltas;
unsigned composite_contours = 0;
head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
unsigned *composite_contours_p = &composite_contours;
// don't compute head/maxp values when glyph has no contours(type is EMPTY)
// also ignore .notdef glyph when --notdef-outline is not enabled
if (type == EMPTY ||
(gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)))
{
head_maxp_info_p = nullptr;
composite_contours_p = nullptr;
}
if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false))
contour_point_vector_t all_points, deltas;
if (!get_points (font, glyf, all_points, &deltas, 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 ();
}
//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;
}
break;
}
if (!compile_header_bytes (plan, all_points, dest_start))
@ -280,26 +202,14 @@ 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 *points_with_deltas = nullptr, /* OUT */
head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
unsigned *composite_contours = nullptr, /* OUT */
contour_point_vector_t *deltas = nullptr, /* OUT */
bool shift_points_hori = true,
bool use_my_metrics = true,
bool phantom_only = false,
hb_array_t<int> coords = hb_array_t<int> (),
unsigned int depth = 0,
unsigned *edge_count = nullptr) const
unsigned int depth = 0) 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);
@ -311,17 +221,14 @@ 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:
{
for (auto &item : get_composite_iterator ())
if (unlikely (!item.get_points (points))) return false;
/* 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;
break;
}
#ifndef HB_NO_VAR_COMPOSITES
@ -331,7 +238,7 @@ struct Glyph
if (unlikely (!item.get_points (points))) return false;
}
#endif
case EMPTY:
default:
break;
}
@ -359,11 +266,17 @@ struct Glyph
#endif
;
phantoms[PHANTOM_LEFT].x = h_delta;
phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
phantoms[PHANTOM_RIGHT].x = 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,
@ -372,16 +285,17 @@ struct Glyph
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
// with child glyphs' points
if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
{
if (unlikely (!points_with_deltas->resize (points.length))) return false;
points_with_deltas->copy_vector (points);
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;
}
}
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;
@ -392,19 +306,17 @@ 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,
points_with_deltas,
head_maxp_info,
composite_contours,
deltas,
shift_points_hori,
use_my_metrics,
phantom_only,
coords,
depth + 1,
edge_count)))
depth + 1)))
return false;
/* Copy phantom points from component if USE_MY_METRICS flag set */
@ -412,12 +324,11 @@ struct Glyph
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
float matrix[4];
contour_point_t default_trans;
item.get_transformation (matrix, default_trans);
/* Apply component transformation & translation */
item.transform_points (comp_points);
/* Apply component transformation & translation (with deltas applied) */
item.transform_points (comp_points, matrix, points[comp_index]);
/* Apply translation from gvar */
comp_points.translate (points[comp_index]);
if (item.is_anchored ())
{
@ -441,13 +352,6 @@ 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
@ -461,26 +365,19 @@ struct Glyph
comp_points.reset ();
auto component_coords = coords;
if (item.is_reset_unspecified_axes ())
component_coords = hb_array<int> ();
coord_setter_t coord_setter (component_coords);
coord_setter_t coord_setter (hb_array (font->coords, font->num_coords));
item.set_variations (coord_setter, record_points);
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
.get_points (font,
glyf_accelerator,
comp_points,
points_with_deltas,
head_maxp_info,
nullptr,
deltas,
shift_points_hori,
use_my_metrics,
phantom_only,
coord_setter.get_coords (),
depth + 1,
edge_count)))
depth + 1)))
return false;
/* Apply component transformation */
@ -501,7 +398,7 @@ struct Glyph
all_points.extend (phantoms);
} break;
#endif
case EMPTY:
default:
all_points.extend (phantoms);
break;
}
@ -527,8 +424,6 @@ 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> ()),
@ -544,9 +439,7 @@ 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 */
}
@ -554,7 +447,7 @@ struct Glyph
hb_bytes_t bytes;
const GlyphHeader *header;
hb_codepoint_t gid;
glyph_type_t type;
unsigned type;
};

View File

@ -20,7 +20,7 @@ struct SimpleGlyph
FLAG_X_SAME = 0x10,
FLAG_Y_SAME = 0x20,
FLAG_OVERLAP_SIMPLE = 0x40,
FLAG_CUBIC = 0x80
FLAG_RESERVED2 = 0x80
};
const GlyphHeader &header;
@ -34,11 +34,6 @@ 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 ();
@ -99,7 +94,6 @@ 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,21 +18,23 @@ 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)
const hb_subset_plan_t *plan,
hb_font_t *font)
{
TRACE_SERIALIZE (this);
hb_bytes_t dest_glyph = dest_start.copy (c);
hb_bytes_t end_copy = dest_end.copy (c);
if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
return false;
if (font)
{
const OT::glyf_accelerator_t &glyf = *font->face->table.glyf;
if (!this->compile_bytes_with_deltas (plan, font, glyf))
return_trace (false);
}
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).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);
@ -46,68 +48,13 @@ 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 ();
@ -121,18 +68,12 @@ struct SubsetGlyph
bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
hb_font_t *font,
const glyf_accelerator_t &glyf)
{
allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
return allocated;
}
{ return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); }
void free_compiled_bytes ()
{
if (likely (allocated)) {
allocated = false;
dest_start.fini ();
dest_end.fini ();
}
dest_start.fini ();
dest_end.fini ();
}
void drop_hints_bytes ()

View File

@ -27,9 +27,8 @@ struct VarCompositeGlyphRecord
HAVE_SKEW_Y = 0x0200,
HAVE_TCENTER_X = 0x0400,
HAVE_TCENTER_Y = 0x0800,
GID_IS_24BIT = 0x1000,
GID_IS_24 = 0x1000,
AXES_HAVE_VARIATION = 0x2000,
RESET_UNSPECIFIED_AXES = 0x4000,
};
public:
@ -43,7 +42,7 @@ struct VarCompositeGlyphRecord
// gid
size += 2;
if (flags & GID_IS_24BIT) size += 1;
if (flags & GID_IS_24) size += 1;
if (flags & HAVE_TRANSLATE_X) size += 2;
if (flags & HAVE_TRANSLATE_Y) size += 2;
@ -61,24 +60,15 @@ 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_24BIT)
if (flags & GID_IS_24)
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;
@ -153,7 +143,7 @@ struct VarCompositeGlyphRecord
float rotation)
{
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
rotation = rotation * HB_PI;
rotation = rotation * float (M_PI);
float c = cosf (rotation);
float s = sinf (rotation);
float other[6] = {c, s, -s, c, 0.f, 0.f};
@ -164,8 +154,8 @@ struct VarCompositeGlyphRecord
float skewX, float skewY)
{
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
skewX = skewX * HB_PI;
skewY = skewY * HB_PI;
skewX = skewX * float (M_PI);
skewY = skewY * float (M_PI);
float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
transform (matrix, trans, other);
}
@ -188,7 +178,7 @@ struct VarCompositeGlyphRecord
unsigned axes_size = numAxes * axis_width;
const F2DOT14 *q = (const F2DOT14 *) (axes_size +
(flags & GID_IS_24BIT ? 3 : 2) +
(flags & GID_IS_24 ? 3 : 2) +
&StructAfter<const HBUINT8> (numAxes));
hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - get_num_points ());
@ -316,8 +306,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_24BIT ? 3 : 2));
const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
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 F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
@ -352,13 +342,6 @@ 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,20 +44,6 @@ _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,12 +31,6 @@ 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);
@ -49,13 +43,14 @@ struct glyf
bool serialize (hb_serialize_context_t *c,
Iterator it,
bool use_short_loca,
const hb_subset_plan_t *plan)
const hb_subset_plan_t *plan,
hb_font_t *font)
{
TRACE_SERIALIZE (this);
unsigned init_len = c->length ();
for (auto &_ : it)
if (unlikely (!_.serialize (c, use_short_loca, plan)))
if (unlikely (!_.serialize (c, use_short_loca, plan, font)))
return false;
/* As a special case when all glyph in the font are empty, add a zero byte
@ -78,82 +73,62 @@ 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->normalized_coords)
if (!c->plan->pinned_at_default)
{
font = _create_font_for_instancing (c->plan);
if (unlikely (!font)) return false;
}
hb_vector_t<unsigned> padded_offsets;
unsigned num_glyphs = c->plan->num_output_glyphs ();
if (unlikely (!padded_offsets.resize (num_glyphs)))
{
hb_font_destroy (font);
return false;
}
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
if (!_populate_subset_glyphs (c->plan, font, glyphs))
{
hb_font_destroy (font);
return false;
}
if (font)
hb_font_destroy (font);
unsigned max_offset = 0;
for (unsigned i = 0; i < num_glyphs; i++)
{
padded_offsets[i] = glyphs[i].padded_size ();
max_offset += padded_offsets[i];
}
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))
{
unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
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);
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)
;
}
if (!result) return false;
if (font)
{
_free_compiled_subset_glyphs (&glyphs);
hb_font_destroy (font);
}
if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
padded_offsets.iter (),
padded_offsets,
use_short_loca)));
}
bool
void
_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 (unsigned i = 0; i < glyphs.length; i++)
glyphs[i].free_compiled_bytes ();
for (auto _ : *glyphs)
_.free_compiled_bytes ();
}
protected:
@ -181,7 +156,7 @@ struct glyf_accelerator_t
vmtx = nullptr;
#endif
const OT::head &head = *face->table.head;
if (!glyf::has_valid_glyf_format (face))
if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
/* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
return;
short_offset = 0 == head.indexToLocFormat;
@ -219,7 +194,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, nullptr, nullptr, true, true, phantom_only)))
if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, true, phantom_only)))
return false;
if (consumer.is_consuming_contour_points ())
@ -241,8 +216,6 @@ struct glyf_accelerator_t
return true;
}
public:
#ifndef HB_NO_VAR
struct points_aggregator_t
{
@ -306,6 +279,7 @@ 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
{
@ -347,15 +321,6 @@ 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
{
@ -425,14 +390,13 @@ struct glyf_accelerator_t
};
inline bool
inline void
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
hb_font_t *font,
hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
{
OT::glyf_accelerator_t glyf (plan->source);
unsigned num_glyphs = plan->num_output_glyphs ();
if (!glyphs.resize (num_glyphs)) return false;
if (!glyphs.resize (num_glyphs)) return;
for (auto p : plan->glyph_map->iter ())
{
@ -442,7 +406,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
if (unlikely (new_gid == 0 &&
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
!plan->normalized_coords)
plan->pinned_at_default)
subset_glyph.source_glyph = glyf_impl::Glyph ();
else
{
@ -455,19 +419,7 @@ 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 *
@ -478,10 +430,7 @@ 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,29 +26,22 @@ 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, first_offcurve2, last_offcurve, last_offcurve2;
} first_oncurve, first_offcurve, last_offcurve;
path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
{
font = font_;
draw_session = &draw_session_;
first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
}
/* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
See also:
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
* https://stackoverflow.com/a/20772557
*
* Cubic support added. */
* https://stackoverflow.com/a/20772557 */
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)
{
@ -59,12 +52,7 @@ struct path_builder_t
}
else
{
if (is_cubic && !first_offcurve2)
{
first_offcurve2 = first_offcurve;
first_offcurve = p;
}
else if (first_offcurve)
if (first_offcurve)
{
optional_point_t mid = first_offcurve.lerp (p, .5f);
first_oncurve = mid;
@ -81,41 +69,16 @@ struct path_builder_t
{
if (is_on_curve)
{
if (last_offcurve2)
{
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
p.x, p.y);
last_offcurve2 = optional_point_t ();
}
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
p.x, p.y);
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
p.x, p.y);
last_offcurve = optional_point_t ();
}
else
{
if (is_cubic && !last_offcurve2)
{
last_offcurve2 = last_offcurve;
last_offcurve = p;
}
else
{
optional_point_t mid = last_offcurve.lerp (p, .5f);
if (is_cubic)
{
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
last_offcurve2 = optional_point_t ();
}
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
last_offcurve = p;
}
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;
}
}
else
@ -131,40 +94,19 @@ struct path_builder_t
{
if (first_offcurve && last_offcurve)
{
optional_point_t mid = last_offcurve.lerp (first_offcurve2 ?
first_offcurve2 :
first_offcurve, .5f);
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
mid.x, mid.y);
optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
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)
{
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);
}
draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
first_oncurve.x, first_oncurve.y);
else if (last_offcurve && first_oncurve)
{
if (last_offcurve2)
draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
else
draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
first_oncurve.x, first_oncurve.y);
}
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)
@ -175,7 +117,7 @@ struct path_builder_t
}
/* Getting ready for the next contour */
first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
draw_session->close_path ();
}
}

View File

@ -1,589 +0,0 @@
/*
* Copyright © 2011,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef OT_NAME_NAME_HH
#define OT_NAME_NAME_HH
#include "../../hb-open-type.hh"
#include "../../hb-ot-name-language.hh"
#include "../../hb-aat-layout.hh"
#include "../../hb-utf.hh"
namespace OT {
template <typename in_utf_t, typename out_utf_t>
inline unsigned int
hb_ot_name_convert_utf (hb_bytes_t bytes,
unsigned int *text_size /* IN/OUT */,
typename out_utf_t::codepoint_t *text /* OUT */)
{
unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
const typename in_utf_t::codepoint_t *src_end = src + src_len;
typename out_utf_t::codepoint_t *dst = text;
hb_codepoint_t unicode;
const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
if (text_size && *text_size)
{
(*text_size)--; /* Save room for NUL-termination. */
const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
while (src < src_end && dst < dst_end)
{
const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
if (dst_next == dst)
break; /* Out-of-room. */
dst = dst_next;
src = src_next;
}
*text_size = dst - text;
*dst = 0; /* NUL-terminate. */
}
/* Accumulate length of rest. */
unsigned int dst_len = dst - text;
while (src < src_end)
{
src = in_utf_t::next (src, src_end, &unicode, replacement);
dst_len += out_utf_t::encode_len (unicode);
}
return dst_len;
}
#define entry_score var.u16[0]
#define entry_index var.u16[1]
/*
* name -- Naming
* https://docs.microsoft.com/en-us/typography/opentype/spec/name
*/
#define HB_OT_TAG_name HB_TAG('n','a','m','e')
#define UNSUPPORTED 42
struct NameRecord
{
hb_language_t language (hb_face_t *face) const
{
#ifndef HB_NO_OT_NAME_LANGUAGE
unsigned int p = platformID;
unsigned int l = languageID;
if (p == 3)
return _hb_ot_name_language_for_ms_code (l);
if (p == 1)
return _hb_ot_name_language_for_mac_code (l);
#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
if (p == 0)
return face->table.ltag->get_language (l);
#endif
#endif
return HB_LANGUAGE_INVALID;
}
uint16_t score () const
{
/* Same order as in cmap::find_best_subtable(). */
unsigned int p = platformID;
unsigned int e = encodingID;
/* 32-bit. */
if (p == 3 && e == 10) return 0;
if (p == 0 && e == 6) return 1;
if (p == 0 && e == 4) return 2;
/* 16-bit. */
if (p == 3 && e == 1) return 3;
if (p == 0 && e == 3) return 4;
if (p == 0 && e == 2) return 5;
if (p == 0 && e == 1) return 6;
if (p == 0 && e == 0) return 7;
/* Symbol. */
if (p == 3 && e == 0) return 8;
/* We treat all Mac Latin names as ASCII only. */
if (p == 1 && e == 0) return 10; /* 10 is magic number :| */
return UNSUPPORTED;
}
NameRecord* copy (hb_serialize_context_t *c, const void *base
#ifdef HB_EXPERIMENTAL_API
, const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
#endif
) const
{
TRACE_SERIALIZE (this);
HB_UNUSED auto snap = c->snapshot ();
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
#ifdef HB_EXPERIMENTAL_API
hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
hb_bytes_t* name_bytes;
if (name_table_overrides->has (record_ids, &name_bytes)) {
hb_bytes_t encoded_bytes = *name_bytes;
char *name_str_utf16_be = nullptr;
if (platformID != 1)
{
unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
if (!name_str_utf16_be)
{
c->revert (snap);
return_trace (nullptr);
}
hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
(hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
c->revert (snap);
hb_free (name_str_utf16_be);
return_trace (nullptr);
}
encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
}
else
{
// mac platform, copy the UTF-8 string(all ascii characters) as is
if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
c->revert (snap);
return_trace (nullptr);
}
}
out->offset = 0;
c->push ();
encoded_bytes.copy (c);
c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
hb_free (name_str_utf16_be);
}
else
#endif
{
out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
}
return_trace (out);
}
bool isUnicode () const
{
unsigned int p = platformID;
unsigned int e = encodingID;
return (p == 0 ||
(p == 3 && (e == 0 || e == 1 || e == 10)));
}
static int cmp (const void *pa, const void *pb)
{
const NameRecord *a = (const NameRecord *)pa;
const NameRecord *b = (const NameRecord *)pb;
if (a->platformID != b->platformID)
return a->platformID - b->platformID;
if (a->encodingID != b->encodingID)
return a->encodingID - b->encodingID;
if (a->languageID != b->languageID)
return a->languageID - b->languageID;
if (a->nameID != b->nameID)
return a->nameID - b->nameID;
if (a->length != b->length)
return a->length - b->length;
return 0;
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
}
HBUINT16 platformID; /* Platform ID. */
HBUINT16 encodingID; /* Platform-specific encoding ID. */
HBUINT16 languageID; /* Language ID. */
HBUINT16 nameID; /* Name ID. */
HBUINT16 length; /* String length (in bytes). */
NNOffset16To<UnsizedArrayOf<HBUINT8>>
offset; /* String offset from start of storage area (in bytes). */
public:
DEFINE_SIZE_STATIC (12);
};
static int
_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
{
const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
/* Compare by name_id, then language. */
if (a->name_id != b->name_id)
return a->name_id - b->name_id;
if (a->language == b->language) return 0;
if (!a->language) return -1;
if (!b->language) return +1;
const char *astr = hb_language_to_string (a->language);
const char *bstr = hb_language_to_string (b->language);
signed c = strcmp (astr, bstr);
// 'a' is the user request, and 'b' is string in the font.
// If eg. user asks for "en-us" and font has "en", approve.
if (!exact && c &&
hb_language_matches (b->language, a->language))
return 0;
return c;
}
static int
_hb_ot_name_entry_cmp (const void *pa, const void *pb)
{
/* Compare by name_id, then language, then score, then index. */
int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
if (v)
return v;
const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
if (a->entry_score != b->entry_score)
return a->entry_score - b->entry_score;
if (a->entry_index != b->entry_index)
return a->entry_index - b->entry_index;
return 0;
}
struct name
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_name;
unsigned int get_size () const
{ return min_size + count * nameRecordZ.item_size; }
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
bool serialize (hb_serialize_context_t *c,
Iterator it,
const void *src_string_pool
#ifdef HB_EXPERIMENTAL_API
, const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
, const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
#endif
)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min ((*this)))) return_trace (false);
unsigned total_count = it.len ()
#ifdef HB_EXPERIMENTAL_API
+ insert_name_records.length
#endif
;
this->format = 0;
if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return false;
NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
if (unlikely (!name_records)) return_trace (false);
hb_array_t<NameRecord> records (name_records, total_count);
for (const NameRecord& record : it)
{
hb_memcpy (name_records, &record, NameRecord::static_size);
name_records++;
}
#ifdef HB_EXPERIMENTAL_API
for (unsigned i = 0; i < insert_name_records.length; i++)
{
const hb_ot_name_record_ids_t& ids = insert_name_records[i];
NameRecord record;
record.platformID = ids.platform_id;
record.encodingID = ids.encoding_id;
record.languageID = ids.language_id;
record.nameID = ids.name_id;
record.length = 0; // handled in NameRecord copy()
record.offset = 0;
memcpy (name_records, &record, NameRecord::static_size);
name_records++;
}
#endif
records.qsort ();
c->copy_all (records,
src_string_pool
#ifdef HB_EXPERIMENTAL_API
, name_table_overrides
#endif
);
hb_free (records.arrayZ);
if (unlikely (c->ran_out_of_room ())) return_trace (false);
this->stringOffset = c->length ();
return_trace (true);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
name *name_prime = c->serializer->start_embed<name> ();
if (unlikely (!name_prime)) return_trace (false);
#ifdef HB_EXPERIMENTAL_API
const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
&c->plan->name_table_overrides;
#endif
auto it =
+ nameRecordZ.as_array (count)
| hb_filter (c->plan->name_ids, &NameRecord::nameID)
| hb_filter (c->plan->name_languages, &NameRecord::languageID)
| hb_filter ([&] (const NameRecord& namerecord) {
return
(c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
|| namerecord.isUnicode ();
})
#ifdef HB_EXPERIMENTAL_API
| hb_filter ([&] (const NameRecord& namerecord) {
if (name_table_overrides->is_empty ())
return true;
hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
namerecord.encodingID,
namerecord.languageID,
namerecord.nameID);
hb_bytes_t *p;
if (name_table_overrides->has (rec_ids, &p) &&
(*p).length == 0)
return false;
return true;
})
#endif
;
#ifdef HB_EXPERIMENTAL_API
hb_hashmap_t<hb_ot_name_record_ids_t, unsigned> retained_name_record_ids;
for (const NameRecord& rec : it)
{
hb_ot_name_record_ids_t rec_ids (rec.platformID,
rec.encodingID,
rec.languageID,
rec.nameID);
retained_name_record_ids.set (rec_ids, 1);
}
hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
if (!name_table_overrides->is_empty ())
{
if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true)))
return_trace (false);
for (const auto& record_ids : name_table_overrides->keys ())
{
if (name_table_overrides->get (record_ids).length == 0)
continue;
if (retained_name_record_ids.has (record_ids))
continue;
insert_name_records.push (record_ids);
}
}
#endif
return (name_prime->serialize (c->serializer, it,
std::addressof (this + stringOffset)
#ifdef HB_EXPERIMENTAL_API
, insert_name_records
, name_table_overrides
#endif
));
}
bool sanitize_records (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
const void *string_pool = (this+stringOffset).arrayZ;
return_trace (nameRecordZ.sanitize (c, count, string_pool));
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
likely (format == 0 || format == 1) &&
c->check_array (nameRecordZ.arrayZ, count) &&
c->check_range (this, stringOffset) &&
sanitize_records (c));
}
struct accelerator_t
{
accelerator_t (hb_face_t *face)
{
this->table = hb_sanitize_context_t ().reference_table<name> (face);
assert (this->table.get_length () >= this->table->stringOffset);
this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
this->pool_len = this->table.get_length () - this->table->stringOffset;
const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
this->table->count);
this->names.alloc (all_names.length, true);
for (unsigned int i = 0; i < all_names.length; i++)
{
hb_ot_name_entry_t *entry = this->names.push ();
entry->name_id = all_names[i].nameID;
entry->language = all_names[i].language (face);
entry->entry_score = all_names[i].score ();
entry->entry_index = i;
}
this->names.qsort (_hb_ot_name_entry_cmp);
/* Walk and pick best only for each name_id,language pair,
* while dropping unsupported encodings. */
unsigned int j = 0;
for (unsigned int i = 0; i < this->names.length; i++)
{
if (this->names[i].entry_score == UNSUPPORTED ||
this->names[i].language == HB_LANGUAGE_INVALID)
continue;
if (i &&
this->names[i - 1].name_id == this->names[i].name_id &&
this->names[i - 1].language == this->names[i].language)
continue;
this->names[j++] = this->names[i];
}
this->names.resize (j);
}
~accelerator_t ()
{
this->table.destroy ();
}
int get_index (hb_ot_name_id_t name_id,
hb_language_t language,
unsigned int *width=nullptr) const
{
const hb_ot_name_entry_t key = {name_id, {0}, language};
const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
this->names.length,
sizeof (hb_ot_name_entry_t),
_hb_ot_name_entry_cmp_key,
true);
if (!entry)
{
entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
this->names.length,
sizeof (hb_ot_name_entry_t),
_hb_ot_name_entry_cmp_key,
false);
}
if (!entry)
return -1;
if (width)
*width = entry->entry_score < 10 ? 2 : 1;
return entry->entry_index;
}
hb_bytes_t get_name (unsigned int idx) const
{
const hb_array_t<const NameRecord> all_names (table->nameRecordZ.arrayZ, table->count);
const NameRecord &record = all_names[idx];
const hb_bytes_t string_pool (pool, pool_len);
return string_pool.sub_array (record.offset, record.length);
}
private:
const char *pool;
unsigned int pool_len;
public:
hb_blob_ptr_t<name> table;
hb_vector_t<hb_ot_name_entry_t> names;
};
public:
/* We only implement format 0 for now. */
HBUINT16 format; /* Format selector (=0/1). */
HBUINT16 count; /* Number of name records. */
NNOffset16To<UnsizedArrayOf<HBUINT8>>
stringOffset; /* Offset to start of string storage (from start of table). */
UnsizedArrayOf<NameRecord>
nameRecordZ; /* The name records where count is the number of records. */
public:
DEFINE_SIZE_ARRAY (6, nameRecordZ);
};
#undef entry_index
#undef entry_score
struct name_accelerator_t : name::accelerator_t {
name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
};
} /* namespace OT */
#endif /* OT_NAME_NAME_HH */

View File

@ -19,8 +19,7 @@ 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_shape_justify
hb_subset_repack_or_fail
"""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,9 +700,6 @@ struct graph_t
}
}
if (in_error ())
return false;
if (!made_changes)
return false;
@ -836,11 +833,7 @@ struct graph_t
if (index_map.has (node_idx))
return;
unsigned clone_idx = duplicate (node_idx);
if (!check_success (clone_idx != (unsigned) -1))
return;
index_map.set (node_idx, clone_idx);
index_map.set (node_idx, duplicate (node_idx));
for (const auto& l : object (node_idx).all_links ()) {
duplicate_subgraph (l.objidx, index_map);
}

View File

@ -12,17 +12,13 @@ list(GET _harfbuzz_version_info 2
_harfbuzz_age)
unset(_harfbuzz_version_info)
if ("@default_library@" MATCHES "static")
set(_harfbuzz_lib_suffix ".a")
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 ()
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 ()
# Unsupported.
set(harfbuzz_FOUND 0)
endif ()
# Add the libraries.

View File

@ -41,7 +41,6 @@
#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"
@ -54,7 +53,6 @@
#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,7 +46,6 @@
#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,8 +464,7 @@ enum { DELETED_GLYPH = 0xFFFF };
template <typename T>
struct Entry
{
// This does seem like it's ever called.
bool sanitize (hb_sanitize_context_t *c) const
bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
/* Note, we don't recurse-sanitize data because we don't access it.
@ -493,8 +492,7 @@ struct Entry
template <>
struct Entry<void>
{
// This does seem like it's ever called.
bool sanitize (hb_sanitize_context_t *c) const
bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));

View File

@ -110,10 +110,9 @@ 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 == __BIG_ENDIAN || \
(__BYTE_ORDER == __LITTLE_ENDIAN && \
hb_has_builtin(__builtin_bswap16)))
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
/* Spoon-feed the compiler a big-endian integer with alignment 1.
* https://github.com/harfbuzz/harfbuzz/pull/1398 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
@ -156,10 +155,9 @@ 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 == __BIG_ENDIAN || \
(__BYTE_ORDER == __LITTLE_ENDIAN && \
hb_has_builtin(__builtin_bswap32)))
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
/* Spoon-feed the compiler a big-endian integer with alignment 1.
* https://github.com/harfbuzz/harfbuzz/pull/1398 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
@ -600,17 +598,13 @@ template <typename T>
static inline unsigned int
hb_popcount (T v)
{
#if hb_has_builtin(__builtin_popcount)
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
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
@ -647,17 +641,13 @@ hb_bit_storage (T v)
{
if (unlikely (!v)) return 0;
#if hb_has_builtin(__builtin_clz)
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
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
@ -725,17 +715,13 @@ hb_ctz (T v)
{
if (unlikely (!v)) return 8 * sizeof (T);
#if hb_has_builtin(__builtin_ctz)
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
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
@ -889,7 +875,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 hb_has_builtin(__builtin_mul_overflow)
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
unsigned stack_result;
if (!result)
result = &stack_result;
@ -1344,62 +1330,4 @@ 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,9 +304,6 @@ 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,10 +38,6 @@
/*
* 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.
*/
@ -88,11 +84,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<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_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_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))
@ -115,15 +111,10 @@ _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
#if defined(__ATOMIC_ACQUIRE) // gcc-like
#define _hb_compiler_memory_r_barrier() asm volatile("": : :"memory")
#elif !defined(_MSC_VER)
/* 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)
#include <atomic>
#define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire)
#else
@ -154,35 +145,15 @@ _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,16 +42,7 @@ struct hb_vector_size_t
elt_t& operator [] (unsigned int i) { return v[i]; }
const elt_t& operator [] (unsigned int i) const { return v[i]; }
void init0 ()
{
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
v[i] = 0;
}
void init1 ()
{
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
v[i] = (elt_t) -1;
}
void clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); }
template <typename Op>
hb_vector_size_t process (const Op& op) const
@ -89,10 +80,10 @@ struct hb_vector_size_t
struct hb_bit_page_t
{
void init0 () { v.init0 (); }
void init1 () { v.init1 (); }
void init0 () { v.clear (); }
void init1 () { v.clear (0xFF); }
static inline constexpr unsigned len ()
constexpr unsigned len () const
{ 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 (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
if (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 (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
if (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) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
{
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) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
{
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) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
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_MODE_READONLY_MAY_MAKE_WRITABLE, however, using that mode
* @HB_MEMORY_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, 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,
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,
9u, 123u, 0u, 0u, 0
};
static const char _deserialize_json_key_spans[] = {
0, 115, 26, 21, 2, 1, 50, 49,
10, 117, 117, 85, 117, 1, 50, 49,
10, 117, 117, 1, 1, 50, 49, 117,
117, 2, 1, 50, 49, 10, 117, 117,
1, 50, 49, 10, 117, 117, 1, 1,
50, 49, 117, 117, 1, 50, 49, 59,
117, 59, 117, 117, 1, 50, 49, 117,
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,
115, 0
};
static const short _deserialize_json_index_offsets[] = {
0, 0, 116, 143, 165, 168, 170, 221,
271, 282, 400, 518, 604, 722, 724, 775,
825, 836, 954, 1072, 1074, 1076, 1127, 1177,
1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648,
1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118,
2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560,
2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137,
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,
3255, 3371
};
@ -131,52 +131,41 @@ 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, 25,
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,
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, 27, 1, 20, 20, 20,
20, 20, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 32, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 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, 33, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@ -186,39 +175,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, 37, 1, 35, 35, 35, 35, 35,
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, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 35, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 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, 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, 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, 40, 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,
@ -228,14 +217,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,
1, 1, 1, 1, 1, 1, 1, 43,
42, 1, 40, 40, 40, 40, 40, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 44, 1, 1, 1, 46,
46, 46, 46, 46, 46, 46, 46, 46,
46, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 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, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@ -243,163 +232,186 @@ 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, 45, 1, 47, 48,
1, 49, 1, 49, 49, 49, 49, 49,
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, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 49, 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, 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, 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, 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, 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,
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, 65, 1, 66,
1, 67, 1, 67, 67, 67, 67, 67,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
66, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 67, 1, 1, 1,
1, 1, 67, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 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, 1, 72, 73, 73, 73, 73,
73, 73, 73, 73, 73, 1, 74, 74,
74, 74, 74, 1, 1, 1, 1, 1,
1, 1, 73, 1, 75, 1, 75, 75,
75, 75, 75, 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, 75, 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, 79, 1, 79,
79, 79, 79, 79, 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, 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,
1, 1, 1, 1, 86, 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,
87, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@ -408,64 +420,42 @@ 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, 88, 1, 83, 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, 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, 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,
1, 1, 1, 86, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 87,
1, 1, 1, 94, 94, 94, 94, 94,
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,
@ -473,7 +463,17 @@ 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, 91, 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,
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, 19, 25,
38, 44, 52, 5, 13, 6, 7, 8,
9, 12, 9, 12, 10, 2, 11, 10,
11, 11, 56, 57, 14, 15, 16, 17,
18, 17, 18, 10, 2, 11, 20, 21,
22, 23, 24, 10, 2, 11, 24, 26,
32, 27, 28, 29, 30, 31, 30, 31,
10, 2, 11, 33, 34, 35, 36, 37,
36, 37, 10, 2, 11, 39, 40, 41,
42, 43, 10, 2, 11, 43, 45, 46,
47, 50, 51, 47, 48, 49, 10, 2,
11, 10, 2, 11, 51, 53, 54, 50,
55, 55
1, 0, 2, 2, 3, 4, 18, 24,
37, 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
};
static const char _deserialize_json_trans_actions[] = {
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2,
2, 2, 0, 0, 3, 3, 4, 0,
5, 0, 0, 0, 0, 0, 2, 2,
2, 0, 0, 6, 6, 7, 0, 0,
0, 2, 2, 8, 8, 9, 0, 0,
0, 0, 0, 2, 2, 2, 0, 0,
10, 10, 11, 0, 0, 2, 2, 2,
0, 0, 12, 12, 13, 0, 0, 0,
2, 2, 14, 14, 15, 0, 0, 0,
2, 16, 16, 0, 17, 0, 18, 18,
19, 20, 20, 21, 17, 0, 0, 22,
22, 23
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
};
static const int deserialize_json_start = 1;
static const int deserialize_json_first_final = 56;
static const int deserialize_json_first_final = 55;
static const int deserialize_json_error = 0;
static const int deserialize_json_en_main = 1;
@ -548,19 +548,21 @@ _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 552 "hb-buffer-deserialize-json.hh"
#line 554 "hb-buffer-deserialize-json.hh"
{
cs = deserialize_json_start;
}
#line 555 "hb-buffer-deserialize-json.hh"
#line 557 "hb-buffer-deserialize-json.hh"
{
int _slen;
int _trans;
@ -772,7 +774,7 @@ _resume:
*end_ptr = p;
}
break;
#line 733 "hb-buffer-deserialize-json.hh"
#line 735 "hb-buffer-deserialize-json.hh"
}
_again:
@ -784,7 +786,7 @@ _again:
_out: {}
}
#line 137 "hb-buffer-deserialize-json.rl"
#line 139 "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,7 +125,9 @@ _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

@ -1,692 +0,0 @@
#line 1 "hb-buffer-deserialize-text-glyphs.rl"
/*
* Copyright © 2013 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#include "hb.hh"
#line 33 "hb-buffer-deserialize-text-glyphs.hh"
static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u,
9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
9u, 124u, 9u, 124u, 9u, 124u, 0
};
static const char _deserialize_text_glyphs_key_spans[] = {
0, 10, 13, 10, 13, 10, 10, 13,
10, 1, 13, 10, 14, 82, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116
};
static const short _deserialize_text_glyphs_index_offsets[] = {
0, 0, 11, 25, 36, 50, 61, 72,
86, 97, 99, 113, 124, 139, 222, 339,
456, 573, 690, 807, 924, 1041, 1158, 1275,
1392, 1509, 1626
};
static const char _deserialize_text_glyphs_indicies[] = {
0, 2, 2, 2, 2, 2, 2,
2, 2, 2, 1, 3, 1, 1, 4,
5, 5, 5, 5, 5, 5, 5, 5,
5, 1, 6, 7, 7, 7, 7, 7,
7, 7, 7, 7, 1, 8, 1, 1,
9, 10, 10, 10, 10, 10, 10, 10,
10, 10, 1, 11, 12, 12, 12, 12,
12, 12, 12, 12, 12, 1, 13, 14,
14, 14, 14, 14, 14, 14, 14, 14,
1, 15, 1, 1, 16, 17, 17, 17,
17, 17, 17, 17, 17, 17, 1, 18,
19, 19, 19, 19, 19, 19, 19, 19,
19, 1, 20, 1, 21, 1, 1, 22,
23, 23, 23, 23, 23, 23, 23, 23,
23, 1, 24, 25, 25, 25, 25, 25,
25, 25, 25, 25, 1, 20, 1, 1,
1, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 1, 26, 26, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 26, 1,
1, 26, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 26, 26, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 26, 1, 28,
28, 28, 28, 28, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 28, 27,
27, 29, 27, 27, 27, 27, 27, 27,
27, 30, 1, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 31, 27, 27, 32, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 33, 1, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 28, 27, 34, 34, 34, 34,
34, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 34, 26, 26, 35, 26,
26, 26, 26, 26, 26, 26, 36, 1,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
37, 26, 26, 38, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 39,
1, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 40,
26, 41, 41, 41, 41, 41, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
41, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 42, 1, 43, 43,
43, 43, 43, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 43, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 44, 1, 41, 41, 41, 41, 41,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 41, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 42, 1,
46, 46, 46, 46, 46, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 46,
1, 1, 47, 1, 1, 1, 1, 1,
1, 1, 1, 48, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 49, 1, 50, 50, 50,
50, 50, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 50, 1, 1, 51,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
52, 1, 50, 50, 50, 50, 50, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 50, 1, 1, 51, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 52, 1, 46,
46, 46, 46, 46, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 46, 1,
1, 47, 1, 1, 1, 1, 1, 1,
1, 1, 48, 1, 1, 1, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 49, 1, 53, 53, 53, 53,
53, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 53, 1, 1, 54, 1,
1, 1, 1, 1, 1, 1, 55, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 56, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 57,
1, 58, 58, 58, 58, 58, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
58, 1, 1, 59, 1, 1, 1, 1,
1, 1, 1, 60, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 61, 1, 58, 58,
58, 58, 58, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 58, 1, 1,
59, 1, 1, 1, 1, 1, 1, 1,
60, 1, 1, 1, 1, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 61, 1, 53, 53, 53, 53, 53,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 53, 1, 1, 54, 1, 1,
1, 1, 1, 1, 1, 55, 1, 1,
1, 1, 62, 62, 62, 62, 62, 62,
62, 62, 62, 62, 1, 1, 1, 1,
1, 1, 56, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 57, 1,
0
};
static const char _deserialize_text_glyphs_trans_targs[] = {
16, 0, 18, 3, 19, 22, 19, 22,
5, 20, 21, 20, 21, 23, 26, 8,
9, 12, 9, 12, 10, 11, 24, 25,
24, 25, 15, 15, 14, 1, 2, 6,
7, 13, 15, 1, 2, 6, 7, 13,
14, 17, 14, 17, 14, 18, 17, 1,
4, 14, 17, 1, 14, 17, 1, 2,
7, 14, 17, 1, 2, 14, 26
};
static const char _deserialize_text_glyphs_trans_actions[] = {
1, 0, 1, 1, 1, 1, 0, 0,
1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 0, 0, 2, 1, 1, 1,
0, 0, 0, 4, 3, 5, 5, 5,
5, 4, 6, 7, 7, 7, 7, 0,
6, 8, 8, 0, 0, 0, 9, 10,
10, 9, 11, 12, 11, 13, 14, 14,
14, 13, 15, 16, 16, 15, 0
};
static const char _deserialize_text_glyphs_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 3, 6,
8, 0, 8, 9, 11, 11, 9, 13,
15, 15, 13
};
static const int deserialize_text_glyphs_start = 14;
static const int deserialize_text_glyphs_first_final = 14;
static const int deserialize_text_glyphs_error = 0;
static const int deserialize_text_glyphs_en_main = 14;
#line 98 "hb-buffer-deserialize-text-glyphs.rl"
static hb_bool_t
_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
const char *buf,
unsigned int buf_len,
const char **end_ptr,
hb_font_t *font)
{
const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
/* Ensure we have positions. */
(void) hb_buffer_get_glyph_positions (buffer, nullptr);
while (p < pe && ISSPACE (*p))
p++;
if (p < pe && *p == (buffer->len ? '|' : '['))
*end_ptr = ++p;
const char *end = strchr ((char *) p, ']');
if (end)
pe = eof = end;
else
{
end = strrchr ((char *) p, '|');
if (end)
pe = eof = end;
else
pe = eof = p;
}
const char *tok = nullptr;
int cs;
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
#line 346 "hb-buffer-deserialize-text-glyphs.hh"
{
cs = deserialize_text_glyphs_start;
}
#line 349 "hb-buffer-deserialize-text-glyphs.hh"
{
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _deserialize_text_glyphs_trans_keys + (cs<<1);
_inds = _deserialize_text_glyphs_indicies + _deserialize_text_glyphs_index_offsets[cs];
_slen = _deserialize_text_glyphs_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
(*p) <= _keys[1] ?
(*p) - _keys[0] : _slen ];
cs = _deserialize_text_glyphs_trans_targs[_trans];
if ( _deserialize_text_glyphs_trans_actions[_trans] == 0 )
goto _again;
switch ( _deserialize_text_glyphs_trans_actions[_trans] ) {
case 1:
#line 51 "hb-buffer-deserialize-text-glyphs.rl"
{
tok = p;
}
break;
case 7:
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
break;
case 14:
#line 63 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
break;
case 2:
#line 64 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
break;
case 16:
#line 65 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
break;
case 10:
#line 66 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
break;
case 12:
#line 67 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
break;
case 4:
#line 38 "hb-buffer-deserialize-text-glyphs.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text-glyphs.rl"
{
tok = p;
}
break;
case 6:
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 13:
#line 63 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 15:
#line 65 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 9:
#line 66 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 11:
#line 67 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 8:
#line 68 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 5:
#line 38 "hb-buffer-deserialize-text-glyphs.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text-glyphs.rl"
{
tok = p;
}
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
break;
case 3:
#line 38 "hb-buffer-deserialize-text-glyphs.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text-glyphs.rl"
{
tok = p;
}
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 516 "hb-buffer-deserialize-text-glyphs.hh"
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
switch ( _deserialize_text_glyphs_eof_actions[cs] ) {
case 6:
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 13:
#line 63 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 15:
#line 65 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 9:
#line 66 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 11:
#line 67 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 8:
#line 68 "hb-buffer-deserialize-text-glyphs.rl"
{ if (!parse_uint (tok, p, &info.mask )) return false; }
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 3:
#line 38 "hb-buffer-deserialize-text-glyphs.rl"
{
hb_memset (&info, 0, sizeof (info));
hb_memset (&pos , 0, sizeof (pos ));
}
#line 51 "hb-buffer-deserialize-text-glyphs.rl"
{
tok = p;
}
#line 55 "hb-buffer-deserialize-text-glyphs.rl"
{
/* TODO Unescape delimiters. */
if (!hb_font_glyph_from_string (font,
tok, p - tok,
&info.codepoint))
return false;
}
#line 43 "hb-buffer-deserialize-text-glyphs.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 616 "hb-buffer-deserialize-text-glyphs.hh"
}
}
_out: {}
}
#line 136 "hb-buffer-deserialize-text-glyphs.rl"
if (pe < orig_pe && *pe == ']')
{
pe++;
if (p == pe)
p++;
}
*end_ptr = p;
return p == pe;
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */

View File

@ -1,332 +0,0 @@
#line 1 "hb-buffer-deserialize-text-unicode.rl"
/*
* Copyright © 2013 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
#define HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
#include "hb.hh"
#line 33 "hb-buffer-deserialize-text-unicode.hh"
static const unsigned char _deserialize_text_unicode_trans_keys[] = {
0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u,
9u, 124u, 0
};
static const char _deserialize_text_unicode_key_spans[] = {
0, 109, 60, 55, 10, 116, 116, 116,
116
};
static const short _deserialize_text_unicode_index_offsets[] = {
0, 0, 110, 171, 227, 238, 355, 472,
589
};
static const char _deserialize_text_unicode_indicies[] = {
0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 3,
1, 1, 1, 1, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 1, 1,
1, 1, 1, 1, 1, 4, 4, 4,
4, 4, 4, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 4, 4, 4,
4, 4, 4, 1, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 1, 1,
1, 1, 1, 1, 1, 4, 4, 4,
4, 4, 4, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 4, 4, 4,
4, 4, 4, 1, 5, 6, 6, 6,
6, 6, 6, 6, 6, 6, 1, 7,
7, 7, 7, 7, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 7, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
1, 1, 1, 9, 1, 1, 1, 8,
8, 8, 8, 8, 8, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 8,
8, 8, 8, 8, 8, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 10, 1, 11, 11, 11, 11,
11, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 11, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0,
1, 12, 12, 12, 12, 12, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
12, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 13, 1, 12, 12,
12, 12, 12, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 12, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 13, 1, 0
};
static const char _deserialize_text_unicode_trans_targs[] = {
1, 0, 2, 3, 5, 7, 8, 6,
5, 4, 1, 6, 6, 1, 8
};
static const char _deserialize_text_unicode_trans_actions[] = {
0, 0, 1, 0, 2, 2, 2, 3,
0, 4, 3, 0, 5, 5, 0
};
static const char _deserialize_text_unicode_eof_actions[] = {
0, 0, 0, 0, 0, 3, 0, 5,
5
};
static const int deserialize_text_unicode_start = 1;
static const int deserialize_text_unicode_first_final = 5;
static const int deserialize_text_unicode_error = 0;
static const int deserialize_text_unicode_en_main = 1;
#line 79 "hb-buffer-deserialize-text-unicode.rl"
static hb_bool_t
_hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer,
const char *buf,
unsigned int buf_len,
const char **end_ptr,
hb_font_t *font)
{
const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
while (p < pe && ISSPACE (*p))
p++;
if (p < pe && *p == (buffer->len ? '|' : '<'))
*end_ptr = ++p;
const char *end = strchr ((char *) p, '>');
if (end)
pe = eof = end;
else
{
end = strrchr ((char *) p, '|');
if (end)
pe = eof = end;
else
pe = eof = p;
}
const char *tok = nullptr;
int cs;
hb_glyph_info_t info = {0};
const hb_glyph_position_t pos = {0};
#line 194 "hb-buffer-deserialize-text-unicode.hh"
{
cs = deserialize_text_unicode_start;
}
#line 197 "hb-buffer-deserialize-text-unicode.hh"
{
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _deserialize_text_unicode_trans_keys + (cs<<1);
_inds = _deserialize_text_unicode_indicies + _deserialize_text_unicode_index_offsets[cs];
_slen = _deserialize_text_unicode_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
(*p) <= _keys[1] ?
(*p) - _keys[0] : _slen ];
cs = _deserialize_text_unicode_trans_targs[_trans];
if ( _deserialize_text_unicode_trans_actions[_trans] == 0 )
goto _again;
switch ( _deserialize_text_unicode_trans_actions[_trans] ) {
case 1:
#line 38 "hb-buffer-deserialize-text-unicode.rl"
{
hb_memset (&info, 0, sizeof (info));
}
break;
case 2:
#line 51 "hb-buffer-deserialize-text-unicode.rl"
{
tok = p;
}
break;
case 4:
#line 55 "hb-buffer-deserialize-text-unicode.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
break;
case 3:
#line 55 "hb-buffer-deserialize-text-unicode.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
#line 42 "hb-buffer-deserialize-text-unicode.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
if (buffer->have_positions)
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 5:
#line 57 "hb-buffer-deserialize-text-unicode.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
#line 42 "hb-buffer-deserialize-text-unicode.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
if (buffer->have_positions)
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 256 "hb-buffer-deserialize-text-unicode.hh"
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
switch ( _deserialize_text_unicode_eof_actions[cs] ) {
case 3:
#line 55 "hb-buffer-deserialize-text-unicode.rl"
{if (!parse_hex (tok, p, &info.codepoint )) return false; }
#line 42 "hb-buffer-deserialize-text-unicode.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
if (buffer->have_positions)
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
case 5:
#line 57 "hb-buffer-deserialize-text-unicode.rl"
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
#line 42 "hb-buffer-deserialize-text-unicode.rl"
{
buffer->add_info (info);
if (unlikely (!buffer->successful))
return false;
if (buffer->have_positions)
buffer->pos[buffer->len - 1] = pos;
*end_ptr = p;
}
break;
#line 289 "hb-buffer-deserialize-text-unicode.hh"
}
}
_out: {}
}
#line 115 "hb-buffer-deserialize-text-unicode.rl"
if (pe < orig_pe && *pe == '>')
{
pe++;
if (p == pe)
p++;
}
*end_ptr = p;
return p == pe;
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */

View File

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

@ -0,0 +1,917 @@
#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

@ -24,14 +24,14 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
#define HB_BUFFER_DESERIALIZE_TEXT_HH
#include "hb.hh"
%%{
machine deserialize_text_glyphs;
machine deserialize_text;
alphtype unsigned char;
write data;
@ -52,6 +52,9 @@ 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,
@ -60,6 +63,8 @@ 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; }
@ -88,45 +93,45 @@ glyph_item =
glyphflags?
)
>clear_item
@ensure_glyphs
%add_item
;
glyphs = glyph_item (space* '|' space* glyph_item)* space*;
unicode = 'U' '+' xdigit+ >tok %parse_hexdigits;
main := space* glyphs;
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) );
}%%
static hb_bool_t
_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
_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, *eof = pe, *orig_pe = pe;
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++;
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;
const char *eof = pe, *tok = nullptr;
int cs;
hb_glyph_info_t info = {0};
hb_glyph_position_t pos = {0};
@ -135,16 +140,9 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
write exec;
}%%
if (pe < orig_pe && *pe == ']')
{
pe++;
if (p == pe)
p++;
}
*end_ptr = p;
return p == pe;
return p == pe && *(p-1) != ']';
}
#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */

View File

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

View File

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

View File

@ -581,59 +581,21 @@ struct hb_buffer_t
unsigned int cluster,
hb_mask_t mask)
{
if (unlikely (start == end))
return;
unsigned cluster_first = infos[start].cluster;
unsigned cluster_last = infos[end - 1].cluster;
if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS ||
(cluster != cluster_first && cluster != cluster_last))
{
for (unsigned int i = start; i < end; i++)
if (cluster != infos[i].cluster)
{
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
infos[i].mask |= mask;
}
return;
}
/* Monotone clusters */
if (cluster == cluster_first)
{
for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--)
{
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
infos[i - 1].mask |= mask;
}
}
else /* cluster == cluster_last */
{
for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++)
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;
}
}
}
unsigned
static unsigned
_infos_find_min_cluster (const hb_glyph_info_t *infos,
unsigned start, unsigned end,
unsigned cluster = UINT_MAX)
{
if (unlikely (start == end))
return cluster;
if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
{
for (unsigned int i = start; i < end; i++)
cluster = hb_min (cluster, infos[i].cluster);
return cluster;
}
return hb_min (cluster, hb_min (infos[start].cluster, infos[end - 1].cluster));
for (unsigned int i = start; i < end; i++)
cluster = hb_min (cluster, infos[i].cluster);
return cluster;
}
void clear_glyph_flags (hb_mask_t mask = 0)

View File

@ -30,19 +30,7 @@
#include "hb.hh"
/* Implements a lockfree cache for int->int functions.
*
* The cache is a fixed-size array of 16-bit or 32-bit integers.
* The key is split into two parts: the cache index and the rest.
*
* The cache index is used to index into the array. The rest is used
* to store the key and the value.
*
* The value is stored in the least significant bits of the integer.
* The key is stored in the most significant bits of the integer.
* The key is shifted by cache_bits to the left to make room for the
* value.
*/
/* Implements a lockfree cache for int->int functions. */
template <unsigned int key_bits=16,
unsigned int value_bits=8 + 32 - key_bits,
@ -51,9 +39,7 @@ template <unsigned int key_bits=16,
struct hb_cache_t
{
using item_t = typename std::conditional<thread_safe,
typename std::conditional<key_bits + value_bits - cache_bits <= 16,
hb_atomic_short_t,
hb_atomic_int_t>::type,
hb_atomic_int_t,
typename std::conditional<key_bits + value_bits - cache_bits <= 16,
short,
int>::type
@ -62,9 +48,8 @@ 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,6 +1,5 @@
/*
* Copyright © 2022 Red Hat, Inc
* Copyright © 2021, 2022 Black Foundry
*
* This is part of HarfBuzz, a text shaping library.
*
@ -33,14 +32,10 @@
#include <cairo.h>
/* Some routines in this file were ported from BlackRenderer by Black Foundry.
* Used by permission to relicense to HarfBuzz license.
*
* https://github.com/BlackFoundryCom/black-renderer
*/
#define PREALLOCATED_COLOR_STOPS 16
#define _2_M_PIf (2.f * float (M_PI))
typedef struct {
float r, g, b, a;
} hb_cairo_color_t;
@ -96,16 +91,14 @@ _hb_cairo_destroy_blob (void *p)
}
hb_bool_t
_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
hb_blob_t *blob,
unsigned width,
unsigned height,
hb_tag_t format,
float slant,
hb_glyph_extents_t *extents)
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)
{
cairo_t *cr = c->cr;
if (!extents) /* SVG currently. */
return false;
@ -219,7 +212,7 @@ _hb_cairo_reduce_anchors (float x0, float y0,
q2x = x2 - x0;
q2y = y2 - y0;
q1x = x1 - x0;
q1x = y1 - x0;
q1y = y1 - y0;
s = q2x * q2x + q2y * q2y;
@ -279,60 +272,28 @@ _hb_cairo_normalize_color_line (hb_color_stop_t *stops,
*omax = max;
}
static bool
_hb_cairo_get_color_stops (hb_cairo_context_t *c,
hb_color_line_t *color_line,
unsigned *count,
hb_color_stop_t **stops)
{
unsigned len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
if (len > *count)
{
*stops = (hb_color_stop_t *) hb_malloc (len * sizeof (hb_color_stop_t));
if (unlikely (!stops))
return false;
}
hb_color_line_get_color_stops (color_line, 0, &len, *stops);
for (unsigned i = 0; i < len; i++)
if ((*stops)[i].is_foreground)
{
#ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
double r, g, b, a;
cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
(*stops)[i].color = HB_COLOR (round (b * 255.), round (g * 255.), round (r * 255.),
round (a * hb_color_get_alpha ((*stops)[i].color)));
else
#endif
(*stops)[i].color = HB_COLOR (0, 0, 0, hb_color_get_alpha ((*stops)[i].color));
}
*count = len;
return true;
}
void
_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float x0, float y0,
float x1, float y1,
float x2, float y2)
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)
{
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;
if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
return;
_hb_cairo_normalize_color_line (stops, len, &min, &max);
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);
_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);
@ -357,27 +318,28 @@ _hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
cairo_pattern_destroy (pattern);
if (stops != stops_)
hb_free (stops);
free (stops);
}
void
_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float x0, float y0, float r0,
float x1, float y1, float r1)
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)
{
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;
if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
return;
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);
_hb_cairo_normalize_color_line (stops, len, &min, &max);
xx0 = x0 + min * (x1 - x0);
@ -406,7 +368,7 @@ _hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
cairo_pattern_destroy (pattern);
if (stops != stops_)
hb_free (stops);
free (stops);
}
typedef struct {
@ -523,7 +485,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 (HB_PI / 8.f)
#define MAX_ANGLE ((float) M_PI / 8.f)
static void
_hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
@ -564,8 +526,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.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));
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));
_hb_cairo_add_patch (pattern, &center, &patch);
@ -591,254 +553,249 @@ _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)
{
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);
}
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;
}
return;
}
assert (start_angle != end_angle);
/* handle directions */
if (end_angle < start_angle)
{
hb_swap (start_angle, end_angle);
{
float angle = end_angle;
end_angle = start_angle;
start_angle = angle;
for (unsigned i = 0; i < n_stops - 1 - i; i++)
hb_swap (stops[i], stops[n_stops - 1 - i]);
for (unsigned i = 0; i < n_stops; i++)
stops[i].offset = 1 - stops[i].offset;
}
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;
}
}
if (n_stops > PREALLOCATED_COLOR_STOPS)
{
angles = (float *) hb_malloc (sizeof (float) * n_stops);
colors = (hb_cairo_color_t *) hb_malloc (sizeof (hb_cairo_color_t) * n_stops);
if (unlikely (!angles || !colors))
{
hb_free (angles);
hb_free (colors);
return;
}
angles = (float *) malloc (sizeof (float) * n_stops);
colors = (hb_cairo_color_t *) malloc (sizeof (hb_cairo_color_t) * n_stops);
}
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;
{
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;
}
color0 = colors[0];
for (pos = 0; pos < n_stops; pos++)
{
if (angles[pos] >= 0)
{
if (pos > 0)
{
float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
_hb_cairo_interpolate_colors (&colors[pos-1], &colors[pos], k, &color0);
}
break;
}
}
if (pos == n_stops)
{
/* everything is below 0 */
color0 = colors[n_stops-1];
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
0., &color0,
HB_2_PI, &color0,
0., &color0,
angles[pos], &colors[pos],
pattern);
goto done;
}
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
0., &color0,
angles[pos], &colors[pos],
pattern);
for (pos++; pos < n_stops; pos++)
{
if (angles[pos] <= _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;
}
}
for (pos++; pos < n_stops; pos++)
{
if (angles[pos] <= HB_2_PI)
{
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
angles[pos - 1], &colors[pos-1],
angles[pos], &colors[pos],
pattern);
}
else
{
float k = (HB_2_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
_hb_cairo_interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1);
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
angles[pos - 1], &colors[pos - 1],
HB_2_PI, &color1,
pattern);
break;
}
if (pos == n_stops)
{
/* everything is below 2*M_PI */
color0 = colors[n_stops - 1];
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
angles[n_stops - 1], &color0,
_2_M_PIf, &color0,
pattern);
goto done;
}
}
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++;
}
}
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);
}
}
}
}
else if (angles[0] < 0)
{
float ee = angles[n_stops - 1];
while (ee < 0)
{
if (span > 0)
{
ee += span;
k++;
}
else
{
ee -= span;
k--;
}
}
}
//assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span);
span = fabs (span);
for (signed l = k; l < 1000; l++)
{
for (unsigned i = 1; i < n_stops; i++)
{
float a0, a1;
hb_cairo_color_t *c0, *c1;
if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT))
{
a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span;
a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span;
c0 = &colors[n_stops - 1 - (i - 1)];
c1 = &colors[n_stops - 1 - i];
}
else
{
a0 = angles[i-1] + l * span;
a1 = angles[i] + l * span;
c0 = &colors[i-1];
c1 = &colors[i];
}
if (a1 < 0)
continue;
if (a0 < 0)
{
hb_cairo_color_t color;
float f = (0 - a0)/(a1 - a0);
_hb_cairo_interpolate_colors (c0, c1, f, &color);
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
0, &color,
a1, c1,
pattern);
}
else if (a1 >= HB_2_PI)
{
hb_cairo_color_t color;
float f = (HB_2_PI - a0)/(a1 - a0);
_hb_cairo_interpolate_colors (c0, c1, f, &color);
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
a0, c0,
HB_2_PI, &color,
pattern);
goto done;
}
else
{
_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
a0, c0,
a1, c1,
pattern);
}
}
}
}
done:
if (angles != angles_)
hb_free (angles);
free (angles);
if (colors != colors_)
hb_free (colors);
free (colors);
}
void
_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float cx, float cy,
float start_angle,
float end_angle)
hb_cairo_paint_sweep_gradient (cairo_t *cr,
hb_color_line_t *color_line,
float cx, float cy,
float start_angle,
float end_angle)
{
cairo_t *cr = c->cr;
unsigned int len = PREALLOCATED_COLOR_STOPS;
unsigned int len;
hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
hb_color_stop_t *stops = stops_;
cairo_extend_t extend;
@ -846,8 +803,10 @@ _hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
float max_x, max_y, radius;
cairo_pattern_t *pattern;
if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
return;
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);
hb_qsort (stops, len, sizeof (hb_color_stop_t), _hb_cairo_cmp_color_stop);
@ -868,7 +827,7 @@ _hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
cairo_pattern_destroy (pattern);
if (stops != stops_)
hb_free (stops);
free (stops);
}
#endif

View File

@ -31,15 +31,8 @@
#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)
{
@ -76,32 +69,32 @@ _hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
}
HB_INTERNAL hb_bool_t
_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
hb_blob_t *blob,
unsigned width,
unsigned height,
hb_tag_t format,
float slant,
hb_glyph_extents_t *extents);
hb_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_INTERNAL void
_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float x0, float y0,
float x1, float y1,
float x2, float y2);
hb_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_INTERNAL void
_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float x0, float y0, float r0,
float x1, float y1, float r1);
hb_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_INTERNAL void
_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line,
float x0, float y0,
float start_angle, float end_angle);
hb_cairo_paint_sweep_gradient (cairo_t *cr,
hb_color_line_t *color_line,
float x0, float y0,
float start_angle, float end_angle);
#endif /* HB_CAIRO_UTILS_H */

View File

@ -36,6 +36,9 @@
#include "hb-utf.hh"
/* TODO Error handling in cairo set_user_data calls? */
/**
* SECTION:hb-cairo
* @title: hb-cairo
@ -143,9 +146,7 @@ hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
float dx, float dy,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_matrix_t m;
cairo_save (cr);
@ -160,8 +161,7 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_restore (cr);
}
@ -173,8 +173,7 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_font_t *font,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_save (cr);
cairo_new_path (cr);
@ -189,8 +188,7 @@ 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)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_save (cr);
cairo_rectangle (cr,
@ -204,8 +202,7 @@ hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_restore (cr);
}
@ -215,8 +212,7 @@ hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
cairo_save (cr);
cairo_push_group (cr);
@ -228,11 +224,10 @@ hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_paint_composite_mode_t mode,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
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);
@ -245,26 +240,13 @@ hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_color_t color,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_t *cr = (cairo_t *) paint_data;
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_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);
}
@ -279,9 +261,9 @@ hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = (cairo_t *) paint_data;
return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
return hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents);
}
static void
@ -293,9 +275,9 @@ hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x2, float y2,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = (cairo_t *)paint_data;
_hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
hb_cairo_paint_linear_gradient (cr, color_line, x0, y0, x1, y1, x2, y2);
}
static void
@ -306,9 +288,9 @@ hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x1, float y1, float r1,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = (cairo_t *)paint_data;
_hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
hb_cairo_paint_radial_gradient (cr, color_line, x0, y0, r0, x1, y1, r1);
}
static void
@ -319,72 +301,9 @@ hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float start_angle, float end_angle,
void *user_data HB_UNUSED)
{
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = (cairo_t *) paint_data;
_hb_cairo_paint_sweep_gradient (c, color_line, x0, y0, start_angle, end_angle);
}
static const cairo_user_data_key_t color_cache_key = {0};
static void
_hb_cairo_destroy_map (void *p)
{
hb_map_destroy ((hb_map_t *) p);
}
static hb_bool_t
hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
void *paint_data,
unsigned int color_index,
hb_color_t *color,
void *user_data HB_UNUSED)
{
#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
#define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF)
hb_map_t *color_cache = c->color_cache;
hb_codepoint_t *v;
if (likely (color_cache && color_cache->has (color_index, &v)))
{
if (*v == HB_DEADBEEF)
return false;
*color = *v;
return true;
}
cairo_font_options_t *options;
double red, green, blue, alpha;
options = cairo_font_options_create ();
cairo_get_font_options (cr, options);
if (CAIRO_STATUS_SUCCESS ==
cairo_font_options_get_custom_palette_color (options, color_index,
&red, &green, &blue, &alpha))
{
cairo_font_options_destroy (options);
*color = HB_COLOR (round (255 * blue),
round (255 * green),
round (255 * red),
round (255 * alpha));
if (likely (color_cache && *color != HB_DEADBEEF))
color_cache->set (color_index, *color);
return true;
}
cairo_font_options_destroy (options);
if (likely (color_cache))
color_cache->set (color_index, HB_DEADBEEF);
#undef HB_DEADBEEF
#endif
return false;
hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle);
}
static inline void free_static_cairo_paint_funcs ();
@ -407,7 +326,6 @@ 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);
@ -428,6 +346,12 @@ 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};
@ -455,7 +379,6 @@ 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
@ -474,7 +397,6 @@ 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);
@ -515,15 +437,6 @@ 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;
}
@ -599,17 +512,19 @@ 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_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);
hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), cr, palette, color);
return CAIRO_STATUS_SUCCESS;
}
@ -630,11 +545,10 @@ 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
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);
cairo_font_face_set_user_data (cairo_face,
&hb_cairo_face_user_data_key,
(void *) hb_face_reference (face),
hb_cairo_face_destroy);
return cairo_face;
}
@ -651,7 +565,7 @@ user_font_face_create (hb_face_t *face)
*
* Returns: (transfer full): a newly created #cairo_font_face_t
*
* Since: 7.0.0
* Since: REPLACEME
*/
cairo_font_face_t *
hb_cairo_font_face_create_for_font (hb_font_t *font)
@ -660,11 +574,10 @@ hb_cairo_font_face_create_for_font (hb_font_t *font)
auto *cairo_face = user_font_face_create (font->face);
if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
&hb_cairo_font_user_data_key,
(void *) hb_font_reference (font),
hb_cairo_font_destroy)))
hb_font_destroy (font);
cairo_font_face_set_user_data (cairo_face,
&hb_cairo_font_user_data_key,
(void *) hb_font_reference (font),
hb_cairo_font_destroy);
return cairo_face;
}
@ -677,7 +590,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: 7.0.0
* Since: REPLACEME
*/
hb_font_t *
hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
@ -695,7 +608,7 @@ hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
*
* Returns: (transfer full): a newly created #cairo_font_face_t
*
* Since: 7.0.0
* Since: REPLACEME
*/
cairo_font_face_t *
hb_cairo_font_face_create_for_face (hb_face_t *face)
@ -713,7 +626,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: 7.0.0
* Since: REPLACEME
*/
hb_face_t *
hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
@ -733,7 +646,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: 7.0.0
* Since: REPLACEME
*/
void
hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
@ -745,17 +658,10 @@ 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);
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);
}
cairo_font_face_set_user_data (font_face,
&hb_cairo_font_init_user_data_user_data_key,
(void *) user_data,
destroy);
}
/**
@ -766,7 +672,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: 7.0.0
* Since: REPLACEME
*/
hb_font_t *
hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
@ -814,7 +720,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: 7.0.0
* Since: REPLACEME
*/
void
hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
@ -835,7 +741,7 @@ hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
*
* Returns: the scale factor of @font_face
*
* Since: 7.0.0
* Since: REPLACEME
*/
unsigned int
hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
@ -868,7 +774,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,
@ -877,11 +783,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
@ -898,7 +804,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: 7.0.0
* Since: REPLACEME
*/
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: 7.0.0
* Since: REPLACEME
*/
typedef hb_font_t * (*hb_cairo_font_init_func_t) (hb_font_t *font,
cairo_scaled_font_t *scaled_font,

View File

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

View File

@ -29,6 +29,32 @@
#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
@ -632,7 +658,6 @@ 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,7 +37,6 @@
#ifndef HB_EXPERIMENTAL_API
#define HB_NO_BEYOND_64K
#define HB_NO_CUBIC_GLYF
#define HB_NO_VAR_COMPOSITES
#endif
@ -136,10 +135,6 @@
#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) ", (int) (2 * sizeof (void *)), obj);
fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
else
fprintf (stderr, " %*s ", (int) (2 * sizeof (void *)), "");
fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
if (indented) {
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
@ -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 %u)",
"return %s (line %d)",
hb_printer_t<hb_decay<decltype (v)>>().print (v), line);
if (plevel) --*plevel;
plevel = nullptr;
@ -373,10 +373,6 @@ 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
@ -400,7 +396,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 %u gid %u lookup %d", \
"idx %d gid %u lookup %d", \
c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index)
#else
#define TRACE_APPLY(this) hb_no_trace_t<bool> trace
@ -458,7 +454,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 %u", (unsigned) format)
"format %d", (int) 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: 7.0.0
* Since: REPLACEME
**/
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: 7.0.0
* Since: REPLACEME
**/
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: 7.0.0
* Since: REPLACEME
**/
void *
hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,

View File

@ -47,12 +47,6 @@
* 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.
**/
@ -203,7 +197,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
* DFont that can contain more than one face. Face indices within
* and DFont that can contain more than one face. Face indices within
* such collections are zero-based.
*
* <note>Note: If the blob font format is not a collection, @index
@ -610,12 +604,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: 7.0.0
* Since: REPLACEME
*/
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 (/*Oh, well.*/const_cast<hb_face_t *> (this), tag, user_data);
blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
if (unlikely (!blob))
return hb_blob_get_empty ();

View File

@ -27,14 +27,6 @@
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:
@ -78,13 +70,6 @@ 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,11 +59,6 @@
*
* 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.
**/
@ -1066,8 +1061,7 @@ 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. Stopes at the
* first unsupported glyph ID.
* IDs must be returned in a #hb_codepoint_t output parameter.
*
* Return value: the number of code points processed
*
@ -1349,9 +1343,6 @@ 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
@ -1392,7 +1383,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
*
@ -1401,7 +1392,6 @@ 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,
@ -1414,7 +1404,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
*
@ -1423,7 +1413,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: 7.0.0
* Since: REPLACEME
**/
void
hb_font_draw_glyph (hb_font_t *font,
@ -1439,7 +1429,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_index: The index of the font's color palette to use
* @palette: The index of the font's color palette to use
* @foreground: The foreground color, unpremultipled
*
* Paints the glyph.
@ -1449,19 +1439,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_index selects the palette to use. If the font only
* has one palette, this will be 0.
* then @palette selects the palette to use. If the font doesn't
* have palettes, passing 0 is fine.
*
* Since: 7.0.0
* Since: REPLACEME
*/
void
hb_font_paint_glyph (hb_font_t *font,
hb_codepoint_t glyph,
hb_paint_funcs_t *pfuncs, void *paint_data,
unsigned int palette_index,
unsigned int palette,
hb_color_t foreground)
{
font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
font->paint_glyph (glyph, pfuncs, paint_data, palette, foreground);
}
/* A bit higher-level, and with fallback */
@ -1722,9 +1712,6 @@ 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
@ -1778,13 +1765,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */
1000, /* y_scale */
0.f, /* x_embolden */
0.f, /* y_embolden */
true, /* embolden_in_place */
0, /* x_strength */
0, /* y_strength */
0.f, /* slant */
0.f, /* slant_xy; */
0., /* slant */
0., /* slant_xy; */
1.f, /* x_multf */
1.f, /* y_multf */
1<<16, /* x_mult */
@ -1822,7 +1804,6 @@ _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;
@ -1907,9 +1888,6 @@ 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;
@ -2457,76 +2435,6 @@ 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
@ -2654,79 +2562,6 @@ 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
@ -2802,7 +2637,7 @@ hb_font_set_var_named_instance (hb_font_t *font,
*
* Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE.
*
* Since: 7.0.0
* Since: REPLACEME
**/
unsigned int
hb_font_get_var_named_instance (hb_font_t *font)

View File

@ -497,7 +497,8 @@ 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: 7.0.0: Use #hb_font_draw_glyph_func_t instead
*
* Deprecated: REPLACEME: 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,
@ -515,7 +516,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: 7.0.0
* Since: REPLACEME
*
**/
typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
@ -530,18 +531,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_index: The color palette to use
* @palette: The color palette to use
* @foreground: The foreground color
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* Since: 7.0.0
* Since: REPLACEME
*/
typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_paint_funcs_t *paint_funcs, void *paint_data,
unsigned int palette_index,
unsigned int palette,
hb_color_t foreground,
void *user_data);
@ -814,7 +815,8 @@ 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: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
*
* Deprecated: REPLACEME: Use hb_font_funcs_set_draw_glyph_func() instead
**/
HB_EXTERN void
hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
@ -831,7 +833,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: 7.0.0
* Since: REPLACEME
**/
HB_EXTERN void
hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs,
@ -847,7 +849,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: 7.0.0
* Since: REPLACEME
*/
HB_EXTERN void
hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs,
@ -948,7 +950,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_index,
unsigned int palette,
hb_color_t foreground);
/* high-level funcs, with fallback */
@ -1129,16 +1131,6 @@ 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);
@ -1150,11 +1142,6 @@ 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,
@ -1180,7 +1167,7 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
* named-instance index set. This is the default of
* a font.
*
* Since: 7.0.0
* Since: REPLACEME
*/
#define HB_FONT_NO_VAR_NAMED_INSTANCE 0xFFFFFFFF

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