Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Fabrice Fontaine 2020-11-17 07:31:07 +01:00
commit 0c3dcfae19
46 changed files with 3212 additions and 2125 deletions

View File

@ -10,49 +10,44 @@ executors:
jobs: jobs:
macos-10_12_6-aat-fonts:
macos:
xcode: "9.0.1"
steps:
- checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 ninja
- run: pip3 install meson --upgrade
- run: meson build
- run: meson compile -Cbuild # or ninja -Cbuild
- run: meson test -Cbuild --print-errorlogs
macos-10_13_6-aat-fonts: macos-10_13_6-aat-fonts:
macos: macos:
xcode: "10.1.0" xcode: "10.1.0"
steps: steps:
- checkout - checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 ninja - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config freetype glib cairo python3 ninja
- run: pip3 install meson --upgrade - run: pip3 install meson --upgrade
- run: meson build - run: meson build
- run: meson compile -Cbuild - run: meson compile -Cbuild
- run: meson test -Cbuild --print-errorlogs - run: meson test -Cbuild --print-errorlogs
- store_artifacts:
path: build/meson-logs/
macos-10_14_4-aat-fonts: macos-10_14_4-aat-fonts:
macos: macos:
xcode: "11.1.0" xcode: "11.1.0"
steps: steps:
- checkout - checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 ninja - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config freetype glib cairo python3 icu4c graphite2 ninja
- run: pip3 install meson --upgrade - run: pip3 install meson --upgrade
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled - run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled
- run: meson compile -Cbuild - run: meson compile -Cbuild
- run: meson test -Cbuild --print-errorlogs - run: meson test -Cbuild --print-errorlogs
- store_artifacts:
path: build/meson-logs/
macos-10_15_3-aat-fonts: macos-10_15_3-aat-fonts:
macos: macos:
xcode: "11.4.0" xcode: "11.4.0"
steps: steps:
- checkout - checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection gtk-doc ninja - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config freetype glib cairo python3 icu4c graphite2 gobject-introspection gtk-doc ninja
- run: pip3 install meson --upgrade - run: pip3 install meson --upgrade
- 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 - 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
- run: meson compile -Cbuild - run: meson compile -Cbuild
- run: meson test -Cbuild --print-errorlogs - run: meson test -Cbuild --print-errorlogs
- store_artifacts:
path: build/meson-logs/
# will be dropped with autotools removal # will be dropped with autotools removal
distcheck: distcheck:
@ -86,18 +81,18 @@ jobs:
- image: fedora - image: fedora
steps: steps:
- checkout - checkout
- run: dnf install -y pkg-config ragel valgrind gcc gcc-c++ meson git glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip || true - run: dnf install -y pkg-config valgrind gcc gcc-c++ meson git glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip || true
- run: meson build --buildtype=debugoptimized - run: meson build --buildtype=debugoptimized
- run: ninja -Cbuild -j9 - run: ninja -Cbuild -j9
# TOOD: increase timeouts and remove --no-suite=slow # TOOD: increase timeouts and remove --no-suite=slow
- run: RUN_VALGRIND=1 HB_TEST_SHAPE_FUZZER_TIMEOUT=5 meson test -Cbuild --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs - run: RUN_VALGRIND=1 meson test -Cbuild --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs
alpine: alpine:
docker: docker:
- image: alpine - image: alpine
steps: steps:
- checkout - checkout
- run: apk update && apk add ragel gcc g++ glib-dev freetype-dev cairo-dev git py3-pip ninja - run: apk update && apk add gcc g++ glib-dev freetype-dev cairo-dev git py3-pip ninja
- run: pip3 install meson==0.47.0 - run: pip3 install meson==0.47.0
- run: meson build --buildtype=minsize - run: meson build --buildtype=minsize
- run: ninja -Cbuild -j9 - run: ninja -Cbuild -j9
@ -108,7 +103,7 @@ jobs:
- image: archlinux/base - image: archlinux/base
steps: steps:
- checkout - checkout
- run: pacman --noconfirm -Syu freetype2 meson git clang cairo icu gettext gobject-introspection gcc gcc-libs glib2 graphite pkg-config ragel python python-pip base-devel gtk-doc - run: pacman --noconfirm -Syu freetype2 meson git clang cairo icu gettext gobject-introspection gcc gcc-libs glib2 graphite pkg-config python python-pip base-devel gtk-doc
- run: pip install flake8 fonttools - run: pip install flake8 fonttools
- run: pip install git+https://github.com/mesonbuild/meson - run: pip install git+https://github.com/mesonbuild/meson
- run: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics - run: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
@ -147,7 +142,7 @@ jobs:
executor: win32-executor executor: win32-executor
steps: steps:
- checkout - checkout
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build binutils meson gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip git g++-mingw-w64-i686 zip - run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build binutils meson gcc g++ pkg-config gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip git g++-mingw-w64-i686 zip
- run: .ci/build-win32.sh - run: .ci/build-win32.sh
- store_artifacts: - store_artifacts:
path: harfbuzz-win32.zip path: harfbuzz-win32.zip
@ -170,7 +165,6 @@ workflows:
build: build:
jobs: jobs:
- macos-10_12_6-aat-fonts
- macos-10_13_6-aat-fonts - macos-10_13_6-aat-fonts
- macos-10_14_4-aat-fonts - macos-10_14_4-aat-fonts
- macos-10_15_3-aat-fonts - macos-10_15_3-aat-fonts

View File

@ -233,7 +233,7 @@ endif ()
if (HB_HAVE_ICU) if (HB_HAVE_ICU)
add_definitions(-DHAVE_ICU) add_definitions(-DHAVE_ICU)
# https://github.com/WebKit/webkit/blob/master/Source/cmake/FindICU.cmake # https://github.com/WebKit/webkit/blob/fdd7733f2f30eab7fe096a9791f98c60f62f49c0/Source/cmake/FindICU.cmake
find_package(PkgConfig) find_package(PkgConfig)
pkg_check_modules(PC_ICU QUIET icu-uc) pkg_check_modules(PC_ICU QUIET icu-uc)

View File

@ -25,7 +25,7 @@ AM_PROG_CC_C_O
AC_PROG_CXX AC_PROG_CXX
AX_CXX_COMPILE_STDCXX(11) AX_CXX_COMPILE_STDCXX(11)
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
PKG_PROG_PKG_CONFIG([0.20]) PKG_PROG_PKG_CONFIG([0.28])
AM_MISSING_PROG([RAGEL], [ragel]) AM_MISSING_PROG([RAGEL], [ragel])
AM_MISSING_PROG([GIT], [git]) AM_MISSING_PROG([GIT], [git])

View File

@ -11,8 +11,7 @@
<title>HarfBuzz</title> <title>HarfBuzz</title>
<graphic fileref="HarfBuzz.png" format="PNG" align="center"/> <graphic fileref="HarfBuzz.png" format="PNG" align="center"/>
<para> <para>
HarfBuzz is an <ulink url="http://www.microsoft.com/typography/otspec/">OpenType</ulink> HarfBuzz is a text shaping library. Using the HarfBuzz library allows
text shaping engine. Using the HarfBuzz library allows
programs to convert a sequence of Unicode input into programs to convert a sequence of Unicode input into
properly formatted and positioned glyph output&mdash;for any writing properly formatted and positioned glyph output&mdash;for any writing
system and language. system and language.

View File

@ -80,6 +80,7 @@ hb_buffer_set_user_data
hb_buffer_get_user_data hb_buffer_get_user_data
hb_buffer_get_glyph_infos hb_buffer_get_glyph_infos
hb_buffer_get_glyph_positions hb_buffer_get_glyph_positions
hb_buffer_has_positions
hb_buffer_get_invisible_glyph hb_buffer_get_invisible_glyph
hb_buffer_set_invisible_glyph hb_buffer_set_invisible_glyph
hb_buffer_set_replacement_codepoint hb_buffer_set_replacement_codepoint

View File

@ -136,10 +136,12 @@
determine which glyph to return. determine which glyph to return.
</para> </para>
<para> <para>
The safest approach is to add all of the text available, then The safest approach is to add all of the text available (even
use <parameter>item_offset</parameter> and if your text contains a mix of scripts, directions, languages
and fonts), then use <parameter>item_offset</parameter> and
<parameter>item_length</parameter> to indicate which characters you <parameter>item_length</parameter> to indicate which characters you
want shaped, so that HarfBuzz has access to any context. want shaped (which must all have the same script, direction,
language and font), so that HarfBuzz has access to any context.
</para> </para>
<para> <para>
You can also add Unicode code points directly with You can also add Unicode code points directly with

View File

@ -50,13 +50,9 @@
</para> </para>
<para> <para>
For example, on an Ubuntu or Debian system, you would run: For example, on an Ubuntu or Debian system, you would run:
<programlisting> <programlisting><command>sudo apt install</command> <package>gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev</package></programlisting>
<command>sudo apt install</command> <package>gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev</package>
</programlisting>
On Fedora, RHEL, CentOS, or other Red-Hat&ndash;based systems, you would run: On Fedora, RHEL, CentOS, or other Red-Hat&ndash;based systems, you would run:
<programlisting> <programlisting><command>sudo yum install</command> <package>gcc gcc-c++ freetype-devel glib2-devel cairo-devel</package></programlisting>
<command>sudo yum install</command> <package>gcc gcc-c++ freetype-devel glib2-devel cairo-devel</package>
</programlisting>
</para> </para>
@ -89,13 +85,9 @@
</para> </para>
<para> <para>
On Ubuntu or Debian, run: On Ubuntu or Debian, run:
<programlisting> <programlisting><command>sudo apt-get install</command> <package>meson pkg-config gtk-doc-tools</package></programlisting>
<command>sudo apt-get install</command> <package>meson pkg-config gtk-doc-tools</package>
</programlisting>
On Fedora, RHEL, CentOS, run: On Fedora, RHEL, CentOS, run:
<programlisting> <programlisting><command>sudo yum install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
<command>sudo yum install</command> <package>meson pkgconfig gtk-doc</package>
</programlisting>
</para> </para>
<para> <para>
@ -110,8 +102,11 @@
<title>Building on Windows</title> <title>Building on Windows</title>
<para> <para>
Install meson and use it like `meson build --wrap-mode=default` <ulink url="https://mesonbuild.com/Getting-meson.html">Install meson</ulink>
or use vcpkg. and run (from the console) <command>meson build</command> (by default
bundled dependencies are not built, <command>--wrap-mode=default</command>
overrides this), then <command>meson compile -C build</command> to
build HarfBuzz.
</para> </para>
</section> </section>
@ -128,15 +123,11 @@
<emphasis>(1)</emphasis> You must first install the <emphasis>(1)</emphasis> You must first install the
development packages for FreeType, Cairo, and GLib. If you are development packages for FreeType, Cairo, and GLib. If you are
using MacPorts, you should run: using MacPorts, you should run:
<programlisting> <programlisting><command>sudo port install</command> <package>freetype glib2 cairo</package></programlisting>
<command>sudo port install</command> <package>freetype glib2 cairo</package>
</programlisting>
</para> </para>
<para> <para>
If you are using Homebrew, you should run: If you are using Homebrew, you should run:
<programlisting> <programlisting><command>brew install</command> <package>freetype glib cairo</package></programlisting>
<command>brew install</command> <package>freetype glib cairo</package>
</programlisting>
</para> </para>
<para> <para>
<emphasis>(2)</emphasis> The next step depends on whether you are building from the <emphasis>(2)</emphasis> The next step depends on whether you are building from the
@ -147,13 +138,9 @@
<emphasis>(2)(a)</emphasis> If you are installing HarfBuzz <emphasis>(2)(a)</emphasis> If you are installing HarfBuzz
from a downloaded tarball release, extract the tarball and from a downloaded tarball release, extract the tarball and
open a Terminal in the extracted source-code directory. Run: open a Terminal in the extracted source-code directory. Run:
<programlisting> <programlisting><command>meson build</command></programlisting>
<command>meson build</command>
</programlisting>
followed by: followed by:
<programlisting> <programlisting><command>meson compile -C build</command></programlisting>
<command>meson compile -C build</command>
</programlisting>
to build HarfBuzz. to build HarfBuzz.
</para> </para>
<para> <para>
@ -164,30 +151,20 @@
</para> </para>
<para>If you are <para>If you are
using MacPorts, you should run: using MacPorts, you should run:
<programlisting> <programlisting><command>sudo port install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
<command>sudo port install</command> <package>meson pkgconfig gtk-doc</package>
</programlisting>
to install the build dependencies. to install the build dependencies.
</para> </para>
<para>If you are using Homebrew, you should run: <para>If you are using Homebrew, you should run:
<programlisting> <programlisting><command>brew install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
<command>brew install</command> <package>meson pkgconfig gtk-doc</package>
</programlisting>
Finally, you can run: Finally, you can run:
<programlisting> <programlisting><command>meson build</command></programlisting>
<command>meson build</command>
</programlisting>
</para> </para>
<para> <para>
<emphasis>(3)</emphasis> You can now build HarfBuzz (on either <emphasis>(3)</emphasis> You can now build HarfBuzz (on either
a MacPorts or a Homebrew system) by running: a MacPorts or a Homebrew system) by running:
<programlisting> <programlisting><command>meson build</command></programlisting>
<command>meson build</command>
</programlisting>
followed by: followed by:
<programlisting> <programlisting><command>meson compile -C build</command></programlisting>
<command>meson compile -C build</command>
</programlisting>
</para> </para>
<para> <para>
This should leave you with a shared This should leave you with a shared

View File

@ -468,11 +468,8 @@ class OpenTypeRegistryParser (HTMLParser):
if ot_macrolanguages: if ot_macrolanguages:
for ot_macrolanguage in ot_macrolanguages: for ot_macrolanguage in ot_macrolanguages:
for language in languages: for language in languages:
# Remove the following condition if e.g. nn should map to NYN,NOR self.add_language (language, ot_macrolanguage)
# instead of just NYN. self.ranks[ot_macrolanguage] += 1
if language not in original_ot_from_bcp_47:
self.add_language (language, ot_macrolanguage)
self.ranks[ot_macrolanguage] += 1
else: else:
for language in languages: for language in languages:
if language in original_ot_from_bcp_47: if language in original_ot_from_bcp_47:
@ -591,7 +588,9 @@ class BCP47Parser (object):
elif not has_preferred_value and line.startswith ('Macrolanguage: '): elif not has_preferred_value and line.startswith ('Macrolanguage: '):
self._add_macrolanguage (line.split (' ')[1], subtag) self._add_macrolanguage (line.split (' ')[1], subtag)
elif subtag_type == 'variant': elif subtag_type == 'variant':
if line.startswith ('Prefix: '): if line.startswith ('Deprecated: '):
self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '')
elif line.startswith ('Prefix: '):
self.prefixes[subtag].add (line.split (' ')[1]) self.prefixes[subtag].add (line.split (' ')[1])
elif line.startswith ('File-Date: '): elif line.startswith ('File-Date: '):
self.header = line self.header = line
@ -622,6 +621,17 @@ class BCP47Parser (object):
for macrolanguage in macrolanguages: for macrolanguage in macrolanguages:
self._add_macrolanguage (biggest_macrolanguage, macrolanguage) self._add_macrolanguage (biggest_macrolanguage, macrolanguage)
def _get_name_piece (self, subtag):
"""Return the first name of a subtag plus its scope suffix.
Args:
subtag (str): A BCP 47 subtag.
Returns:
The name form of ``subtag``.
"""
return self.names[subtag].split ('\n')[0] + self.scopes.get (subtag, '')
def get_name (self, lt): def get_name (self, lt):
"""Return the names of the subtags in a language tag. """Return the names of the subtags in a language tag.
@ -631,13 +641,13 @@ class BCP47Parser (object):
Returns: Returns:
The name form of ``lt``. The name form of ``lt``.
""" """
name = self.names[lt.language].split ('\n')[0] name = self._get_name_piece (lt.language)
if lt.script: if lt.script:
name += '; ' + self.names[lt.script.title ()].split ('\n')[0] name += '; ' + self._get_name_piece (lt.script.title ())
if lt.region: if lt.region:
name += '; ' + self.names[lt.region.upper ()].split ('\n')[0] name += '; ' + self._get_name_piece (lt.region.upper ())
if lt.variant: if lt.variant:
name += '; ' + self.names[lt.variant].split ('\n')[0] name += '; ' + self._get_name_piece (lt.variant)
return name return name
bcp_47 = BCP47Parser () bcp_47 = BCP47Parser ()
@ -673,6 +683,8 @@ ot.add_language ('und-fonnapa', 'APPH')
ot.remove_language_ot ('IRT') ot.remove_language_ot ('IRT')
ot.add_language ('ga-Latg', 'IRT') ot.add_language ('ga-Latg', 'IRT')
ot.add_language ('hy-arevmda', 'HYE')
ot.remove_language_ot ('KGE') ot.remove_language_ot ('KGE')
ot.add_language ('und-Geok', 'KGE') ot.add_language ('und-Geok', 'KGE')
@ -796,6 +808,7 @@ disambiguation = {
'ECR': 'crj', 'ECR': 'crj',
'HAL': 'cfm', 'HAL': 'cfm',
'HND': 'hnd', 'HND': 'hnd',
'HYE': 'hyw',
'KIS': 'kqs', 'KIS': 'kqs',
'KUI': 'uki', 'KUI': 'uki',
'LRC': 'bqi', 'LRC': 'bqi',
@ -982,22 +995,24 @@ for initial, items in sorted (complex_tags.items ()):
print (" case '%s':" % initial) print (" case '%s':" % initial)
for lt, tags in items: for lt, tags in items:
print (' if (', end='') print (' if (', end='')
script = lt.script
region = lt.region
if lt.grandfathered: if lt.grandfathered:
print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='')
else: else:
string_literal = lt.language[1:] + '-' string_literal = lt.language[1:] + '-'
if lt.script: if script:
string_literal += lt.script string_literal += script
lt.script = None script = None
if lt.region: if region:
string_literal += '-' + lt.region string_literal += '-' + region
lt.region = None region = None
if string_literal[-1] == '-': if string_literal[-1] == '-':
print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='')
else: else:
print ('lang_matches (&lang_str[1], "%s")' % string_literal, end='') print ('lang_matches (&lang_str[1], "%s")' % string_literal, end='')
print_subtag_matches (lt.script, True) print_subtag_matches (script, True)
print_subtag_matches (lt.region, True) print_subtag_matches (region, True)
print_subtag_matches (lt.variant, True) print_subtag_matches (lt.variant, True)
print (')') print (')')
print (' {') print (' {')
@ -1087,8 +1102,8 @@ def verify_disambiguation_dict ():
'%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag))
elif ot_tag not in disambiguation: elif ot_tag not in disambiguation:
disambiguation[ot_tag] = macrolanguages[0] disambiguation[ot_tag] = macrolanguages[0]
different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t))) different_bcp_47_tags = sorted (t for t in bcp_47_tags if not same_tag (t, ot.from_bcp_47.get (t)))
if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]: if different_bcp_47_tags and disambiguation[ot_tag] == different_bcp_47_tags[0] and '-' not in disambiguation[ot_tag]:
del disambiguation[ot_tag] del disambiguation[ot_tag]
for ot_tag in disambiguation.keys (): for ot_tag in disambiguation.keys ():
expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)

View File

@ -9,8 +9,8 @@ Input files:
* https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt * https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt * https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt
* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt * https://unicode.org/Public/UCD/latest/ucd/Blocks.txt
* ms-use/IndicPositionalCategory-Additional.txt
* ms-use/IndicSyllabicCategory-Additional.txt * ms-use/IndicSyllabicCategory-Additional.txt
* ms-use/IndicPositionalCategory-Additional.txt
""" """
import sys import sys
@ -241,14 +241,13 @@ def is_BASE(U, UISC, UGC, AJT):
return (UISC in [Number, Consonant, Consonant_Head_Letter, return (UISC in [Number, Consonant, Consonant_Head_Letter,
Tone_Letter, Tone_Letter,
Vowel_Independent, Vowel_Independent,
] or ] and
# TODO: https://github.com/microsoft/font-tools/issues/12
UGC != Cn or
# TODO: https://github.com/MicrosoftDocs/typography-issues/issues/484 # TODO: https://github.com/MicrosoftDocs/typography-issues/issues/484
AJT in [jt_C, jt_D, jt_L, jt_R] and not is_ZWJ(U, UISC, UGC, AJT) or AJT in [jt_C, jt_D, jt_L, jt_R] and UISC != Joiner or
(UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial,
Consonant_Subjoined, Vowel, Vowel_Dependent])) Consonant_Subjoined, Vowel, Vowel_Dependent]))
def is_BASE_IND(U, UISC, UGC, AJT):
return (UISC in [Consonant_Dead, Modifying_Letter] or
(UGC == Po and not U in [0x0F04, 0x0F05, 0x0F06, 0x104B, 0x104E, 0x1800, 0x1807, 0x180A, 0x1B5B, 0x1B5C, 0x1B5F, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]))
def is_BASE_NUM(U, UISC, UGC, AJT): def is_BASE_NUM(U, UISC, UGC, AJT):
return UISC == Brahmi_Joining_Number return UISC == Brahmi_Joining_Number
def is_BASE_OTHER(U, UISC, UGC, AJT): def is_BASE_OTHER(U, UISC, UGC, AJT):
@ -290,19 +289,13 @@ def is_HIEROGLYPH_SEGMENT_END(U, UISC, UGC, AJT):
return UISC == Hieroglyph_Segment_End return UISC == Hieroglyph_Segment_End
def is_ZWNJ(U, UISC, UGC, AJT): def is_ZWNJ(U, UISC, UGC, AJT):
return UISC == Non_Joiner return UISC == Non_Joiner
def is_ZWJ(U, UISC, UGC, AJT):
return UISC == Joiner
def is_Word_Joiner(U, UISC, UGC, AJT):
return U == 0x2060
def is_OTHER(U, UISC, UGC, AJT): def is_OTHER(U, UISC, UGC, AJT):
return (UISC == Other return ((UGC in [Cn, Po] or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other])
and not is_BASE(U, UISC, UGC, AJT) and not is_BASE(U, UISC, UGC, AJT)
and not is_BASE_OTHER(U, UISC, UGC, AJT)
and not is_SYM(U, UISC, UGC, AJT) and not is_SYM(U, UISC, UGC, AJT)
and not is_SYM_MOD(U, UISC, UGC, AJT) and not is_SYM_MOD(U, UISC, UGC, AJT)
and not is_Word_Joiner(U, UISC, UGC, AJT)
) )
def is_Reserved(U, UISC, UGC, AJT):
return UGC == 'Cn'
def is_REPHA(U, UISC, UGC, AJT): def is_REPHA(U, UISC, UGC, AJT):
return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed] return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
def is_SAKOT(U, UISC, UGC, AJT): def is_SAKOT(U, UISC, UGC, AJT):
@ -321,10 +314,9 @@ def is_VOWEL_MOD(U, UISC, UGC, AJT):
return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
(UGC != Lo and (UISC == Bindu or U in [0xAA29]))) (UGC != Lo and (UISC == Bindu or U in [0xAA29])))
# CGJ and VS are handled in find_syllables # CGJ, VS, WJ, and ZWJ are handled in find_syllables
use_mapping = { use_mapping = {
'B': is_BASE, 'B': is_BASE,
'IND': is_BASE_IND,
'N': is_BASE_NUM, 'N': is_BASE_NUM,
'GB': is_BASE_OTHER, 'GB': is_BASE_OTHER,
'F': is_CONS_FINAL, 'F': is_CONS_FINAL,
@ -341,10 +333,7 @@ use_mapping = {
'SB': is_HIEROGLYPH_SEGMENT_BEGIN, 'SB': is_HIEROGLYPH_SEGMENT_BEGIN,
'SE': is_HIEROGLYPH_SEGMENT_END, 'SE': is_HIEROGLYPH_SEGMENT_END,
'ZWNJ': is_ZWNJ, 'ZWNJ': is_ZWNJ,
'ZWJ': is_ZWJ,
'WJ': is_Word_Joiner,
'O': is_OTHER, 'O': is_OTHER,
'Rsv': is_Reserved,
'R': is_REPHA, 'R': is_REPHA,
'S': is_SYM, 'S': is_SYM,
'Sk': is_SAKOT, 'Sk': is_SAKOT,
@ -402,11 +391,6 @@ def map_to_use(data):
items = use_mapping.items() items = use_mapping.items()
for U,(UISC,UIPC,UGC,AJT,UBlock) in data.items(): for U,(UISC,UIPC,UGC,AJT,UBlock) in data.items():
if UGC == Cn: continue
# TODO: These variation selectors are overridden to IND, but we want to ignore them
if U in range (0xFE00, 0xFE0F + 1): continue
# Resolve Indic_Syllabic_Category # Resolve Indic_Syllabic_Category
# TODO: These don't have UISC assigned in Unicode 13.0.0, but have UIPC # TODO: These don't have UISC assigned in Unicode 13.0.0, but have UIPC
@ -533,6 +517,8 @@ print ("static const USE_TABLE_ELEMENT_TYPE use_table[] = {")
for u in uu: for u in uu:
if u <= last: if u <= last:
continue continue
if data[u][0] == 'O':
continue
block = data[u][1] block = data[u][1]
start = u//8*8 start = u//8*8

File diff suppressed because it is too large Load Diff

View File

@ -52,14 +52,18 @@ action tok {
tok = p; tok = p;
} }
action parse_glyph { action ensure_glyphs { if (unlikely (!buffer->ensure_glyphs ())) return false; }
action ensure_unicode { if (unlikely (!buffer->ensure_unicode ())) return false; }
action parse_glyph_name {
/* TODO Unescape \" and \\ if found. */
if (!hb_font_glyph_from_string (font, if (!hb_font_glyph_from_string (font,
tok, p - tok, tok, p - tok,
&info.codepoint)) &info.codepoint))
return false; return false;
} }
action parse_gid { if (!parse_uint (tok, p, &info.codepoint)) return false; } action parse_codepoint { if (!parse_uint (tok, p, &info.codepoint)) return false; }
action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) 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_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; } action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
@ -72,20 +76,27 @@ num = '-'? unum;
comma = space* ',' space*; comma = space* ',' space*;
colon = space* ':' space*; colon = space* ':' space*;
glyph_id = unum; codepoint = unum;
glyph_name = alpha (alnum|'_'|'.'|'-')*; glyph_name = '"' ([^\\"] | '\\' [\\"])* '"';
glyph_string = '"' (glyph_name >tok %parse_glyph) '"'; parse_glyph_name = (glyph_name >tok %parse_glyph_name);
glyph_number = (glyph_id >tok %parse_gid); parse_codepoint = (codepoint >tok %parse_codepoint);
glyph = "\"g\"" colon (glyph_string | glyph_number); glyph = "\"g\"" colon (parse_glyph_name | parse_codepoint);
unicode = "\"u\"" colon parse_codepoint;
cluster = "\"cl\"" colon (unum >tok %parse_cluster); cluster = "\"cl\"" colon (unum >tok %parse_cluster);
xoffset = "\"dx\"" colon (num >tok %parse_x_offset); xoffset = "\"dx\"" colon (num >tok %parse_x_offset);
yoffset = "\"dy\"" colon (num >tok %parse_y_offset); yoffset = "\"dy\"" colon (num >tok %parse_y_offset);
xadvance= "\"ax\"" colon (num >tok %parse_x_advance); xadvance= "\"ax\"" colon (num >tok %parse_x_advance);
yadvance= "\"ay\"" colon (num >tok %parse_y_advance); yadvance= "\"ay\"" colon (num >tok %parse_y_advance);
element = glyph | cluster | xoffset | yoffset | xadvance | yadvance; element = glyph @ensure_glyphs
| unicode @ensure_unicode
| cluster
| xoffset
| yoffset
| xadvance
| yadvance;
item = item =
( '{' space* element (comma element)* space* '}') ( '{' space* element (comma element)* space* '}')
>clear_item >clear_item
@ -97,7 +108,7 @@ main := space* item (comma item)* space* (','|']')?;
}%% }%%
static hb_bool_t static hb_bool_t
_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, _hb_buffer_deserialize_json (hb_buffer_t *buffer,
const char *buf, const char *buf,
unsigned int buf_len, unsigned int buf_len,
const char **end_ptr, const char **end_ptr,

File diff suppressed because it is too large Load Diff

View File

@ -52,30 +52,37 @@ action tok {
tok = p; 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 { action parse_glyph {
/* TODO Unescape delimeters. */
if (!hb_font_glyph_from_string (font, if (!hb_font_glyph_from_string (font,
tok, p - tok, tok, p - tok,
&info.codepoint)) &info.codepoint))
return false; 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_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_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; } action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; } action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; }
action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; } action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; }
unum = '0' | [1-9] digit*; unum = '0' | [1-9] digit*;
num = '-'? unum; num = '-'? unum;
glyph_id = unum; glyph_id = unum;
glyph_name = alpha (alnum|'_'|'.'|'-')*; glyph_name = ([^\\\]=@+,|] | '\\' [\\\]=@+,|]) *;
glyph = (glyph_id | glyph_name) >tok %parse_glyph; glyph = (glyph_id | glyph_name) >tok %parse_glyph;
cluster = '=' (unum >tok %parse_cluster); cluster = '=' (unum >tok %parse_cluster);
offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset ); offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset );
advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?; advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?;
item =
glyph_item =
( (
glyph glyph
cluster? cluster?
@ -83,15 +90,31 @@ item =
advances? advances?
) )
>clear_item >clear_item
@ensure_glyphs
%add_item %add_item
; ;
main := space* item (space* '|' space* item)* space* ('|'|']')?; unicode = 'U' '+' xdigit+ >tok %parse_hexdigits;
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 static hb_bool_t
_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, _hb_buffer_deserialize_text (hb_buffer_t *buffer,
const char *buf, const char *buf,
unsigned int buf_len, unsigned int buf_len,
const char **end_ptr, const char **end_ptr,
@ -104,10 +127,6 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
while (p < pe && ISSPACE (*p)) while (p < pe && ISSPACE (*p))
p++; p++;
if (p < pe && *p == (buffer->len ? '|' : '['))
{
*end_ptr = ++p;
}
const char *eof = pe, *tok = nullptr; const char *eof = pe, *tok = nullptr;
int cs; int cs;

View File

@ -91,26 +91,26 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{ {
switch ((unsigned) format) switch ((unsigned) format)
{ {
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0]; case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1]; case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
default: default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr; case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
} }
} }
static unsigned int static unsigned int
_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
unsigned int start, unsigned int start,
unsigned int end, unsigned int end,
char *buf, char *buf,
unsigned int buf_size, unsigned int buf_size,
unsigned int *buf_consumed, unsigned int *buf_consumed,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_flags_t flags) hb_buffer_serialize_flags_t flags)
{ {
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0; *buf_consumed = 0;
hb_position_t x = 0, y = 0; hb_position_t x = 0, y = 0;
@ -125,6 +125,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (i) if (i)
*p++ = ','; *p++ = ',';
else
*p++ = '[';
*p++ = '{'; *p++ = '{';
@ -134,8 +136,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
char g[128]; char g[128];
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g)); hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
*p++ = '"'; *p++ = '"';
for (char *q = g; *q; q++) { for (char *q = g; *q; q++)
if (*q == '"') {
if (unlikely (*q == '"' || *q == '\\'))
*p++ = '\\'; *p++ = '\\';
*p++ = *q; *p++ = *q;
} }
@ -151,16 +154,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{ {
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
x+pos[i].x_offset, y+pos[i].y_offset)); x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
pos[i].x_advance, pos[i].y_advance)); pos[i].x_advance, pos[i].y_advance));
} }
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
{ {
if (info[i].mask & HB_GLYPH_FLAG_DEFINED) if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
} }
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@ -168,12 +171,14 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_glyph_extents_t extents; hb_glyph_extents_t extents;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents); hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
extents.x_bearing, extents.y_bearing)); extents.x_bearing, extents.y_bearing));
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
extents.width, extents.height)); extents.width, extents.height));
} }
*p++ = '}'; *p++ = '}';
if (i == end-1)
*p++ = ']';
unsigned int l = p - b; unsigned int l = p - b;
if (buf_size > l) if (buf_size > l)
@ -196,19 +201,72 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
return end - start; return end - start;
} }
static unsigned int
_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
char *p = b;
if (i)
*p++ = ',';
else
*p++ = '[';
*p++ = '{';
APPEND ("\"u\":");
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
}
*p++ = '}';
if (i == end-1)
*p++ = ']';
unsigned int l = p - b;
if (buf_size > l)
{
memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
}
return end - start;
}
static unsigned int static unsigned int
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
unsigned int start, unsigned int start,
unsigned int end, unsigned int end,
char *buf, char *buf,
unsigned int buf_size, unsigned int buf_size,
unsigned int *buf_consumed, unsigned int *buf_consumed,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_flags_t flags) hb_buffer_serialize_flags_t flags)
{ {
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0; *buf_consumed = 0;
hb_position_t x = 0, y = 0; hb_position_t x = 0, y = 0;
@ -221,9 +279,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (i) if (i)
*p++ = '|'; *p++ = '|';
else
*p++ = '[';
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES)) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
{ {
/* TODO Escape delimiters we use. */
hb_font_glyph_to_string (font, info[i].codepoint, p, 128); hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
p += strlen (p); p += strlen (p);
} }
@ -237,21 +298,21 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{ {
if (x+pos[i].x_offset || y+pos[i].y_offset) if (x+pos[i].x_offset || y+pos[i].y_offset)
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
{ {
*p++ = '+'; *p++ = '+';
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
if (pos[i].y_advance) if (pos[i].y_advance)
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
} }
} }
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
{ {
if (info[i].mask & HB_GLYPH_FLAG_DEFINED) if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
} }
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@ -261,6 +322,10 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
} }
if (i == end-1) {
*p++ = ']';
}
unsigned int l = p - b; unsigned int l = p - b;
if (buf_size > l) if (buf_size > l)
{ {
@ -282,6 +347,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
return end - start; return end - start;
} }
static unsigned int
_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
char *p = b;
if (i)
*p++ = '|';
else
*p++ = '<';
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
}
if (i == end-1)
*p++ = '>';
unsigned int l = p - b;
if (buf_size > l)
{
memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
}
return end - start;
}
/** /**
* hb_buffer_serialize_glyphs: * hb_buffer_serialize_glyphs:
* @buffer: an #hb_buffer_t buffer. * @buffer: an #hb_buffer_t buffer.
@ -321,7 +431,24 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* `&lt;x_bearing,y_bearing,width,height&gt;` * `&lt;x_bearing,y_bearing,width,height&gt;`
* *
* ## json * ## json
* TODO. * A machine-readable, structured format.
* The serialized glyphs will look something like:
*
* ```
* [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},
* {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]
* ```
* Each glyph is a JSON object, with the following properties:
* - `g`: the glyph name or glyph index if
* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.
* - `cl`: #hb_glyph_info_t.cluster if
* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
* - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,
* #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance
* respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.
* - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,
* #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if
* #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.
* *
* Return value: * Return value:
* The number of serialized items. * The number of serialized items.
@ -330,16 +457,17 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
**/ **/
unsigned int unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer, hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
unsigned int start, unsigned int start,
unsigned int end, unsigned int end,
char *buf, char *buf,
unsigned int buf_size, unsigned int buf_size,
unsigned int *buf_consumed, unsigned int *buf_consumed,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_format_t format, hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags) hb_buffer_serialize_flags_t flags)
{ {
assert (start <= end && end <= buffer->len); end = hb_clamp (end, start, buffer->len);
start = hb_min (start, end);
unsigned int sconsumed; unsigned int sconsumed;
if (!buf_consumed) if (!buf_consumed)
@ -348,8 +476,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size) if (buf_size)
*buf = '\0'; *buf = '\0';
assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) || buffer->assert_glyphs ();
(buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
if (!buffer->have_positions) if (!buffer->have_positions)
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS; flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
@ -364,13 +491,13 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
{ {
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_glyphs_text (buffer, start, end, return _hb_buffer_serialize_glyphs_text (buffer, start, end,
buf, buf_size, buf_consumed, buf, buf_size, buf_consumed,
font, flags); font, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON: case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_glyphs_json (buffer, start, end, return _hb_buffer_serialize_glyphs_json (buffer, start, end,
buf, buf_size, buf_consumed, buf, buf_size, buf_consumed,
font, flags); font, flags);
default: default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
@ -379,6 +506,180 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
} }
} }
/**
* hb_buffer_serialize_unicode:
* @buffer: an #hb_buffer_t buffer.
* @start: the first item in @buffer to serialize.
* @end: the last item in @buffer to serialize.
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
*
* Serializes @buffer into a textual representation of its content,
* when the buffer contains Unicode codepoints (i.e., before shaping). This is
* useful for showing the contents of the buffer, for example during debugging.
* There are currently two supported serialization formats:
*
* ## text
* A human-readable, plain text format.
* The serialized codepoints will look something like:
*
* ```
* <U+0651=0|U+0628=1>
* ```
* - Glyphs are separated with `|`
* - Unicode codepoints are expressed as zero-padded four (or more)
* digit hexadecimal numbers preceded by `U+`
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster
* will be indicated with a `=` then #hb_glyph_info_t.cluster.
*
* ## json
* A machine-readable, structured format.
* The serialized codepoints will be a list of objects with the following
* properties:
* - `u`: the Unicode codepoint as a decimal integer
* - `cl`: #hb_glyph_info_t.cluster if
* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
*
* For example:
* ```
* [{u:1617,cl:0},{u:1576,cl:1}]
* ```
*
* Return value:
* The number of serialized items.
*
* Since: 2.7.3
**/
unsigned int
hb_buffer_serialize_unicode (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
end = hb_clamp (end, start, buffer->len);
start = hb_min (start, end);
unsigned int sconsumed;
if (!buf_consumed)
buf_consumed = &sconsumed;
*buf_consumed = 0;
if (buf_size)
*buf = '\0';
buffer->assert_unicode ();
if (unlikely (start == end))
return 0;
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_unicode_text (buffer, start, end,
buf, buf_size, buf_consumed, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_unicode_json (buffer, start, end,
buf, buf_size, buf_consumed, flags);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
return 0;
}
}
static unsigned int
_hb_buffer_serialize_invalid (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
assert (!buffer->len);
unsigned int sconsumed;
if (!buf_consumed)
buf_consumed = &sconsumed;
if (buf_size < 3)
return 0;
if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {
*buf++ = '[';
*buf++ = ']';
*buf = '\0';
} else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {
*buf++ = '!';
*buf++ = '!';
*buf = '\0';
}
*buf_consumed = 2;
return 0;
}
/**
* hb_buffer_serialize:
* @buffer: an #hb_buffer_t buffer.
* @start: the first item in @buffer to serialize.
* @end: the last item in @buffer to serialize.
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
* @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
* read glyph names and extents. If %NULL, and empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
*
* Serializes @buffer into a textual representation of its content, whether
* Unicode codepoints or glyph identifiers and positioning information. This is
* useful for showing the contents of the buffer, for example during debugging.
* See the documentation of hb_buffer_serialize_unicode() and
* hb_buffer_serialize_glyphs() for a description of the output format.
*
* Return value:
* The number of serialized items.
*
* Since: 2.7.3
**/
unsigned int
hb_buffer_serialize (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
switch (buffer->content_type)
{
case HB_BUFFER_CONTENT_TYPE_GLYPHS:
return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,
buf_consumed, font, format, flags);
case HB_BUFFER_CONTENT_TYPE_UNICODE:
return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,
buf_consumed, format, flags);
case HB_BUFFER_CONTENT_TYPE_INVALID:
default:
return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,
buf_consumed, format, flags);
}
}
static bool static bool
parse_int (const char *pp, const char *end, int32_t *pv) parse_int (const char *pp, const char *end, int32_t *pv)
{ {
@ -403,6 +704,18 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
return true; return true;
} }
static bool
parse_hex (const char *pp, const char *end, uint32_t *pv)
{
unsigned int v;
const char *p = pp;
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))
return false;
*pv = v;
return true;
}
#include "hb-buffer-deserialize-json.hh" #include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh" #include "hb-buffer-deserialize-text.hh"
@ -423,23 +736,23 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
**/ **/
hb_bool_t hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf, const char *buf,
int buf_len, /* -1 means nul-terminated */ int buf_len, /* -1 means nul-terminated */
const char **end_ptr, /* May be NULL */ const char **end_ptr, /* May be NULL */
hb_font_t *font, /* May be NULL */ hb_font_t *font, /* May be NULL */
hb_buffer_serialize_format_t format) hb_buffer_serialize_format_t format)
{ {
const char *end; const char *end;
if (!end_ptr) if (!end_ptr)
end_ptr = &end; end_ptr = &end;
*end_ptr = buf; *end_ptr = buf;
assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) || buffer->assert_glyphs ();
(buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
if (unlikely (hb_object_is_immutable (buffer))) if (unlikely (hb_object_is_immutable (buffer)))
{ {
*end_ptr = buf; if (end_ptr)
*end_ptr = buf;
return false; return false;
} }
@ -460,14 +773,82 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
switch (format) switch (format)
{ {
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_glyphs_text (buffer, return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr, buf, buf_len, end_ptr,
font); font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON: case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_deserialize_glyphs_json (buffer, return _hb_buffer_deserialize_json (buffer,
buf, buf_len, end_ptr, buf, buf_len, end_ptr,
font); font);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
return false;
}
}
/**
* hb_buffer_deserialize_unicode:
* @buffer: an #hb_buffer_t buffer.
* @buf: (array length=buf_len):
* @buf_len:
* @end_ptr: (out):
* @format:
*
*
*
* Return value:
*
* Since: 2.7.3
**/
hb_bool_t
hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
const char *buf,
int buf_len, /* -1 means nul-terminated */
const char **end_ptr, /* May be NULL */
hb_buffer_serialize_format_t format)
{
const char *end;
if (!end_ptr)
end_ptr = &end;
*end_ptr = buf;
buffer->assert_unicode ();
if (unlikely (hb_object_is_immutable (buffer)))
{
if (end_ptr)
*end_ptr = buf;
return false;
}
if (buf_len == -1)
buf_len = strlen (buf);
if (!buf_len)
{
*end_ptr = buf;
return false;
}
hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
hb_font_t* font = hb_font_get_empty ();
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr,
font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_deserialize_json (buffer,
buf, buf_len, end_ptr,
font);
default: default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: case HB_BUFFER_SERIALIZE_FORMAT_INVALID:

View File

@ -50,7 +50,7 @@
* Checks the equality of two #hb_segment_properties_t's. * Checks the equality of two #hb_segment_properties_t's.
* *
* Return value: * Return value:
* %true if all properties of @a equal those of @b, false otherwise. * %true if all properties of @a equal those of @b, %false otherwise.
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -617,8 +617,7 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en
void void
hb_buffer_t::guess_segment_properties () hb_buffer_t::guess_segment_properties ()
{ {
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) || assert_unicode ();
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
/* If script is set to INVALID, guess from buffer contents */ /* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) { if (props.script == HB_SCRIPT_INVALID) {
@ -1404,6 +1403,25 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
return (hb_glyph_position_t *) buffer->pos; return (hb_glyph_position_t *) buffer->pos;
} }
/**
* hb_buffer_has_positions:
* @buffer: an #hb_buffer_t.
*
* Returns whether @buffer has glyph position data.
* A buffer gains position data when hb_buffer_get_glyph_positions() is called on it,
* and cleared of position data when hb_buffer_clear_contents() is called.
*
* Return value:
* %true if the @buffer has position array, %false otherwise.
*
* Since: REPLACEME
**/
HB_EXTERN hb_bool_t
hb_buffer_has_positions (hb_buffer_t *buffer)
{
return buffer->have_positions;
}
/** /**
* hb_glyph_info_get_glyph_flags: * hb_glyph_info_get_glyph_flags:
* @info: a #hb_glyph_info_t. * @info: a #hb_glyph_info_t.
@ -1513,8 +1531,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
typedef typename utf_t::codepoint_t T; typedef typename utf_t::codepoint_t T;
const hb_codepoint_t replacement = buffer->replacement; const hb_codepoint_t replacement = buffer->replacement;
assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) || buffer->assert_unicode ();
(!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
if (unlikely (hb_object_is_immutable (buffer))) if (unlikely (hb_object_is_immutable (buffer)))
return; return;
@ -1834,8 +1851,8 @@ void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer) hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{ {
assert (buffer->have_positions); assert (buffer->have_positions);
assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
(!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID))); buffer->assert_glyphs ();
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);

View File

@ -447,6 +447,9 @@ HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer, hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length); unsigned int *length);
HB_EXTERN hb_bool_t
hb_buffer_has_positions (hb_buffer_t *buffer);
HB_EXTERN void HB_EXTERN void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer); hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
@ -518,6 +521,27 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format, hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags); hb_buffer_serialize_flags_t flags);
HB_EXTERN unsigned int
hb_buffer_serialize_unicode (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
HB_EXTERN unsigned int
hb_buffer_serialize (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
HB_EXTERN hb_bool_t HB_EXTERN hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf, const char *buf,
@ -526,6 +550,14 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_format_t format); hb_buffer_serialize_format_t format);
HB_EXTERN hb_bool_t
hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
const char *buf,
int buf_len,
const char **end_ptr,
hb_buffer_serialize_format_t format);
/* /*
* Compare buffers * Compare buffers

View File

@ -35,20 +35,20 @@
#ifndef HB_BUFFER_MAX_LEN_FACTOR #ifndef HB_BUFFER_MAX_LEN_FACTOR
#define HB_BUFFER_MAX_LEN_FACTOR 32 #define HB_BUFFER_MAX_LEN_FACTOR 64
#endif #endif
#ifndef HB_BUFFER_MAX_LEN_MIN #ifndef HB_BUFFER_MAX_LEN_MIN
#define HB_BUFFER_MAX_LEN_MIN 8192 #define HB_BUFFER_MAX_LEN_MIN 16384
#endif #endif
#ifndef HB_BUFFER_MAX_LEN_DEFAULT #ifndef HB_BUFFER_MAX_LEN_DEFAULT
#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
#endif #endif
#ifndef HB_BUFFER_MAX_OPS_FACTOR #ifndef HB_BUFFER_MAX_OPS_FACTOR
#define HB_BUFFER_MAX_OPS_FACTOR 64 #define HB_BUFFER_MAX_OPS_FACTOR 1024
#endif #endif
#ifndef HB_BUFFER_MAX_OPS_MIN #ifndef HB_BUFFER_MAX_OPS_MIN
#define HB_BUFFER_MAX_OPS_MIN 1024 #define HB_BUFFER_MAX_OPS_MIN 16384
#endif #endif
#ifndef HB_BUFFER_MAX_OPS_DEFAULT #ifndef HB_BUFFER_MAX_OPS_DEFAULT
#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
@ -339,6 +339,39 @@ struct hb_buffer_t
bool ensure_inplace (unsigned int size) bool ensure_inplace (unsigned int size)
{ return likely (!size || size < allocated); } { return likely (!size || size < allocated); }
void assert_glyphs ()
{
assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
}
void assert_unicode ()
{
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
}
bool ensure_glyphs ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
{
if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
return false;
assert (len == 0);
content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
}
return true;
}
bool ensure_unicode ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
{
if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
return false;
assert (len == 0);
content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
}
return true;
}
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count); HB_INTERNAL bool shift_forward (unsigned int count);

View File

@ -448,7 +448,12 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC; case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
/* Script variants from https://unicode.org/iso15924/ */ /* Script variants from https://unicode.org/iso15924/ */
case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC;
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC; case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN;
case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN;
case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN;
case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL;
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN; case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN; case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC; case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;

View File

@ -41,8 +41,10 @@
* @short_description: Font face objects * @short_description: Font face objects
* @include: hb.h * @include: hb.h
* *
* Font face is objects represent a single face in a font family. * A font face is an object that represents a single face from within a
* More exactly, a font face represents a single face in a binary font file. * font family.
*
* More precisely, a font face represents a single face in a binary font file.
* Font faces are typically built from a binary blob and a face index. * Font faces are typically built from a binary blob and a face index.
* Font faces are used to create fonts. * Font faces are used to create fonts.
**/ **/
@ -52,7 +54,7 @@
* hb_face_count: * hb_face_count:
* @blob: a blob. * @blob: a blob.
* *
* Get number of faces in a blob. * Fetches the number of faces in a blob.
* *
* Return value: Number of faces in @blob * Return value: Number of faces in @blob
* *
@ -96,13 +98,19 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
/** /**
* hb_face_create_for_tables: * hb_face_create_for_tables:
* @reference_table_func: (closure user_data) (destroy destroy) (scope notified): * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function
* @user_data: * @user_data: A pointer to the user data
* @destroy: * @destroy: (optional): A callback to call when @data is not needed anymore
* *
* Variant of hb_face_create(), built for those cases where it is more
* convenient to provide data for individual tables instead of the whole font
* data. With the caveat that hb_face_get_table_tags() does not currently work
* with faces created this way.
*
* Creates a new face object from the specified @user_data and @reference_table_func,
* with the @destroy callback.
* *
* * Return value: (transfer full): The new face object
* Return value: (transfer full)
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -182,12 +190,15 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
/** /**
* hb_face_create: (Xconstructor) * hb_face_create: (Xconstructor)
* @blob: * @blob: #hb_blob_t to work upon
* @index: * @index: The index of the face within @blob
* *
* Constructs a new face object from the specified blob and
* a face index into that blob. This is used for blobs of
* file formats such as Dfont and TTC that can contain more
* than one face.
* *
* * Return value: (transfer full): The new face object
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -222,9 +233,9 @@ hb_face_create (hb_blob_t *blob,
/** /**
* hb_face_get_empty: * hb_face_get_empty:
* *
* Fetches the singleton empty face object.
* *
* * Return value: (transfer full) The empty face object
* Return value: (transfer full)
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -237,11 +248,11 @@ hb_face_get_empty ()
/** /**
* hb_face_reference: (skip) * hb_face_reference: (skip)
* @face: a face. * @face: A face object
* *
* Increases the reference count on a face object.
* *
* * Return value: The @face object
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -253,9 +264,11 @@ hb_face_reference (hb_face_t *face)
/** /**
* hb_face_destroy: (skip) * hb_face_destroy: (skip)
* @face: a face. * @face: A face object
* *
* * Decreases the reference count on a face object. When the
* reference count reaches zero, the face is destroyed,
* freeing all memory.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -283,15 +296,15 @@ hb_face_destroy (hb_face_t *face)
/** /**
* hb_face_set_user_data: (skip) * hb_face_set_user_data: (skip)
* @face: a face. * @face: A face object
* @key: * @key: The user-data key to set
* @data: * @data: A pointer to the user data
* @destroy: * @destroy: (optional): A callback to call when @data is not needed anymore
* @replace: * @replace: Whether to replace an existing data with the same key
* *
* Attaches a user-data key/data pair to the given face object.
* *
* * Return value: %true if success, false otherwise
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -307,12 +320,13 @@ hb_face_set_user_data (hb_face_t *face,
/** /**
* hb_face_get_user_data: (skip) * hb_face_get_user_data: (skip)
* @face: a face. * @face: A face object
* @key: * @key: The user-data key to query
* *
* Fetches the user data associated with the specified key,
* attached to the specified face object.
* *
* * Return value: (transfer none): A pointer to the user data
* Return value: (transfer none):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -325,9 +339,9 @@ hb_face_get_user_data (const hb_face_t *face,
/** /**
* hb_face_make_immutable: * hb_face_make_immutable:
* @face: a face. * @face: A face object
*
* *
* Makes the given face object immutable.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -342,11 +356,11 @@ hb_face_make_immutable (hb_face_t *face)
/** /**
* hb_face_is_immutable: * hb_face_is_immutable:
* @face: a face. * @face: A face object
* *
* Tests whether the given face object is immutable.
* *
* * Return value: True is @face is immutable, false otherwise
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -359,12 +373,13 @@ hb_face_is_immutable (const hb_face_t *face)
/** /**
* hb_face_reference_table: * hb_face_reference_table:
* @face: a face. * @face: A face object
* @tag: * @tag: The #hb_tag_t of the table to query
* *
* Fetches a reference to the specified table within
* the specified face.
* *
* * Return value: (transfer full): A pointer to the @tag table within @face
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -380,11 +395,13 @@ hb_face_reference_table (const hb_face_t *face,
/** /**
* hb_face_reference_blob: * hb_face_reference_blob:
* @face: a face. * @face: A face object
* *
* Fetches a pointer to the binary blob that contains the
* specified face. Returns an empty blob if referencing face data is not
* possible.
* *
* * Return value: (transfer full): A pointer to the blob for @face
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -396,10 +413,13 @@ hb_face_reference_blob (hb_face_t *face)
/** /**
* hb_face_set_index: * hb_face_set_index:
* @face: a face. * @face: A face object
* @index: * @index: The index to assign
* *
* Assigns the specified face-index to @face. Fails if the
* face is immutable.
* *
* <note>Note: face indices within a collection are zero-based.</note>
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -415,11 +435,13 @@ hb_face_set_index (hb_face_t *face,
/** /**
* hb_face_get_index: * hb_face_get_index:
* @face: a face. * @face: A face object
* *
* Fetches the face-index corresponding to the given face.
* *
* <note>Note: face indices within a collection are zero-based.</note>
* *
* Return value: * Return value: The index of @face.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -431,10 +453,10 @@ hb_face_get_index (const hb_face_t *face)
/** /**
* hb_face_set_upem: * hb_face_set_upem:
* @face: a face. * @face: A face object
* @upem: * @upem: The units-per-em value to assign
*
* *
* Sets the units-per-em (upem) for a face object to the specified value.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -450,11 +472,11 @@ hb_face_set_upem (hb_face_t *face,
/** /**
* hb_face_get_upem: * hb_face_get_upem:
* @face: a face. * @face: A face object
* *
* Fetches the units-per-em (upem) value of the specified face object.
* *
* * Return value: The upem value of @face
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -466,10 +488,10 @@ hb_face_get_upem (const hb_face_t *face)
/** /**
* hb_face_set_glyph_count: * hb_face_set_glyph_count:
* @face: a face. * @face: A face object
* @glyph_count: * @glyph_count: The glyph-count value to assign
*
* *
* Sets the glyph count for a face object to the specified value.
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -485,11 +507,11 @@ hb_face_set_glyph_count (hb_face_t *face,
/** /**
* hb_face_get_glyph_count: * hb_face_get_glyph_count:
* @face: a face. * @face: A face object
* *
* Fetches the glyph-count value of the specified face object.
* *
* * Return value: The glyph-count value of @face
* Return value:
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -501,14 +523,16 @@ hb_face_get_glyph_count (const hb_face_t *face)
/** /**
* hb_face_get_table_tags: * hb_face_get_table_tags:
* @face: a face. * @face: A face object
* @start_offset: index of first tag to return. * @start_offset: The index of first table tag to retrieve
* @table_count: input length of @table_tags array, output number of items written. * @table_count: (inout): Input = the maximum number of table tags to return;
* @table_tags: array to write tags into. * Output = the actual number of table tags returned (may be zero)
* @table_tags: (out) (array length=table_count): The array of table tags found
* *
* Retrieves table tags for a face, if possible. * Fetches a list of all table tags for a face, if possible. The list returned will
* begin at the offset provided
* *
* Return value: total number of tables, or 0 if not possible to list. * Return value: Total number of tables, or zero if it is not possible to list
* *
* Since: 1.6.0 * Since: 1.6.0
**/ **/
@ -542,8 +566,11 @@ hb_face_get_table_tags (const hb_face_t *face,
#ifndef HB_NO_FACE_COLLECT_UNICODES #ifndef HB_NO_FACE_COLLECT_UNICODES
/** /**
* hb_face_collect_unicodes: * hb_face_collect_unicodes:
* @face: font face. * @face: A face object
* @out: set to add Unicode characters covered by @face to. * @out: The set to add Unicode characters to
*
* Collects all of the Unicode characters covered by @face and adds
* them to the #hb_set_t set @out.
* *
* Since: 1.9.0 * Since: 1.9.0
*/ */
@ -555,10 +582,11 @@ hb_face_collect_unicodes (hb_face_t *face,
} }
/** /**
* hb_face_collect_variation_selectors: * hb_face_collect_variation_selectors:
* @face: font face. * @face: A face object
* @out: set to add Variation Selector characters covered by @face to. * @out: The set to add Variation Selector characters to
*
* *
* Collects all Unicode "Variation Selector" characters covered by @face and adds
* them to the #hb_set_t set @out.
* *
* Since: 1.9.0 * Since: 1.9.0
*/ */
@ -570,10 +598,12 @@ hb_face_collect_variation_selectors (hb_face_t *face,
} }
/** /**
* hb_face_collect_variation_unicodes: * hb_face_collect_variation_unicodes:
* @face: font face. * @face: A face object
* @out: set to add Unicode characters for @variation_selector covered by @face to. * @variation_selector: The Variation Selector to query
* * @out: The set to add Unicode characters to
* *
* Collects all Unicode characters for @variation_selector covered by @face and adds
* them to the #hb_set_t set @out.
* *
* Since: 1.9.0 * Since: 1.9.0
*/ */
@ -708,6 +738,9 @@ hb_face_builder_create ()
/** /**
* hb_face_builder_add_table: * hb_face_builder_add_table:
* @face: A face object created with hb_face_builder_create()
* @tag: The #hb_tag_t of the table to add
* @blob: The blob containing the table data to add
* *
* Add table for @tag with data provided by @blob to the face. @face must * Add table for @tag with data provided by @blob to the face. @face must
* be created using hb_face_builder_create(). * be created using hb_face_builder_create().

View File

@ -46,6 +46,12 @@ hb_face_count (hb_blob_t *blob);
* hb_face_t * hb_face_t
*/ */
/**
* hb_face_t:
*
* Data type for holding font faces.
*
**/
typedef struct hb_face_t hb_face_t; typedef struct hb_face_t hb_face_t;
HB_EXTERN hb_face_t * HB_EXTERN hb_face_t *

View File

@ -306,6 +306,9 @@ _hb_ot_get_font_funcs ()
/** /**
* hb_ot_font_set_funcs: * hb_ot_font_set_funcs:
* @font: #hb_font_t to work upon
*
* Sets the font functions to use when working with @font.
* *
* Since: 0.9.28 * Since: 0.9.28
**/ **/

View File

@ -379,12 +379,20 @@ struct Axis
const BaseCoord **coord) const const BaseCoord **coord) const
{ {
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
if (!base_script.has_data ()) return false; if (!base_script.has_data ())
{
*coord = nullptr;
return false;
}
if (likely (coord)) if (likely (coord))
{ {
unsigned int tag_index = 0; unsigned int tag_index = 0;
(this+baseTagList).bfind (baseline_tag, &tag_index); if (!(this+baseTagList).bfind (baseline_tag, &tag_index))
{
*coord = nullptr;
return false;
}
*coord = &base_script.get_base_coord (tag_index); *coord = &base_script.get_base_coord (tag_index);
} }
@ -398,7 +406,11 @@ struct Axis
const BaseCoord **max_coord) const const BaseCoord **max_coord) const
{ {
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
if (!base_script.has_data ()) return false; if (!base_script.has_data ())
{
*min_coord = *max_coord = nullptr;
return false;
}
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord); base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);

View File

@ -76,7 +76,7 @@
* Tests whether a face includes any kerning data in the 'kern' table. * Tests whether a face includes any kerning data in the 'kern' table.
* Does NOT test for kerning lookups in the GPOS table. * Does NOT test for kerning lookups in the GPOS table.
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
**/ **/
bool bool
@ -92,7 +92,7 @@ hb_ot_layout_has_kerning (hb_face_t *face)
* Tests whether a face includes any state-machine kerning in the 'kern' table. * Tests whether a face includes any state-machine kerning in the 'kern' table.
* Does NOT examine the GPOS table. * Does NOT examine the GPOS table.
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
**/ **/
bool bool
@ -112,7 +112,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
* *
* Does NOT examine the GPOS table. * Does NOT examine the GPOS table.
* *
* Return value: true is data found, false otherwise * Return value: %true is data found, false otherwise
* *
**/ **/
bool bool
@ -268,7 +268,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
* *
* Tests whether a face has any glyph classes defined in its GDEF table. * Tests whether a face has any glyph classes defined in its GDEF table.
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -444,7 +444,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face,
* Fetches the index if a given script tag in the specified face's GSUB table * Fetches the index if a given script tag in the specified face's GSUB table
* or GPOS table. * or GPOS table.
* *
* Return value: true if the script is found, false otherwise * Return value: %true if the script is found, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -598,7 +598,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face,
* Fetches the index for a given feature tag in the specified face's GSUB table * Fetches the index for a given feature tag in the specified face's GSUB table
* or GPOS table. * or GPOS table.
* *
* Return value: true if the feature is found, false otherwise * Return value: %true if the feature is found, false otherwise
**/ **/
bool bool
hb_ot_layout_table_find_feature (hb_face_t *face, hb_ot_layout_table_find_feature (hb_face_t *face,
@ -663,7 +663,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table * Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script tag. * or GPOS table, underneath the specified script tag.
* *
* Return value: true if the language tag is found, false otherwise * Return value: %true if the language tag is found, false otherwise
* *
* Since: ?? * Since: ??
* Deprecated: ?? * Deprecated: ??
@ -697,7 +697,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table * Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script index. * or GPOS table, underneath the specified script index.
* *
* Return value: true if the language tag is found, false otherwise * Return value: %true if the language tag is found, false otherwise
* *
* Since: 2.0.0 * Since: 2.0.0
**/ **/
@ -739,7 +739,7 @@ hb_ot_layout_script_select_language (hb_face_t *face,
* Fetches the index of a requested feature in the given face's GSUB or GPOS table, * Fetches the index of a requested feature in the given face's GSUB or GPOS table,
* underneath the specified script and language. * underneath the specified script and language.
* *
* Return value: true if the feature is found, false otherwise * Return value: %true if the feature is found, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -770,7 +770,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
* Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
* underneath the specified script and language. * underneath the specified script and language.
* *
* Return value: true if the feature is found, false otherwise * Return value: %true if the feature is found, false otherwise
* *
* Since: 0.9.30 * Since: 0.9.30
**/ **/
@ -877,7 +877,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
* Fetches the index of a given feature tag in the specified face's GSUB table * Fetches the index of a given feature tag in the specified face's GSUB table
* or GPOS table, underneath the specified script and language. * or GPOS table, underneath the specified script and language.
* *
* Return value: true if the feature is found, false otherwise * Return value: %true if the feature is found, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -1196,7 +1196,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
* @glyphs_before: (out): Array of glyphs preceding the substitution range * @glyphs_before: (out): Array of glyphs preceding the substitution range
* @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
* @glyphs_after: (out): Array of glyphs following the substitution range * @glyphs_after: (out): Array of glyphs following the substitution range
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup
* *
* Fetches a list of all glyphs affected by the specified lookup in the * Fetches a list of all glyphs affected by the specified lookup in the
* specified face's GSUB table or GPOS table. * specified face's GSUB table or GPOS table.
@ -1245,7 +1245,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
* @face: #hb_face_t to work upon * @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @coords: The variation coordinates to query * @coords: The variation coordinates to query
* @num_coords: The number of variation coorinates * @num_coords: The number of variation coordinates
* @variations_index: (out): The array of feature variations found for the query * @variations_index: (out): The array of feature variations found for the query
* *
* Fetches a list of feature variations in the specified face's GSUB table * Fetches a list of feature variations in the specified face's GSUB table
@ -1310,7 +1310,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
* *
* Tests whether the specified face includes any GSUB substitutions. * Tests whether the specified face includes any GSUB substitutions.
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -1331,7 +1331,7 @@ hb_ot_layout_has_substitution (hb_face_t *face)
* Tests whether a specified lookup in the specified face would * Tests whether a specified lookup in the specified face would
* trigger a substitution on the given glyph sequence. * trigger a substitution on the given glyph sequence.
* *
* Return value: true if a substitution would be triggered, false otherwise * Return value: %true if a substitution would be triggered, false otherwise
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -1488,7 +1488,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
* hb_ot_layout_has_positioning: * hb_ot_layout_has_positioning:
* @face: #hb_face_t to work upon * @face: #hb_face_t to work upon
* *
* Return value: true if the face has GPOS data, false otherwise * Return value: %true if the face has GPOS data, false otherwise
* *
**/ **/
hb_bool_t hb_bool_t
@ -1561,7 +1561,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
* For more information on this distinction, see the [`size` feature documentation]( * For more information on this distinction, see the [`size` feature documentation](
* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size).
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
* Since: 0.9.10 * Since: 0.9.10
**/ **/
@ -1625,7 +1625,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
* Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
* "Character Variant" ('cvXX') features. * "Character Variant" ('cvXX') features.
* *
* Return value: true if data found, false otherwise * Return value: %true if data found, false otherwise
* *
* Since: 2.0.0 * Since: 2.0.0
**/ **/

View File

@ -37,306 +37,278 @@
#line 39 "hb-ot-shape-complex-use-machine.hh" #line 39 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = { static const unsigned char _use_syllable_machine_trans_keys[] = {
12u, 48u, 1u, 15u, 1u, 1u, 12u, 48u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u,
1u, 15u, 1u, 1u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u,
23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u,
11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u,
26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u,
23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 1u, 15u, 22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u,
4u, 4u, 13u, 13u, 12u, 48u, 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 1u, 5u, 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
50u, 52u, 49u, 52u, 49u, 51u, 0
}; };
static const char _use_syllable_machine_key_spans[] = { static const char _use_syllable_machine_key_spans[] = {
37, 15, 1, 37, 1, 52, 38, 38, 1, 1, 52, 38, 38, 1, 27, 26,
15, 1, 27, 26, 24, 23, 22, 2, 24, 23, 22, 2, 1, 25, 25, 25,
1, 25, 25, 25, 1, 25, 26, 26, 1, 25, 26, 26, 26, 27, 27, 27,
26, 27, 27, 27, 38, 48, 1, 1, 38, 48, 1, 1, 38, 2, 1, 38,
38, 2, 1, 38, 27, 26, 24, 23, 27, 26, 24, 23, 22, 2, 1, 25,
22, 2, 1, 25, 25, 25, 25, 26, 25, 25, 25, 26, 26, 26, 27, 27,
26, 26, 27, 27, 27, 38, 48, 15, 27, 38, 48, 1, 1, 1, 48, 38,
1, 1, 37, 48, 38, 2, 1, 5, 2, 1, 5, 3, 4, 3
3, 4, 3
}; };
static const short _use_syllable_machine_index_offsets[] = { static const short _use_syllable_machine_index_offsets[] = {
0, 38, 54, 56, 94, 96, 149, 188, 0, 2, 4, 57, 96, 135, 137, 165,
227, 243, 245, 273, 300, 325, 349, 372, 192, 217, 241, 264, 267, 269, 295, 321,
375, 377, 403, 429, 455, 457, 483, 510, 347, 349, 375, 402, 429, 456, 484, 512,
537, 564, 592, 620, 648, 687, 736, 738, 540, 579, 628, 630, 632, 671, 674, 676,
740, 779, 782, 784, 823, 851, 878, 903, 715, 743, 770, 795, 819, 842, 845, 847,
927, 950, 953, 955, 981, 1007, 1033, 1059, 873, 899, 925, 951, 978, 1005, 1032, 1060,
1086, 1113, 1140, 1168, 1196, 1224, 1263, 1312, 1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259,
1328, 1330, 1332, 1370, 1419, 1458, 1461, 1463, 1298, 1301, 1303, 1309, 1313, 1318
1469, 1473, 1478
}; };
static const char _use_syllable_machine_indicies[] = { static const char _use_syllable_machine_indicies[] = {
1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 4, 5, 5,
0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 5, 5, 5, 5, 5, 1,
0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 5, 5, 5, 5, 10, 11,
0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 12, 13, 14, 15, 16, 17,
1, 0, 0, 0, 1, 0, 3, 2, 18, 12, 19, 20, 21, 22, 23, 24,
2, 2, 2, 2, 2, 2, 2, 2, 5, 25, 26, 27, 5, 28, 29, 30,
2, 2, 2, 2, 4, 2, 3, 2, 31, 32, 33, 34, 8, 35, 5, 36,
6, 5, 5, 5, 5, 5, 5, 5, 5, 38, 39, 37, 37, 37, 37, 37,
5, 5, 5, 5, 5, 5, 5, 5, 37, 37, 37, 37, 40, 41, 42, 43,
5, 5, 5, 5, 5, 5, 5, 5, 44, 45, 46, 40, 47, 4, 48, 49,
5, 5, 5, 5, 5, 5, 5, 5, 50, 51, 37, 52, 53, 54, 37, 37,
6, 5, 5, 5, 6, 5, 7, 5, 37, 37, 55, 56, 57, 58, 39, 37,
8, 9, 10, 8, 11, 12, 10, 10, 38, 39, 37, 37, 37, 37, 37, 37,
10, 10, 10, 3, 13, 14, 10, 15, 37, 37, 37, 40, 41, 42, 43, 44,
8, 8, 16, 17, 10, 10, 18, 19, 45, 46, 40, 47, 48, 48, 49, 50,
20, 21, 22, 23, 24, 18, 25, 26, 51, 37, 52, 53, 54, 37, 37, 37,
27, 28, 29, 30, 10, 31, 32, 33, 37, 55, 56, 57, 58, 39, 37, 38,
10, 34, 35, 36, 37, 38, 39, 40, 59, 40, 41, 42, 43, 44, 37, 37,
13, 41, 10, 42, 10, 44, 1, 43, 37, 37, 37, 37, 49, 50, 51, 37,
43, 45, 43, 43, 43, 43, 43, 43, 52, 53, 54, 37, 37, 37, 37, 41,
46, 47, 48, 49, 50, 51, 52, 46, 56, 57, 58, 60, 37, 41, 42, 43,
53, 9, 54, 55, 56, 57, 43, 58, 44, 37, 37, 37, 37, 37, 37, 37,
59, 60, 43, 43, 43, 43, 61, 62, 37, 37, 37, 52, 53, 54, 37, 37,
63, 64, 1, 43, 44, 1, 43, 43, 37, 37, 37, 56, 57, 58, 60, 37,
45, 43, 43, 43, 43, 43, 43, 46, 42, 43, 44, 37, 37, 37, 37, 37,
47, 48, 49, 50, 51, 52, 46, 53, 37, 37, 37, 37, 37, 37, 37, 37,
54, 54, 55, 56, 57, 43, 58, 59, 37, 37, 37, 37, 37, 56, 57, 58,
60, 43, 43, 43, 43, 61, 62, 63, 37, 43, 44, 37, 37, 37, 37, 37,
64, 1, 43, 44, 65, 65, 65, 65, 37, 37, 37, 37, 37, 37, 37, 37,
65, 65, 65, 65, 65, 65, 65, 65, 37, 37, 37, 37, 37, 56, 57, 58,
65, 66, 65, 44, 65, 46, 47, 48, 37, 44, 37, 37, 37, 37, 37, 37,
49, 50, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 37, 37, 37,
55, 56, 57, 43, 58, 59, 60, 43, 37, 37, 37, 37, 56, 57, 58, 37,
43, 43, 43, 47, 62, 63, 64, 67, 56, 57, 37, 57, 37, 42, 43, 44,
43, 47, 48, 49, 50, 43, 43, 43, 37, 37, 37, 37, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 43, 58, 37, 37, 52, 53, 54, 37, 37, 37,
59, 60, 43, 43, 43, 43, 43, 62, 37, 37, 56, 57, 58, 60, 37, 42,
63, 64, 67, 43, 48, 49, 50, 43, 43, 44, 37, 37, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 53, 54, 37,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 56, 57, 58, 60,
43, 62, 63, 64, 43, 49, 50, 43, 37, 42, 43, 44, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 43, 43, 54, 37, 37, 37, 37, 37, 56, 57,
43, 62, 63, 64, 43, 50, 43, 43, 58, 60, 37, 62, 61, 42, 43, 44,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 37, 37, 37,
62, 63, 64, 43, 62, 63, 43, 63, 37, 37, 56, 57, 58, 60, 37, 41,
43, 48, 49, 50, 43, 43, 43, 43, 42, 43, 44, 37, 37, 37, 37, 37,
43, 43, 43, 43, 43, 43, 58, 59, 37, 49, 50, 51, 37, 52, 53, 54,
60, 43, 43, 43, 43, 43, 62, 63, 37, 37, 37, 37, 41, 56, 57, 58,
64, 67, 43, 48, 49, 50, 43, 43, 60, 37, 41, 42, 43, 44, 37, 37,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 37, 37, 50, 51, 37,
43, 59, 60, 43, 43, 43, 43, 43, 52, 53, 54, 37, 37, 37, 37, 41,
62, 63, 64, 67, 43, 48, 49, 50, 56, 57, 58, 60, 37, 41, 42, 43,
43, 43, 43, 43, 43, 43, 43, 43, 44, 37, 37, 37, 37, 37, 37, 37,
43, 43, 43, 43, 60, 43, 43, 43, 37, 51, 37, 52, 53, 54, 37, 37,
43, 43, 62, 63, 64, 67, 43, 69, 37, 37, 41, 56, 57, 58, 60, 37,
68, 48, 49, 50, 43, 43, 43, 43, 40, 41, 42, 43, 44, 37, 46, 40,
43, 43, 43, 43, 43, 43, 43, 43, 37, 37, 37, 49, 50, 51, 37, 52,
43, 43, 43, 43, 43, 43, 62, 63, 53, 54, 37, 37, 37, 37, 41, 56,
64, 67, 43, 47, 48, 49, 50, 43, 57, 58, 60, 37, 40, 41, 42, 43,
43, 43, 43, 43, 43, 55, 56, 57, 44, 37, 37, 40, 37, 37, 37, 49,
43, 58, 59, 60, 43, 43, 43, 43, 50, 51, 37, 52, 53, 54, 37, 37,
47, 62, 63, 64, 67, 43, 47, 48, 37, 37, 41, 56, 57, 58, 60, 37,
49, 50, 43, 43, 43, 43, 43, 43, 40, 41, 42, 43, 44, 45, 46, 40,
43, 56, 57, 43, 58, 59, 60, 43, 37, 37, 37, 49, 50, 51, 37, 52,
43, 43, 43, 47, 62, 63, 64, 67, 53, 54, 37, 37, 37, 37, 41, 56,
43, 47, 48, 49, 50, 43, 43, 43, 57, 58, 60, 37, 38, 39, 37, 37,
43, 43, 43, 43, 43, 57, 43, 58, 37, 37, 37, 37, 37, 37, 37, 40,
59, 60, 43, 43, 43, 43, 47, 62, 41, 42, 43, 44, 45, 46, 40, 47,
63, 64, 67, 43, 46, 47, 48, 49, 37, 48, 49, 50, 51, 37, 52, 53,
50, 43, 52, 46, 43, 43, 43, 55, 54, 37, 37, 37, 37, 55, 56, 57,
56, 57, 43, 58, 59, 60, 43, 43, 58, 39, 37, 38, 59, 59, 59, 59,
43, 43, 47, 62, 63, 64, 67, 43, 59, 59, 59, 59, 59, 59, 59, 59,
46, 47, 48, 49, 50, 43, 43, 46, 59, 59, 59, 59, 59, 59, 59, 59,
43, 43, 43, 55, 56, 57, 43, 58, 59, 41, 42, 43, 44, 59, 59, 59,
59, 60, 43, 43, 43, 43, 47, 62, 59, 59, 59, 59, 59, 59, 59, 52,
63, 64, 67, 43, 46, 47, 48, 49, 53, 54, 59, 59, 59, 59, 59, 56,
50, 51, 52, 46, 43, 43, 43, 55, 57, 58, 60, 59, 64, 63, 6, 65,
56, 57, 43, 58, 59, 60, 43, 43, 38, 39, 37, 37, 37, 37, 37, 37,
43, 43, 47, 62, 63, 64, 67, 43, 37, 37, 37, 40, 41, 42, 43, 44,
44, 1, 43, 43, 45, 43, 43, 43, 45, 46, 40, 47, 4, 48, 49, 50,
43, 43, 43, 46, 47, 48, 49, 50, 51, 37, 52, 53, 54, 37, 11, 66,
51, 52, 46, 53, 43, 54, 55, 56, 37, 55, 56, 57, 58, 39, 37, 11,
57, 43, 58, 59, 60, 43, 43, 43, 66, 67, 66, 67, 1, 69, 68, 68,
43, 61, 62, 63, 64, 1, 43, 44, 68, 68, 68, 68, 68, 68, 68, 12,
65, 65, 65, 65, 65, 65, 65, 65, 13, 14, 15, 16, 17, 18, 12, 19,
65, 65, 65, 65, 65, 66, 65, 65, 21, 21, 22, 23, 24, 68, 25, 26,
65, 65, 65, 65, 65, 47, 48, 49, 27, 68, 68, 68, 68, 31, 32, 33,
50, 65, 65, 65, 65, 65, 65, 65, 34, 69, 68, 12, 13, 14, 15, 16,
65, 65, 65, 58, 59, 60, 65, 65, 68, 68, 68, 68, 68, 68, 22, 23,
65, 65, 65, 62, 63, 64, 67, 65, 24, 68, 25, 26, 27, 68, 68, 68,
71, 70, 11, 72, 44, 1, 43, 43, 68, 13, 32, 33, 34, 70, 68, 13,
45, 43, 43, 43, 43, 43, 43, 46, 14, 15, 16, 68, 68, 68, 68, 68,
47, 48, 49, 50, 51, 52, 46, 53, 68, 68, 68, 68, 68, 25, 26, 27,
9, 54, 55, 56, 57, 43, 58, 59, 68, 68, 68, 68, 68, 32, 33, 34,
60, 43, 17, 73, 43, 61, 62, 63, 70, 68, 14, 15, 16, 68, 68, 68,
64, 1, 43, 17, 73, 74, 73, 74, 68, 68, 68, 68, 68, 68, 68, 68,
3, 6, 75, 75, 76, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 32,
75, 75, 75, 18, 19, 20, 21, 22, 33, 34, 68, 15, 16, 68, 68, 68,
23, 24, 18, 25, 27, 27, 28, 29, 68, 68, 68, 68, 68, 68, 68, 68,
30, 75, 31, 32, 33, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 32,
75, 37, 38, 39, 40, 6, 75, 18, 33, 34, 68, 16, 68, 68, 68, 68,
19, 20, 21, 22, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 68,
75, 75, 28, 29, 30, 75, 31, 32, 68, 68, 68, 68, 68, 68, 32, 33,
33, 75, 75, 75, 75, 19, 38, 39, 34, 68, 32, 33, 68, 33, 68, 14,
40, 77, 75, 19, 20, 21, 22, 75, 15, 16, 68, 68, 68, 68, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 25, 26, 27, 68,
75, 31, 32, 33, 75, 75, 75, 75, 68, 68, 68, 68, 32, 33, 34, 70,
75, 38, 39, 40, 77, 75, 20, 21, 68, 14, 15, 16, 68, 68, 68, 68,
22, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 26,
75, 75, 75, 75, 75, 75, 75, 75, 27, 68, 68, 68, 68, 68, 32, 33,
75, 75, 75, 38, 39, 40, 75, 21, 34, 70, 68, 14, 15, 16, 68, 68,
22, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 27, 68, 68, 68, 68, 68,
75, 75, 75, 38, 39, 40, 75, 22, 32, 33, 34, 70, 68, 14, 15, 16,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 68,
75, 75, 38, 39, 40, 75, 38, 39, 68, 68, 32, 33, 34, 70, 68, 13,
75, 39, 75, 20, 21, 22, 75, 75, 14, 15, 16, 68, 68, 68, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 22, 23, 24, 68, 25, 26, 27,
31, 32, 33, 75, 75, 75, 75, 75, 68, 68, 68, 68, 13, 32, 33, 34,
38, 39, 40, 77, 75, 20, 21, 22, 70, 68, 13, 14, 15, 16, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 23, 24, 68,
75, 75, 75, 32, 33, 75, 75, 75, 25, 26, 27, 68, 68, 68, 68, 13,
75, 75, 38, 39, 40, 77, 75, 20, 32, 33, 34, 70, 68, 13, 14, 15,
21, 22, 75, 75, 75, 75, 75, 75, 16, 68, 68, 68, 68, 68, 68, 68,
75, 75, 75, 75, 75, 75, 33, 75, 68, 24, 68, 25, 26, 27, 68, 68,
75, 75, 75, 75, 38, 39, 40, 77, 68, 68, 13, 32, 33, 34, 70, 68,
75, 20, 21, 22, 75, 75, 75, 75, 12, 13, 14, 15, 16, 68, 18, 12,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 22, 23, 24, 68, 25,
75, 75, 75, 75, 75, 75, 38, 39, 26, 27, 68, 68, 68, 68, 13, 32,
40, 77, 75, 19, 20, 21, 22, 75, 33, 34, 70, 68, 12, 13, 14, 15,
75, 75, 75, 75, 75, 28, 29, 30, 16, 68, 68, 12, 68, 68, 68, 22,
75, 31, 32, 33, 75, 75, 75, 75, 23, 24, 68, 25, 26, 27, 68, 68,
19, 38, 39, 40, 77, 75, 19, 20, 68, 68, 13, 32, 33, 34, 70, 68,
21, 22, 75, 75, 75, 75, 75, 75, 12, 13, 14, 15, 16, 17, 18, 12,
75, 29, 30, 75, 31, 32, 33, 75, 68, 68, 68, 22, 23, 24, 68, 25,
75, 75, 75, 19, 38, 39, 40, 77, 26, 27, 68, 68, 68, 68, 13, 32,
75, 19, 20, 21, 22, 75, 75, 75, 33, 34, 70, 68, 1, 69, 68, 68,
75, 75, 75, 75, 75, 30, 75, 31, 68, 68, 68, 68, 68, 68, 68, 12,
32, 33, 75, 75, 75, 75, 19, 38, 13, 14, 15, 16, 17, 18, 12, 19,
39, 40, 77, 75, 18, 19, 20, 21, 68, 21, 22, 23, 24, 68, 25, 26,
22, 75, 24, 18, 75, 75, 75, 28, 27, 68, 68, 68, 68, 31, 32, 33,
29, 30, 75, 31, 32, 33, 75, 75, 34, 69, 68, 1, 68, 68, 68, 68,
75, 75, 19, 38, 39, 40, 77, 75, 68, 68, 68, 68, 68, 68, 68, 68,
18, 19, 20, 21, 22, 75, 75, 18, 68, 68, 68, 68, 68, 68, 68, 68,
75, 75, 75, 28, 29, 30, 75, 31, 68, 13, 14, 15, 16, 68, 68, 68,
32, 33, 75, 75, 75, 75, 19, 38, 68, 68, 68, 68, 68, 68, 68, 25,
39, 40, 77, 75, 18, 19, 20, 21, 26, 27, 68, 68, 68, 68, 68, 32,
22, 23, 24, 18, 75, 75, 75, 28, 33, 34, 70, 68, 1, 71, 72, 68,
29, 30, 75, 31, 32, 33, 75, 75, 9, 68, 4, 68, 68, 68, 4, 68,
75, 75, 19, 38, 39, 40, 77, 75, 68, 68, 68, 68, 1, 69, 9, 68,
3, 6, 75, 75, 76, 75, 75, 75, 68, 68, 68, 68, 68, 68, 68, 12,
75, 75, 75, 18, 19, 20, 21, 22, 13, 14, 15, 16, 17, 18, 12, 19,
23, 24, 18, 25, 75, 27, 28, 29, 20, 21, 22, 23, 24, 68, 25, 26,
30, 75, 31, 32, 33, 75, 75, 75, 27, 68, 28, 29, 68, 31, 32, 33,
75, 37, 38, 39, 40, 6, 75, 3, 34, 69, 68, 1, 69, 68, 68, 68,
75, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 68, 68, 12, 13,
75, 75, 75, 75, 75, 4, 75, 75, 14, 15, 16, 17, 18, 12, 19, 20,
75, 75, 75, 75, 75, 19, 20, 21, 21, 22, 23, 24, 68, 25, 26, 27,
22, 75, 75, 75, 75, 75, 75, 75, 68, 68, 68, 68, 31, 32, 33, 34,
75, 75, 75, 31, 32, 33, 75, 75, 69, 68, 28, 29, 68, 29, 68, 4,
75, 75, 75, 38, 39, 40, 77, 75, 71, 71, 71, 4, 71, 74, 73, 35,
3, 78, 78, 78, 78, 78, 78, 78, 73, 35, 74, 73, 74, 73, 35, 73,
78, 78, 78, 78, 78, 78, 4, 78, 36, 73, 0
79, 75, 14, 75, 6, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 78, 6, 78, 78, 78,
6, 78, 9, 75, 75, 75, 9, 75,
75, 75, 75, 75, 3, 6, 14, 75,
76, 75, 75, 75, 75, 75, 75, 18,
19, 20, 21, 22, 23, 24, 18, 25,
26, 27, 28, 29, 30, 75, 31, 32,
33, 75, 34, 35, 75, 37, 38, 39,
40, 6, 75, 3, 6, 75, 75, 76,
75, 75, 75, 75, 75, 75, 18, 19,
20, 21, 22, 23, 24, 18, 25, 26,
27, 28, 29, 30, 75, 31, 32, 33,
75, 75, 75, 75, 37, 38, 39, 40,
6, 75, 34, 35, 75, 35, 75, 9,
78, 78, 78, 9, 78, 81, 80, 41,
80, 41, 81, 80, 81, 80, 41, 80,
42, 80, 0
}; };
static const char _use_syllable_machine_trans_targs[] = { static const char _use_syllable_machine_trans_targs[] = {
5, 8, 5, 35, 2, 5, 1, 46, 2, 31, 42, 2, 3, 2, 26, 28,
5, 6, 5, 30, 32, 55, 56, 58, 51, 52, 54, 29, 32, 33, 34, 35,
59, 33, 36, 37, 38, 39, 40, 50, 36, 46, 47, 48, 55, 49, 43, 44,
51, 52, 60, 53, 47, 48, 49, 43, 45, 39, 40, 41, 56, 57, 58, 50,
44, 45, 61, 62, 63, 54, 41, 42, 37, 38, 2, 59, 61, 2, 4, 5,
5, 64, 66, 5, 7, 0, 10, 11, 6, 7, 8, 9, 10, 21, 22, 23,
12, 13, 14, 25, 26, 27, 28, 22, 24, 18, 19, 20, 13, 14, 15, 25,
23, 24, 17, 18, 19, 29, 15, 16, 11, 12, 2, 2, 16, 2, 17, 2,
5, 5, 9, 20, 5, 21, 5, 31, 27, 2, 30, 2, 2, 0, 1, 2,
5, 34, 5, 5, 3, 4, 5, 57, 53, 2, 60
5, 65
}; };
static const char _use_syllable_machine_trans_actions[] = { static const char _use_syllable_machine_trans_actions[] = {
1, 0, 2, 3, 0, 4, 0, 5, 1, 2, 2, 5, 0, 6, 0, 0,
8, 5, 9, 0, 5, 10, 0, 10, 0, 0, 2, 0, 2, 2, 0, 0,
3, 0, 5, 5, 0, 0, 0, 5, 0, 2, 2, 2, 2, 2, 2, 2,
5, 5, 3, 3, 5, 5, 5, 5, 2, 2, 2, 2, 0, 0, 0, 2,
5, 5, 0, 0, 0, 3, 0, 0, 0, 0, 7, 0, 0, 8, 0, 0,
11, 0, 0, 12, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 5, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13, 14, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 18, 19, 0, 0, 20, 0, 0, 0, 9, 10, 0, 11, 0, 12,
21, 0 0, 13, 0, 14, 15, 0, 0, 16,
0, 17, 0
}; };
static const char _use_syllable_machine_to_state_actions[] = { static const char _use_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0
}; };
static const char _use_syllable_machine_from_state_actions[] = { static const char _use_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0
}; };
static const short _use_syllable_machine_eof_trans[] = { static const short _use_syllable_machine_eof_trans[] = {
1, 3, 3, 6, 6, 0, 44, 44, 1, 1, 0, 38, 38, 60, 38, 38,
66, 66, 44, 44, 44, 44, 44, 44, 38, 38, 38, 38, 38, 38, 38, 38,
44, 44, 44, 44, 69, 44, 44, 44, 62, 38, 38, 38, 38, 38, 38, 38,
44, 44, 44, 44, 44, 66, 71, 73, 38, 60, 64, 66, 38, 68, 68, 69,
44, 75, 75, 76, 76, 76, 76, 76, 69, 69, 69, 69, 69, 69, 69, 69,
76, 76, 76, 76, 76, 76, 76, 76, 69, 69, 69, 69, 69, 69, 69, 69,
76, 76, 76, 76, 76, 76, 76, 79, 69, 69, 69, 72, 69, 69, 69, 69,
76, 76, 79, 76, 76, 76, 76, 79, 69, 69, 72, 74, 74, 74
81, 81, 81
}; };
static const int use_syllable_machine_start = 5; static const int use_syllable_machine_start = 2;
static const int use_syllable_machine_first_final = 5; static const int use_syllable_machine_first_final = 2;
static const int use_syllable_machine_error = -1; static const int use_syllable_machine_error = -1;
static const int use_syllable_machine_en_main = 5; static const int use_syllable_machine_en_main = 2;
#line 39 "hb-ot-shape-complex-use-machine.rl" #line 39 "hb-ot-shape-complex-use-machine.rl"
#line 166 "hb-ot-shape-complex-use-machine.rl" #line 154 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \ #define found_syllable(syllable_type) \
@ -350,7 +322,7 @@ static const int use_syllable_machine_en_main = 5;
static bool static bool
not_standard_default_ignorable (const hb_glyph_info_t &i) not_standard_default_ignorable (const hb_glyph_info_t &i)
{ return !((i.use_category() == USE_O || i.use_category() == USE_Rsv) && _hb_glyph_info_is_default_ignorable (&i)); } { return !(i.use_category() == USE_O && _hb_glyph_info_is_default_ignorable (&i)); }
static void static void
find_syllables_use (hb_buffer_t *buffer) find_syllables_use (hb_buffer_t *buffer)
@ -359,7 +331,8 @@ find_syllables_use (hb_buffer_t *buffer)
auto p = auto p =
+ hb_iter (info, buffer->len) + hb_iter (info, buffer->len)
| hb_enumerate | hb_enumerate
| hb_filter (not_standard_default_ignorable, hb_second) | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); },
hb_second)
| hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
{ {
if (p.second.use_category() == USE_ZWNJ) if (p.second.use_category() == USE_ZWNJ)
@ -378,7 +351,7 @@ find_syllables_use (hb_buffer_t *buffer)
unsigned int act; unsigned int act;
int cs; int cs;
#line 382 "hb-ot-shape-complex-use-machine.hh" #line 355 "hb-ot-shape-complex-use-machine.hh"
{ {
cs = use_syllable_machine_start; cs = use_syllable_machine_start;
ts = 0; ts = 0;
@ -386,12 +359,12 @@ find_syllables_use (hb_buffer_t *buffer)
act = 0; act = 0;
} }
#line 209 "hb-ot-shape-complex-use-machine.rl" #line 198 "hb-ot-shape-complex-use-machine.rl"
unsigned int syllable_serial = 1; unsigned int syllable_serial = 1;
#line 395 "hb-ot-shape-complex-use-machine.hh" #line 368 "hb-ot-shape-complex-use-machine.hh"
{ {
int _slen; int _slen;
int _trans; int _trans;
@ -401,11 +374,11 @@ find_syllables_use (hb_buffer_t *buffer)
goto _test_eof; goto _test_eof;
_resume: _resume:
switch ( _use_syllable_machine_from_state_actions[cs] ) { switch ( _use_syllable_machine_from_state_actions[cs] ) {
case 7: case 4:
#line 1 "NONE" #line 1 "NONE"
{ts = p;} {ts = p;}
break; break;
#line 409 "hb-ot-shape-complex-use-machine.hh" #line 382 "hb-ot-shape-complex-use-machine.hh"
} }
_keys = _use_syllable_machine_trans_keys + (cs<<1); _keys = _use_syllable_machine_trans_keys + (cs<<1);
@ -423,104 +396,76 @@ _eof_trans:
goto _again; goto _again;
switch ( _use_syllable_machine_trans_actions[_trans] ) { switch ( _use_syllable_machine_trans_actions[_trans] ) {
case 5: case 2:
#line 1 "NONE" #line 1 "NONE"
{te = p+1;} {te = p+1;}
break; break;
case 8: case 5:
#line 153 "hb-ot-shape-complex-use-machine.rl" #line 141 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (independent_cluster); }} {te = p+1;{ found_syllable (independent_cluster); }}
break; break;
case 13: case 9:
#line 156 "hb-ot-shape-complex-use-machine.rl" #line 144 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (standard_cluster); }} {te = p+1;{ found_syllable (standard_cluster); }}
break; break;
case 11: case 7:
#line 161 "hb-ot-shape-complex-use-machine.rl" #line 149 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }} {te = p+1;{ found_syllable (broken_cluster); }}
break; break;
case 9: case 6:
#line 162 "hb-ot-shape-complex-use-machine.rl" #line 150 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (non_cluster); }} {te = p+1;{ found_syllable (non_cluster); }}
break; break;
case 14: case 10:
#line 154 "hb-ot-shape-complex-use-machine.rl" #line 142 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (virama_terminated_cluster); }} {te = p;p--;{ found_syllable (virama_terminated_cluster); }}
break; break;
case 15: case 11:
#line 155 "hb-ot-shape-complex-use-machine.rl" #line 143 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (sakot_terminated_cluster); }} {te = p;p--;{ found_syllable (sakot_terminated_cluster); }}
break; break;
case 12: case 8:
#line 156 "hb-ot-shape-complex-use-machine.rl" #line 144 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }} {te = p;p--;{ found_syllable (standard_cluster); }}
break; break;
case 17: case 13:
#line 157 "hb-ot-shape-complex-use-machine.rl" #line 145 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
break; break;
case 16: case 12:
#line 158 "hb-ot-shape-complex-use-machine.rl" #line 146 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (numeral_cluster); }} {te = p;p--;{ found_syllable (numeral_cluster); }}
break; break;
case 18: case 14:
#line 159 "hb-ot-shape-complex-use-machine.rl" #line 147 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }} {te = p;p--;{ found_syllable (symbol_cluster); }}
break; break;
case 21: case 17:
#line 160 "hb-ot-shape-complex-use-machine.rl" #line 148 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (hieroglyph_cluster); }} {te = p;p--;{ found_syllable (hieroglyph_cluster); }}
break; break;
case 19: case 15:
#line 161 "hb-ot-shape-complex-use-machine.rl" #line 149 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }} {te = p;p--;{ found_syllable (broken_cluster); }}
break; break;
case 20: case 16:
#line 162 "hb-ot-shape-complex-use-machine.rl" #line 150 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (non_cluster); }} {te = p;p--;{ found_syllable (non_cluster); }}
break; break;
case 1: case 1:
#line 156 "hb-ot-shape-complex-use-machine.rl" #line 149 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (standard_cluster); }}
break;
case 4:
#line 161 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }} {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break; break;
case 2: #line 460 "hb-ot-shape-complex-use-machine.hh"
#line 1 "NONE"
{ switch( act ) {
case 9:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
case 10:
{{p = ((te))-1;} found_syllable (non_cluster); }
break;
}
}
break;
case 3:
#line 1 "NONE"
{te = p+1;}
#line 161 "hb-ot-shape-complex-use-machine.rl"
{act = 9;}
break;
case 10:
#line 1 "NONE"
{te = p+1;}
#line 162 "hb-ot-shape-complex-use-machine.rl"
{act = 10;}
break;
#line 515 "hb-ot-shape-complex-use-machine.hh"
} }
_again: _again:
switch ( _use_syllable_machine_to_state_actions[cs] ) { switch ( _use_syllable_machine_to_state_actions[cs] ) {
case 6: case 3:
#line 1 "NONE" #line 1 "NONE"
{ts = 0;} {ts = 0;}
break; break;
#line 524 "hb-ot-shape-complex-use-machine.hh" #line 469 "hb-ot-shape-complex-use-machine.hh"
} }
if ( ++p != pe ) if ( ++p != pe )
@ -536,7 +481,7 @@ _again:
} }
#line 214 "hb-ot-shape-complex-use-machine.rl" #line 203 "hb-ot-shape-complex-use-machine.rl"
} }

View File

@ -45,26 +45,15 @@
O = 0; # OTHER O = 0; # OTHER
B = 1; # BASE B = 1; # BASE
IND = 3; # BASE_IND
N = 4; # BASE_NUM N = 4; # BASE_NUM
GB = 5; # BASE_OTHER GB = 5; # BASE_OTHER
#F = 7; # CONS_FINAL
#FM = 8; # CONS_FINAL_MOD
#M = 9; # CONS_MED
#CM = 10; # CONS_MOD
SUB = 11; # CONS_SUB SUB = 11; # CONS_SUB
H = 12; # HALANT H = 12; # HALANT
HN = 13; # HALANT_NUM HN = 13; # HALANT_NUM
ZWNJ = 14; # Zero width non-joiner ZWNJ = 14; # Zero width non-joiner
ZWJ = 15; # Zero width joiner
WJ = 16; # Word joiner
Rsv = 17; # Reserved characters
R = 18; # REPHA R = 18; # REPHA
S = 19; # SYM S = 19; # SYM
#SM = 20; # SYM_MOD
#V = 36; # VOWEL
#VM = 40; # VOWEL_MOD
CS = 43; # CONS_WITH_STACKER CS = 43; # CONS_WITH_STACKER
HVM = 44; # HALANT_OR_VOWEL_MODIFIER HVM = 44; # HALANT_OR_VOWEL_MODIFIER
Sk = 48; # SAKOT Sk = 48; # SAKOT
@ -98,8 +87,7 @@ FMPst = 47; # CONS_FINAL_MOD UIPC = Not_Applicable
h = H | HVM | Sk; h = H | HVM | Sk;
# Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729 consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*;
consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.h.ZWJ? B | SUB) CMAbv? CMBlw*)*;
medial_consonants = MPre? MAbv? MBlw? MPst?; medial_consonants = MPre? MAbv? MBlw? MPst?;
dependent_vowels = VPre* VAbv* VBlw* VPst*; dependent_vowels = VPre* VAbv* VBlw* VPst*;
vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*; vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
@ -126,7 +114,7 @@ symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
virama_terminated_cluster = virama_terminated_cluster =
complex_syllable_start complex_syllable_start
consonant_modifiers consonant_modifiers
ZWJ?.h.ZWJ? h
; ;
sakot_terminated_cluster = sakot_terminated_cluster =
complex_syllable_start complex_syllable_start
@ -146,7 +134,7 @@ number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
numeral_cluster = N numeral_cluster_tail?; numeral_cluster = N numeral_cluster_tail?;
symbol_cluster = (S | GB) symbol_cluster_tail?; symbol_cluster = (S | GB) symbol_cluster_tail?;
hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*; hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
independent_cluster = (IND | O | Rsv | WJ); independent_cluster = O;
other = any; other = any;
main := |* main := |*
@ -176,7 +164,7 @@ main := |*
static bool static bool
not_standard_default_ignorable (const hb_glyph_info_t &i) not_standard_default_ignorable (const hb_glyph_info_t &i)
{ return !((i.use_category() == USE_O || i.use_category() == USE_Rsv) && _hb_glyph_info_is_default_ignorable (&i)); } { return !(i.use_category() == USE_O && _hb_glyph_info_is_default_ignorable (&i)); }
static void static void
find_syllables_use (hb_buffer_t *buffer) find_syllables_use (hb_buffer_t *buffer)
@ -185,7 +173,8 @@ find_syllables_use (hb_buffer_t *buffer)
auto p = auto p =
+ hb_iter (info, buffer->len) + hb_iter (info, buffer->len)
| hb_enumerate | hb_enumerate
| hb_filter (not_standard_default_ignorable, hb_second) | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); },
hb_second)
| hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
{ {
if (p.second.use_category() == USE_ZWNJ) if (p.second.use_category() == USE_ZWNJ)

View File

@ -46,19 +46,15 @@
#define H USE_H /* HALANT */ #define H USE_H /* HALANT */
#define HN USE_HN /* HALANT_NUM */ #define HN USE_HN /* HALANT_NUM */
#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */ #define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */
#define IND USE_IND /* BASE_IND */
#define J USE_J /* HIEROGLYPH_JOINER */ #define J USE_J /* HIEROGLYPH_JOINER */
#define N USE_N /* BASE_NUM */ #define N USE_N /* BASE_NUM */
#define O USE_O /* OTHER */ #define O USE_O /* OTHER */
#define R USE_R /* REPHA */ #define R USE_R /* REPHA */
#define Rsv USE_Rsv /* Reserved */
#define S USE_S /* SYM */ #define S USE_S /* SYM */
#define SB USE_SB /* HIEROGLYPH_SEGMENT_BEGIN */ #define SB USE_SB /* HIEROGLYPH_SEGMENT_BEGIN */
#define SE USE_SE /* HIEROGLYPH_SEGMENT_END */ #define SE USE_SE /* HIEROGLYPH_SEGMENT_END */
#define SUB USE_SUB /* CONS_SUB */ #define SUB USE_SUB /* CONS_SUB */
#define Sk USE_Sk /* SAKOT */ #define Sk USE_Sk /* SAKOT */
#define WJ USE_WJ /* Word_Joiner */
#define ZWJ USE_ZWJ /* ZWJ */
#define ZWNJ USE_ZWNJ /* ZWNJ */ #define ZWNJ USE_ZWNJ /* ZWNJ */
#define CMAbv USE_CMAbv #define CMAbv USE_CMAbv
#define CMBlw USE_CMBlw #define CMBlw USE_CMBlw
@ -148,7 +144,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O, /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, O, /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, O,
@ -188,7 +184,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* Tamil */ /* Tamil */
/* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B, /* 0B80 */ O, O, VMAbv, O, O, B, B, B, B, B, B, O, O, O, B, B,
/* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B, /* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B,
/* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B,
/* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst,
@ -226,9 +222,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst, /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
/* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B, /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, B,
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, /* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Sinhala */ /* Sinhala */
@ -253,8 +249,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, /* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
/* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, /* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
/* 0F70 */ O, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, IND, /* 0F70 */ O, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O,
/* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, IND, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB,
/* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O, /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O,
@ -411,7 +407,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
/* 1CF0 */ O, O, IND, IND, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O, /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
#define use_offset_0x1df8u 3040 #define use_offset_0x1df8u 3040
@ -423,32 +419,31 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* General Punctuation */ /* General Punctuation */
O, O, O, O, ZWNJ, ZWJ, O, O, O, O, O, O, ZWNJ, O, O, O,
/* 2010 */ GB, GB, GB, GB, GB, O, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O,
#define use_offset_0x2060u 3064 #define use_offset_0x2070u 3064
/* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Superscripts and Subscripts */ /* Superscripts and Subscripts */
/* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O, /* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O,
#define use_offset_0x20f0u 3104 #define use_offset_0x20f0u 3088
/* Combining Diacritical Marks for Symbols */ /* Combining Diacritical Marks for Symbols */
/* 20F0 */ VMAbv, O, O, O, O, O, O, O, /* 20F0 */ VMAbv, O, O, O, O, O, O, O,
#define use_offset_0x25c8u 3112 #define use_offset_0x25c8u 3096
/* Geometric Shapes */ /* Geometric Shapes */
O, O, O, O, B, O, O, O, O, O, O, O, B, O, O, O,
#define use_offset_0x2d30u 3120 #define use_offset_0x2d30u 3104
/* Tifinagh */ /* Tifinagh */
@ -459,7 +454,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B, /* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B,
/* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H, /* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H,
#define use_offset_0xa800u 3200 #define use_offset_0xa800u 3184
/* Syloti Nagri */ /* Syloti Nagri */
@ -546,7 +541,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O, /* AAF0 */ O, O, O, O, O, VMPst, H, O,
#define use_offset_0xabc0u 3960 #define use_offset_0xabc0u 3944
/* Meetei Mayek */ /* Meetei Mayek */
@ -556,7 +551,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x10a00u 4024 #define use_offset_0x10a00u 4008
/* Kharoshthi */ /* Kharoshthi */
@ -567,7 +562,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
#define use_offset_0x10ac0u 4104 #define use_offset_0x10ac0u 4088
/* Manichaean */ /* Manichaean */
@ -576,7 +571,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O,
#define use_offset_0x10b80u 4144 #define use_offset_0x10b80u 4128
/* Psalter Pahlavi */ /* Psalter Pahlavi */
@ -585,7 +580,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O, /* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O,
#define use_offset_0x10d00u 4192 #define use_offset_0x10d00u 4176
/* Hanifi Rohingya */ /* Hanifi Rohingya */
@ -595,7 +590,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O, /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O,
/* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x10e80u 4256 #define use_offset_0x10e80u 4240
/* Yezidi */ /* Yezidi */
@ -605,7 +600,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O, /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O,
/* 10EB0 */ B, B, O, O, O, O, O, O, /* 10EB0 */ B, B, O, O, O, O, O, O,
#define use_offset_0x10f30u 4312 #define use_offset_0x10f30u 4296
/* Sogdian */ /* Sogdian */
@ -614,7 +609,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,
/* 10F50 */ VMBlw, B, B, B, B, O, O, O, /* 10F50 */ VMBlw, B, B, B, B, O, O, O,
#define use_offset_0x10fb0u 4352 #define use_offset_0x10fb0u 4336
/* Chorasmian */ /* Chorasmian */
@ -643,7 +638,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11100u 4624 #define use_offset_0x11100u 4608
/* Chakma */ /* Chakma */
@ -681,7 +676,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
#define use_offset_0x11280u 4944 #define use_offset_0x11280u 4928
/* Multani */ /* Multani */
@ -709,7 +704,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
#define use_offset_0x11400u 5192 #define use_offset_0x11400u 5176
/* Newa */ /* Newa */
@ -732,7 +727,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11580u 5416 #define use_offset_0x11580u 5400
/* Siddham */ /* Siddham */
@ -775,7 +770,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VMAbv, O, O, O, O, /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VMAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
#define use_offset_0x11800u 5864 #define use_offset_0x11800u 5848
/* Dogra */ /* Dogra */
@ -785,7 +780,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw,
/* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O, /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11900u 5928 #define use_offset_0x11900u 5912
/* Dives Akuru */ /* Dives Akuru */
@ -797,7 +792,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x119a0u 6024 #define use_offset_0x119a0u 6008
/* Nandinagari */ /* Nandinagari */
@ -825,7 +820,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O, /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O,
#define use_offset_0x11c00u 6280 #define use_offset_0x11c00u 6264
/* Bhaiksuki */ /* Bhaiksuki */
@ -846,7 +841,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
#define use_offset_0x11d00u 6464 #define use_offset_0x11d00u 6448
/* Masaram Gondi */ /* Masaram Gondi */
@ -866,7 +861,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O, /* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O,
/* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11ee0u 6640 #define use_offset_0x11ee0u 6624
/* Makasar */ /* Makasar */
@ -874,7 +869,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O,
#define use_offset_0x13000u 6664 #define use_offset_0x13000u 6648
/* Egyptian Hieroglyphs */ /* Egyptian Hieroglyphs */
@ -951,7 +946,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O, /* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O,
#define use_offset_0x16b00u 7752 #define use_offset_0x16b00u 7736
/* Pahawh Hmong */ /* Pahawh Hmong */
@ -961,7 +956,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O,
#define use_offset_0x16f00u 7808 #define use_offset_0x16f00u 7792
/* Miao */ /* Miao */
@ -971,20 +966,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, CMBlw, /* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, CMBlw,
/* 16F50 */ IND, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, /* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, /* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, /* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw, /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw,
/* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O,
#define use_offset_0x16fe0u 7960 #define use_offset_0x16fe0u 7944
/* Ideographic Symbols and Punctuation */ /* Ideographic Symbols and Punctuation */
/* 16FE0 */ O, O, O, O, B, O, O, O, /* 16FE0 */ O, O, O, O, B, O, O, O,
#define use_offset_0x18b00u 7968 #define use_offset_0x18b00u 7952
/* Khitan Small Script */ /* Khitan Small Script */
@ -1020,7 +1015,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CD0 */ B, B, B, B, B, B, O, O, /* 18CD0 */ B, B, B, B, B, B, O, O,
#define use_offset_0x1bc00u 8440 #define use_offset_0x1bc00u 8424
/* Duployan */ /* Duployan */
@ -1036,7 +1031,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
/* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O, /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O,
#define use_offset_0x1e100u 8600 #define use_offset_0x1e100u 8584
/* Nyiakeng Puachue Hmong */ /* Nyiakeng Puachue Hmong */
@ -1047,7 +1042,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O, /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O,
/* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B, /* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B,
#define use_offset_0x1e2c0u 8680 #define use_offset_0x1e2c0u 8664
/* Wancho */ /* Wancho */
@ -1057,7 +1052,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv,
/* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1e900u 8744 #define use_offset_0x1e900u 8728
/* Adlam */ /* Adlam */
@ -1069,7 +1064,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O, /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O,
/* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
}; /* Table items: 8840; occupancy: 79% */ }; /* Table items: 8824; occupancy: 79% */
USE_TABLE_ELEMENT_TYPE USE_TABLE_ELEMENT_TYPE
hb_use_get_category (hb_codepoint_t u) hb_use_get_category (hb_codepoint_t u)
@ -1097,7 +1092,7 @@ hb_use_get_category (hb_codepoint_t u)
case 0x2u: case 0x2u:
if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u]; if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u];
if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u]; if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u];
if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u]; if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u];
@ -1169,19 +1164,15 @@ hb_use_get_category (hb_codepoint_t u)
#undef H #undef H
#undef HN #undef HN
#undef HVM #undef HVM
#undef IND
#undef J #undef J
#undef N #undef N
#undef O #undef O
#undef R #undef R
#undef Rsv
#undef S #undef S
#undef SB #undef SB
#undef SE #undef SE
#undef SUB #undef SUB
#undef Sk #undef Sk
#undef WJ
#undef ZWJ
#undef ZWNJ #undef ZWNJ
#undef CMAbv #undef CMAbv
#undef CMBlw #undef CMBlw

View File

@ -387,8 +387,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \ #define POST_BASE_FLAGS64 (FLAG64 (USE_FAbv) | \
FLAG64 (USE_FAbv) | \
FLAG64 (USE_FBlw) | \ FLAG64 (USE_FBlw) | \
FLAG64 (USE_FPst) | \ FLAG64 (USE_FPst) | \
FLAG64 (USE_MAbv) | \ FLAG64 (USE_MAbv) | \

View File

@ -46,26 +46,15 @@ enum use_category_t {
USE_O = 0, /* OTHER */ USE_O = 0, /* OTHER */
USE_B = 1, /* BASE */ USE_B = 1, /* BASE */
USE_IND = 3, /* BASE_IND */
USE_N = 4, /* BASE_NUM */ USE_N = 4, /* BASE_NUM */
USE_GB = 5, /* BASE_OTHER */ USE_GB = 5, /* BASE_OTHER */
// USE_F = 7, /* CONS_FINAL */
USE_FM = 8, /* CONS_FINAL_MOD */
// USE_M = 9, /* CONS_MED */
// USE_CM = 10, /* CONS_MOD */
USE_SUB = 11, /* CONS_SUB */ USE_SUB = 11, /* CONS_SUB */
USE_H = 12, /* HALANT */ USE_H = 12, /* HALANT */
USE_HN = 13, /* HALANT_NUM */ USE_HN = 13, /* HALANT_NUM */
USE_ZWNJ = 14, /* Zero width non-joiner */ USE_ZWNJ = 14, /* Zero width non-joiner */
USE_ZWJ = 15, /* Zero width joiner */
USE_WJ = 16, /* Word joiner */
USE_Rsv = 17, /* Reserved characters */
USE_R = 18, /* REPHA */ USE_R = 18, /* REPHA */
USE_S = 19, /* SYM */ USE_S = 19, /* SYM */
// USE_SM = 20, /* SYM_MOD */
// USE_V = 36, /* VOWEL */
// USE_VM = 40, /* VOWEL_MOD */
USE_CS = 43, /* CONS_WITH_STACKER */ USE_CS = 43, /* CONS_WITH_STACKER */
/* https://github.com/harfbuzz/harfbuzz/issues/1102 */ /* https://github.com/harfbuzz/harfbuzz/issues/1102 */

View File

@ -301,7 +301,7 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Don't shift down "above" marks too much. */ /* Don't shift down "above" marks too much. */
if ((y_gap > 0) != (pos.y_offset > 0)) if ((y_gap > 0) != (pos.y_offset > 0))
{ {
unsigned int correction = -pos.y_offset / 2; int correction = -pos.y_offset / 2;
base_extents.y_bearing += correction; base_extents.y_bearing += correction;
base_extents.height -= correction; base_extents.height -= correction;
pos.y_offset += correction; pos.y_offset += correction;

View File

@ -1155,6 +1155,12 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
/** /**
* hb_ot_shape_plan_collect_lookups: * hb_ot_shape_plan_collect_lookups:
* @shape_plan: #hb_shape_plan_t to query
* @table_tag: GSUB or GPOS
* @lookup_indexes: (out): The #hb_set_t set of lookups returned
*
* Computes the complete set of GSUB or GPOS lookups that are applicable
* under a given @shape_plan.
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -1189,6 +1195,15 @@ add_char (hb_font_t *font,
/** /**
* hb_ot_shape_glyphs_closure: * hb_ot_shape_glyphs_closure:
* @font: #hb_font_t to work upon
* @buffer: The input buffer to compute from
* @features: (array length=num_features): The features enabled on the buffer
* @num_features: The number of features enabled on the buffer
* @glyphs: (out): The #hb_set_t set of glyphs comprising the transitive closure of the query
*
* Computes the transitive closure of glyphs needed for a specified
* input buffer under the given font and feature list. The closure is
* computed as a set, not as a list.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/

File diff suppressed because it is too large Load Diff

View File

@ -37,10 +37,17 @@
* @short_description: Object representing a shaping plan * @short_description: Object representing a shaping plan
* @include: hb.h * @include: hb.h
* *
* Shape plans are not used for shaping directly, but can be access to query * Shape plans are an internal mechanism. Each plan contains state
* certain information about how shaping will perform given a set of input * describing how HarfBuzz will shape a particular text segment, based on
* parameters (script, language, direction, features, etc.) * the combination of segment properties and the capabilities in the
* Most client would not need to deal with shape plans directly. * font face in use.
*
* Shape plans are not used for shaping directly, but can be queried to
* access certain information about how shaping will perform, given a set
* of specific input parameters (script, language, direction, features,
* etc.).
*
* Most client programs will not need to deal with shape plans directly.
**/ **/
@ -164,15 +171,16 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
/** /**
* hb_shape_plan_create: (Xconstructor) * hb_shape_plan_create: (Xconstructor)
* @face: * @face: #hb_face_t to use
* @props: * @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): * @user_features: (array length=num_user_features): The list of user-selected features
* @num_user_features: * @num_user_features: The number of user-selected features
* @shaper_list: (array zero-terminated=1): * @shaper_list: (array zero-terminated=1): List of shapers to try
* *
* Constructs a shaping plan for a combination of @face, @user_features, @props,
* and @shaper_list.
* *
* * Return value: (transfer full): The shaping plan
* Return value: (transfer full):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -189,6 +197,24 @@ hb_shape_plan_create (hb_face_t *face,
shaper_list); shaper_list);
} }
/**
* hb_shape_plan_create2: (Xconstructor)
* @face: #hb_face_t to use
* @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): The list of user-selected features
* @num_user_features: The number of user-selected features
* @coords: (array length=num_coords): The list of variation-space coordinates
* @num_coords: The number of variation-space coordinates
* @shaper_list: (array zero-terminated=1): List of shapers to try
*
* The variable-font version of #hb_shape_plan_create.
* Constructs a shaping plan for a combination of @face, @user_features, @props,
* and @shaper_list, plus the variation-space coordinates @coords.
*
* Return value: (transfer full): The shaping plan
*
* Since: 1.4.0
**/
hb_shape_plan_t * hb_shape_plan_t *
hb_shape_plan_create2 (hb_face_t *face, hb_shape_plan_create2 (hb_face_t *face,
const hb_segment_properties_t *props, const hb_segment_properties_t *props,
@ -248,9 +274,9 @@ bail:
/** /**
* hb_shape_plan_get_empty: * hb_shape_plan_get_empty:
* *
* Fetches the singleton empty shaping plan.
* *
* * Return value: (transfer full): The empty shaping plan
* Return value: (transfer full):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -262,11 +288,11 @@ hb_shape_plan_get_empty ()
/** /**
* hb_shape_plan_reference: (skip) * hb_shape_plan_reference: (skip)
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
* *
* Increases the reference count on the given shaping plan.
* *
* * Return value: (transfer full): @shape_plan
* Return value: (transfer full):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -278,9 +304,11 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
/** /**
* hb_shape_plan_destroy: (skip) * hb_shape_plan_destroy: (skip)
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
*
* *
* Decreases the reference count on the given shaping plan. When the
* reference count reaches zero, the shaping plan is destroyed,
* freeing all memory.
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -298,13 +326,13 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
/** /**
* hb_shape_plan_set_user_data: (skip) * hb_shape_plan_set_user_data: (skip)
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
* @key: * @key: The user-data key to set
* @data: * @data: A pointer to the user data
* @destroy: * @destroy: A callback to call when @data is not needed anymore
* @replace: * @replace: Whether to replace an existing data with the same key
*
* *
* Attaches a user-data key/data pair to the given shaping plan.
* *
* Return value: * Return value:
* *
@ -322,12 +350,13 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
/** /**
* hb_shape_plan_get_user_data: (skip) * hb_shape_plan_get_user_data: (skip)
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
* @key: * @key: The user-data key to query
* *
* Fetches the user data associated with the specified key,
* attached to the specified shaping plan.
* *
* * Return value: (transfer none): A pointer to the user data
* Return value: (transfer none):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -340,11 +369,11 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
/** /**
* hb_shape_plan_get_shaper: * hb_shape_plan_get_shaper:
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
* *
* Fetches the shaper from a given shaping plan.
* *
* * Return value: (transfer none): The shaper
* Return value: (transfer none):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -372,7 +401,8 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
return true; return true;
assert (!hb_object_is_immutable (buffer)); assert (!hb_object_is_immutable (buffer));
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
buffer->assert_unicode ();
if (unlikely (hb_object_is_inert (shape_plan))) if (unlikely (hb_object_is_inert (shape_plan)))
return false; return false;
@ -400,15 +430,16 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan,
} }
/** /**
* hb_shape_plan_execute: * hb_shape_plan_execute:
* @shape_plan: a shape plan. * @shape_plan: A shaping plan
* @font: a font. * @font: The #hb_font_t to use
* @buffer: a buffer. * @buffer: The #hb_buffer_t to work upon
* @features: (array length=num_features): * @features: (array length=num_features): Features to enable
* @num_features: * @num_features: The number of features to enable
* *
* Executes the given shaping plan on the specified buffer, using
* the given @font and @features.
* *
* * Return value:
* Return value:
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -435,15 +466,16 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
/** /**
* hb_shape_plan_create_cached: * hb_shape_plan_create_cached:
* @face: * @face: #hb_face_t to use
* @props: * @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): * @user_features: (array length=num_user_features): The list of user-selected features
* @num_user_features: * @num_user_features: The number of user-selected features
* @shaper_list: (array zero-terminated=1): * @shaper_list: (array zero-terminated=1): List of shapers to try
* *
* Creates a cached shaping plan suitable for reuse, for a combination
* of @face, @user_features, @props, and @shaper_list.
* *
* * Return value: (transfer full): The shaping plan
* Return value: (transfer full):
* *
* Since: 0.9.7 * Since: 0.9.7
**/ **/
@ -460,6 +492,25 @@ hb_shape_plan_create_cached (hb_face_t *face,
shaper_list); shaper_list);
} }
/**
* hb_shape_plan_create_cached2:
* @face: #hb_face_t to use
* @props: The #hb_segment_properties_t of the segment
* @user_features: (array length=num_user_features): The list of user-selected features
* @num_user_features: The number of user-selected features
* @coords: (array length=num_coords): The list of variation-space coordinates
* @num_coords: The number of variation-space coordinates
* @shaper_list: (array zero-terminated=1): List of shapers to try
*
* The variable-font version of #hb_shape_plan_create_cached.
* Creates a cached shaping plan suitable for reuse, for a combination
* of @face, @user_features, @props, and @shaper_list, plus the
* variation-space coordinates @coords.
*
* Return value: (transfer full): The shaping plan
*
* Since: 1.4.0
**/
hb_shape_plan_t * hb_shape_plan_t *
hb_shape_plan_create_cached2 (hb_face_t *face, hb_shape_plan_create_cached2 (hb_face_t *face,
const hb_segment_properties_t *props, const hb_segment_properties_t *props,

View File

@ -36,6 +36,20 @@
HB_BEGIN_DECLS HB_BEGIN_DECLS
/**
* hb_shape_plan_t:
*
* Data type for holding a shaping plan.
*
* Shape plans contain information about how HarfBuzz will shape a
* particular text segment, based on the segment's properties and the
* capabilities in the font face in use.
*
* Shape plans can be queried about how shaping will perform, given a set
* of specific input parameters (script, language, direction, features,
* etc.).
*
**/
typedef struct hb_shape_plan_t hb_shape_plan_t; typedef struct hb_shape_plan_t hb_shape_plan_t;
HB_EXTERN hb_shape_plan_t * HB_EXTERN hb_shape_plan_t *

View File

@ -40,11 +40,16 @@
* @include: hb.h * @include: hb.h
* *
* Unicode functions are used to access Unicode character properties. * Unicode functions are used to access Unicode character properties.
* Client can pass its own Unicode functions to HarfBuzz, or access * With these functions, client programs can query various properties from
* the built-in Unicode functions that come with HarfBuzz. * the Unicode Character Database for any code point, such as General
* Category (gc), Script (sc), Canonical Combining Class (ccc), etc.
* *
* With the Unicode functions, one can query variour Unicode character * Client programs can optionally pass in their own Unicode functions
* properties, such as General Category, Script, Combining Class, etc. * that implement the same queries. The set of functions available is
* defined by the virtual methods in #hb_unicode_funcs_t.
*
* HarfBuzz provides built-in default functions for each method in
* #hb_unicode_funcs_t.
**/ **/
@ -133,6 +138,16 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
#include "hb-icu.h" #include "hb-icu.h"
#endif #endif
/**
* hb_unicode_funcs_get_default:
*
* Fetches a pointer to the default Unicode-functions structure that is used
* when no functions are explicitly set on #hb_buffer_t.
*
* Return value: (transfer none): a pointer to the #hb_unicode_funcs_t Unicode-functions structure
*
* Since: 0.9.2
**/
hb_unicode_funcs_t * hb_unicode_funcs_t *
hb_unicode_funcs_get_default () hb_unicode_funcs_get_default ()
{ {
@ -155,11 +170,11 @@ hb_unicode_funcs_get_default ()
/** /**
* hb_unicode_funcs_create: (Xconstructor) * hb_unicode_funcs_create: (Xconstructor)
* @parent: (nullable): * @parent: (nullable): Parent Unicode-functions structure
* *
* Creates a new #hb_unicode_funcs_t structure of Unicode functions.
* *
* * Return value: (transfer full): The Unicode-functions structure
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -203,9 +218,9 @@ DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) =
/** /**
* hb_unicode_funcs_get_empty: * hb_unicode_funcs_get_empty:
* *
* Fetches the singleton empty Unicode-functions structure.
* *
* * Return value: (transfer full): The empty Unicode-functions structure
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -217,11 +232,11 @@ hb_unicode_funcs_get_empty ()
/** /**
* hb_unicode_funcs_reference: (skip) * hb_unicode_funcs_reference: (skip)
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* *
* Increases the reference count on a Unicode-functions structure.
* *
* * Return value: (transfer full): The Unicode-functions structure
* Return value: (transfer full):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -233,9 +248,11 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
/** /**
* hb_unicode_funcs_destroy: (skip) * hb_unicode_funcs_destroy: (skip)
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
*
* *
* Decreases the reference count on a Unicode-functions structure. When
* the reference count reaches zero, the Unicode-functions structure is
* destroyed, freeing all memory.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -256,15 +273,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
/** /**
* hb_unicode_funcs_set_user_data: (skip) * hb_unicode_funcs_set_user_data: (skip)
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* @key: * @key: The user-data key
* @data: * @data: A pointer to the user data
* @destroy: * @destroy: A callback to call when @data is not needed anymore
* @replace: * @replace: Whether to replace an existing data with the same key
* *
* Attaches a user-data key/data pair to the specified Unicode-functions structure.
* *
* * Return value: %true if success, false otherwise
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -280,12 +297,13 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_get_user_data: (skip) * hb_unicode_funcs_get_user_data: (skip)
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* @key: * @key: The user-data key to query
* *
* Fetches the user-data associated with the specified key,
* attached to the specified Unicode-functions structure.
* *
* * Return value: (transfer none): A pointer to the user data
* Return value: (transfer none):
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -299,9 +317,10 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_make_immutable: * hb_unicode_funcs_make_immutable:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
*
* *
* Makes the specified Unicode-functions structure
* immutable.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -316,11 +335,12 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
/** /**
* hb_unicode_funcs_is_immutable: * hb_unicode_funcs_is_immutable:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* *
* Tests whether the specified Unicode-functions structure
* is immutable.
* *
* * Return value: %true if @ufuncs is immutable, false otherwise
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -332,11 +352,12 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
/** /**
* hb_unicode_funcs_get_parent: * hb_unicode_funcs_get_parent:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* *
* Fetches the parent of the Unicode-functions structure
* @ufuncs.
* *
* * Return value: The parent Unicode-functions structure
* Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -389,14 +410,18 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
/** /**
* hb_unicode_compose: * hb_unicode_compose:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* @a: * @a: The first Unicode code point to compose
* @b: * @b: The second Unicode code point to compose
* @ab: (out): * @ab: (out): The composition of @a, @b
* *
* Fetches the composition of a sequence of two Unicode
* code points.
* *
* Calls the composition function of the specified
* Unicode-functions structure @ufuncs.
* *
* Return value: * Return value: %true if @a and @b composed, false otherwise
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -411,14 +436,17 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_decompose: * hb_unicode_decompose:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* @ab: * @ab: Unicode code point to decompose
* @a: (out): * @a: (out): The first code point of the decomposition of @ab
* @b: (out): * @b: (out): The second code point of the decomposition of @ab
* *
* Fetches the decomposition of a Unicode code point.
* *
* Calls the decomposition function of the specified
* Unicode-functions structure @ufuncs.
* *
* Return value: * Return value: %true if @ab was decomposed, false otherwise
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -434,11 +462,12 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
#ifndef HB_DISABLE_DEPRECATED #ifndef HB_DISABLE_DEPRECATED
/** /**
* hb_unicode_decompose_compatibility: * hb_unicode_decompose_compatibility:
* @ufuncs: Unicode functions. * @ufuncs: The Unicode-functions structure
* @u: * @u: Code point to decompose
* @decomposed: (out): * @decomposed: (out): Compatibility decomposition of @u
*
* *
* Fetches the compatibility decomposition of a Unicode
* code point. Deprecated.
* *
* Return value: * Return value:
* *

View File

@ -48,7 +48,42 @@ HB_BEGIN_DECLS
#define HB_UNICODE_MAX 0x10FFFFu #define HB_UNICODE_MAX 0x10FFFFu
/* hb_unicode_general_category_t */ /**
* hb_unicode_general_category_t:
* @HB_UNICODE_GENERAL_CATEGORY_CONTROL: (Cc)
* @HB_UNICODE_GENERAL_CATEGORY_FORMAT: (Cf)
* @HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED: (Cn)
* @HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE: (Co)
* @HB_UNICODE_GENERAL_CATEGORY_SURROGATE: (Cs)
* @HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER: (Ll)
* @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER: (Lm)
* @HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER: (Lo)
* @HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER: (Lt)
* @HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER: (Lu)
* @HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK: (Mc)
* @HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK: (Me)
* @HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK: (Mn)
* @HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER: (Nd)
* @HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER: (Nl)
* @HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER: (No)
* @HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: (Pc)
* @HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: (Pd)
* @HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: (Pe)
* @HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: (Pf)
* @HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: (Pi)
* @HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: (Po)
* @HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: (Ps)
* @HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: (Sc)
* @HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: (Sk)
* @HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: (Sm)
* @HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: (So)
* @HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR: (Zl)
* @HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR: (Zp)
* @HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR: (Zs)
*
* Data type for the "General_Category" (gc) property from
* the Unicode Character Database.
**/
/* Unicode Character Database property: General_Category (gc) */ /* Unicode Character Database property: General_Category (gc) */
typedef enum typedef enum
@ -85,13 +120,72 @@ typedef enum
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */ HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR /* Zs */
} hb_unicode_general_category_t; } hb_unicode_general_category_t;
/* hb_unicode_combining_class_t */ /**
* hb_unicode_combining_class_t:
/* Note: newer versions of Unicode may add new values. Clients should be ready to handle * @HB_UNICODE_COMBINING_CLASS_NOT_REORDERED
* any value in the 0..254 range being returned from hb_unicode_combining_class(). * @HB_UNICODE_COMBINING_CLASS_OVERLAY
*/ * @HB_UNICODE_COMBINING_CLASS_NUKTA
* @HB_UNICODE_COMBINING_CLASS_KANA_VOICING
/* Unicode Character Database property: Canonical_Combining_Class (ccc) */ * @HB_UNICODE_COMBINING_CLASS_VIRAMA
* @HB_UNICODE_COMBINING_CLASS_CCC11: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC12: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC13: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC14: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC15: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC16: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC17: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC18: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC19: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC20: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC21: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC22: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC23: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC24: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC25: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC26: (Hebrew)
* @HB_UNICODE_COMBINING_CLASS_CCC28: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC29: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC30: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC31: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC32: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC33: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC34: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC35: (Arabic)
* @HB_UNICODE_COMBINING_CLASS_CCC36: (Syriac)
* @HB_UNICODE_COMBINING_CLASS_CCC84: (Telugu)
* @HB_UNICODE_COMBINING_CLASS_CCC91: (Telugu)
* @HB_UNICODE_COMBINING_CLASS_CCC103: (Thai)
* @HB_UNICODE_COMBINING_CLASS_CCC107: (Thai)
* @HB_UNICODE_COMBINING_CLASS_CCC118: (Lao)
* @HB_UNICODE_COMBINING_CLASS_CCC122: (Lao)
* @HB_UNICODE_COMBINING_CLASS_CCC129: (Tibetan)
* @HB_UNICODE_COMBINING_CLASS_CCC130: (Tibetan)
* @HB_UNICODE_COMBINING_CLASS_CCC133: (Tibetan)
* @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT
* @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW
* @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE
* @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT
* @HB_UNICODE_COMBINING_CLASS_BELOW_LEFT
* @HB_UNICODE_COMBINING_CLASS_BELOW
* @HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT
* @HB_UNICODE_COMBINING_CLASS_LEFT
* @HB_UNICODE_COMBINING_CLASS_RIGHT
* @HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT
* @HB_UNICODE_COMBINING_CLASS_ABOVE
* @HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT
* @HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW
* @HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE
* @HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT
* @HB_UNICODE_COMBINING_CLASS_INVALID: 255
*
* Data type for the Canonical_Combining_Class (ccc) property
* from the Unicode Character Database.
*
* <note>Note: newer versions of Unicode may add new values.
* Client programs should be ready to handle any value in the 0..254 range
* being returned from hb_unicode_combining_class().</note>
*
**/
typedef enum typedef enum
{ {
HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0, HB_UNICODE_COMBINING_CLASS_NOT_REORDERED = 0,
@ -176,6 +270,18 @@ typedef enum
* hb_unicode_funcs_t * hb_unicode_funcs_t
*/ */
/**
* hb_unicode_funcs_t:
*
* Data type containing a set of virtual methods used for
* accessing various Unicode character properties.
*
* HarfBuzz provides a default function for each of the
* methods in #hb_unicode_funcs_t. Client programs can implement
* their own replacements for the individual Unicode functions, as
* needed, and replace the default by calling the setter for a
* method.
**/
typedef struct hb_unicode_funcs_t hb_unicode_funcs_t; typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
@ -227,40 +333,107 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
/* typedefs */ /* typedefs */
/**
* hb_unicode_combining_class_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should retrieve the Canonical Combining Class (ccc)
* property for a specified Unicode code point.
*
**/
typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); void *user_data);
/**
* hb_unicode_general_category_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should retrieve the General Category property for
* a specified Unicode code point.
*
**/
typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); void *user_data);
/**
* hb_unicode_mirroring_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should retrieve the Bi-Directional Mirroring Glyph
* code point for a specified Unicode code point.
*
* <note>Note: If a code point does not have a specified
* Bi-Directional Mirroring Glyph defined, the method should
* return the original code point.</note>
*
**/
typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_codepoint_t (*hb_unicode_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); void *user_data);
/**
* hb_unicode_script_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should retrieve the Script property for a
* specified Unicode code point.
*
**/
typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); void *user_data);
/**
* hb_unicode_compose_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should compose a sequence of two input Unicode code
* points by canonical equivalence, returning the composed code
* point in a #hb_codepoint_t output parameter (if successful).
* The method must return an #hb_bool_t indicating the success
* of the composition.
*
**/
typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a, hb_codepoint_t a,
hb_codepoint_t b, hb_codepoint_t b,
hb_codepoint_t *ab, hb_codepoint_t *ab,
void *user_data); void *user_data);
/**
* hb_unicode_decompose_func_t:
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* This method should decompose an input Unicode code point,
* returning the two decomposed code points in #hb_codepoint_t
* output parameters (if successful). The method must return an
* #hb_bool_t indicating the success of the composition.
*
**/
typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab, hb_codepoint_t ab,
hb_codepoint_t *a, hb_codepoint_t *a,
hb_codepoint_t *b, hb_codepoint_t *b,
void *user_data); void *user_data);
/* setters */ /* func setters */
/** /**
* hb_unicode_funcs_set_combining_class_func: * hb_unicode_funcs_set_combining_class_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_combining_class_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -271,12 +444,12 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_set_general_category_func: * hb_unicode_funcs_set_general_category_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_general_category_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -287,12 +460,12 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_set_mirroring_func: * hb_unicode_funcs_set_mirroring_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_mirroring_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -303,12 +476,12 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_set_script_func: * hb_unicode_funcs_set_script_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_script_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -319,12 +492,12 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_set_compose_func: * hb_unicode_funcs_set_compose_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_compose_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -335,12 +508,12 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_funcs_set_decompose_func: * hb_unicode_funcs_set_decompose_func:
* @ufuncs: a Unicode function structure * @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: * @user_data: Data to pass to @func
* @destroy: * @destroy: The function to call when @user_data is not needed anymore
*
* *
* Sets the implementation function for #hb_unicode_decompose_func_t.
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -353,6 +526,13 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_combining_class: * hb_unicode_combining_class:
* @ufuncs: The Unicode-functions structure
* @unicode: The code point to query
*
* Retrieves the Canonical Combining Class (ccc) property
* of code point @unicode.
*
* Return value: The #hb_unicode_combining_class_t of @unicode
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -362,6 +542,13 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_general_category: * hb_unicode_general_category:
* @ufuncs: The Unicode-functions structure
* @unicode: The code point to query
*
* Retrieves the General Category (gc) property
* of code point @unicode.
*
* Return value: The #hb_unicode_general_category_t of @unicode
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -371,6 +558,13 @@ hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_mirroring: * hb_unicode_mirroring:
* @ufuncs: The Unicode-functions structure
* @unicode: The code point to query
*
* Retrieves the Bi-directional Mirroring Glyph code
* point defined for code point @unicode.
*
* Return value: The #hb_codepoint_t of the Mirroring Glyph for @unicode
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -380,6 +574,13 @@ hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
/** /**
* hb_unicode_script: * hb_unicode_script:
* @ufuncs: The Unicode-functions structure
* @unicode: The code point to query
*
* Retrieves the #hb_script_t script to which code
* point @unicode belongs.
*
* Return value: The #hb_script_t of @unicode
* *
* Since: 0.9.2 * Since: 0.9.2
**/ **/
@ -387,12 +588,40 @@ HB_EXTERN hb_script_t
hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_unicode_script (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode); hb_codepoint_t unicode);
/**
* hb_unicode_compose:
* @ufuncs: The Unicode-functions structure
* @a: The first code point to compose
* @b: The second code point to compose
* @ab: (out): The composed code point
*
* Composes the code point sequence @a,@b by canonical equivalence into
* code point @ab.
*
* Return value: True is @a,@b composed, false otherwise
*
* Since: 0.9.2
**/
HB_EXTERN hb_bool_t HB_EXTERN hb_bool_t
hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a, hb_codepoint_t a,
hb_codepoint_t b, hb_codepoint_t b,
hb_codepoint_t *ab); hb_codepoint_t *ab);
/**
* hb_unicode_decompose:
* @ufuncs: The Unicode-functions structure
* @ab: The code point to decompose
* @a: (out): The first decomposed code point
* @b: (out): The second decomposed code point
*
* Decomposes code point @ab by canonical equivalence, into code points
* @a and @b.
*
* Return value: True if @ab decomposed, false otherwise
*
* Since: 0.9.2
**/
HB_EXTERN hb_bool_t HB_EXTERN hb_bool_t
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab, hb_codepoint_t ab,

View File

@ -71,7 +71,7 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
case BUFFER_ONE_BY_ONE: case BUFFER_ONE_BY_ONE:
for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++) for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
hb_buffer_add (b, utf32[i], i); hb_buffer_add (b, utf32[i], i);
break; break;
case BUFFER_UTF32: case BUFFER_UTF32:
@ -856,6 +856,75 @@ test_buffer_empty (void)
g_assert (!hb_buffer_allocation_successful (b)); g_assert (!hb_buffer_allocation_successful (b));
} }
typedef struct {
const char *contents;
hb_buffer_serialize_format_t format;
unsigned int num_items;
hb_bool_t success;
} serialization_test_t;
static const serialization_test_t serialization_tests[] = {
{ "<U+0640=0|U+0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 2, 1 },
{ "[{\"u\":1600,\"cl\":0},{\"u\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 2, 1 },
/* Mixed glyphs/Unicodes -> parse fail */
{ "[{\"u\":1600,\"cl\":0},{\"g\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 0, 0 },
{ "<U+0640=0|uni0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 0, 0 },
};
static void
test_buffer_serialize_deserialize (void)
{
hb_buffer_t *b;
unsigned int i;
for (i = 0; i < G_N_ELEMENTS (serialization_tests); i++)
{
unsigned int consumed;
char round_trip[1024];
hb_bool_t retval;
b = hb_buffer_create ();
hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
const serialization_test_t *test = &serialization_tests[i];
g_test_message ("serialize test #%d", i);
retval = hb_buffer_deserialize_unicode (b, test->contents, -1, NULL, test->format);
// Expected parse failure, got one, don't round-trip
if (test->success != 0)
{
unsigned int num_glyphs = hb_buffer_get_length (b);
g_assert_cmpint (num_glyphs, ==, test->num_items);
hb_buffer_serialize_unicode (b, 0, num_glyphs, round_trip,
sizeof(round_trip), &consumed, test->format,
HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
g_assert_cmpstr (round_trip, ==, test->contents);
}
hb_buffer_destroy (b);
}
char test[1024];
unsigned int consumed;
hb_buffer_t *indeterminate = hb_buffer_get_empty ();
hb_buffer_serialize (indeterminate, 0, (unsigned) -1,
test, sizeof(test), &consumed, NULL,
HB_BUFFER_SERIALIZE_FORMAT_JSON,
HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
g_assert_cmpstr ( test, ==, "[]");
hb_buffer_serialize (indeterminate, 0, (unsigned) - 1,
test, sizeof(test), &consumed, NULL,
HB_BUFFER_SERIALIZE_FORMAT_TEXT,
HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
g_assert_cmpstr ( test, ==, "!!");
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -880,6 +949,7 @@ main (int argc, char **argv)
hb_test_add (test_buffer_utf16_conversion); hb_test_add (test_buffer_utf16_conversion);
hb_test_add (test_buffer_utf32_conversion); hb_test_add (test_buffer_utf32_conversion);
hb_test_add (test_buffer_empty); hb_test_add (test_buffer_empty);
hb_test_add (test_buffer_serialize_deserialize);
return hb_test_run(); return hb_test_run();
} }

View File

@ -335,6 +335,8 @@ test_ot_tag_language (void)
test_language_two_way ("FAR", "fa"); test_language_two_way ("FAR", "fa");
test_tag_from_language ("FAR", "fa_IR"); test_tag_from_language ("FAR", "fa_IR");
test_language_two_way ("MNK", "man"); /* Mandingo [macrolanguage] */
test_language_two_way ("SWA", "aii"); /* Swadaya Aramaic */ test_language_two_way ("SWA", "aii"); /* Swadaya Aramaic */
test_language_two_way ("SYR", "syr"); /* Syriac [macrolanguage] */ test_language_two_way ("SYR", "syr"); /* Syriac [macrolanguage] */

View File

@ -31,7 +31,6 @@ endforeach
env = environment() env = environment()
env.set('srcdir', meson.current_source_dir()) env.set('srcdir', meson.current_source_dir())
env.set('HB_TEST_SUBSET_FUZZER_TIMEOUT', '50')
test('shape_fuzzer', find_program('run-shape-fuzzer-tests.py'), test('shape_fuzzer', find_program('run-shape-fuzzer-tests.py'),
args: [ args: [

View File

@ -9,7 +9,7 @@ def cmd (command):
p = subprocess.Popen (command, stderr=tempf) p = subprocess.Popen (command, stderr=tempf)
try: try:
p.wait (timeout=int (os.getenv ("HB_TEST_SHAPE_FUZZER_TIMEOUT", "2"))) p.wait ()
tempf.seek (0) tempf.seek (0)
text = tempf.read () text = tempf.read ()

View File

@ -9,7 +9,7 @@ def cmd (command):
p = subprocess.Popen (command, stderr=tempf) p = subprocess.Popen (command, stderr=tempf)
try: try:
p.wait (timeout=int (os.getenv ("HB_TEST_SHAPE_FUZZER_TIMEOUT", "2"))) p.wait ()
tempf.seek (0) tempf.seek (0)
text = tempf.read () text = tempf.read ()

View File

@ -9,7 +9,7 @@ def cmd (command):
p = subprocess.Popen (command, stderr=tempf) p = subprocess.Popen (command, stderr=tempf)
try: try:
p.wait (timeout=int (os.getenv ("HB_TEST_SUBSET_FUZZER_TIMEOUT", "12"))) p.wait ()
tempf.seek (0) tempf.seek (0)
text = tempf.read () text = tempf.read ()

View File

@ -18,3 +18,5 @@
../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+11442,U+200C,U+034F,U+11411:[Ga=0+576|Virama=0@70,70+0|Gha=4+566] ../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+11442,U+200C,U+034F,U+11411:[Ga=0+576|Virama=0@70,70+0|Gha=4+566]
../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+200C,U+11442,U+034F,U+11411:[Ga.icd=0+367|Gha.diag=1@100,0+386] ../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+200C,U+11442,U+034F,U+11411:[Ga.icd=0+367|Gha.diag=1@100,0+386]
../fonts/e68a88939e0f06e34d2bc911f09b70890289c8fd.ttf::U+AA00,U+200C,U+AA34:[raMedial_cham_pre=0+400|a_cham=0+1121] ../fonts/e68a88939e0f06e34d2bc911f09b70890289c8fd.ttf::U+AA00,U+200C,U+AA34:[raMedial_cham_pre=0+400|a_cham=0+1121]
../fonts/2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf::U+11124,U+200D,U+11127:[u11124=0+514|u11127=0+0]
../fonts/2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf::U+11124,U+2060,U+11127:[u11124=0+514|u11127=1+0]

View File

@ -137,7 +137,7 @@ struct output_buffer_t
g_string_set_size (gs, 0); g_string_set_size (gs, 0);
format.serialize_line_no (line_no, gs); format.serialize_line_no (line_no, gs);
g_string_append_printf (gs, "trace: %s buffer: ", message); g_string_append_printf (gs, "trace: %s buffer: ", message);
format.serialize_glyphs (buffer, font, output_format, format_flags, gs); format.serialize (buffer, font, output_format, format_flags, gs);
g_string_append_c (gs, '\n'); g_string_append_c (gs, '\n');
fprintf (options.fp, "%s", gs->str); fprintf (options.fp, "%s", gs->str);
} }

View File

@ -70,27 +70,27 @@ struct subset_consumer_t
hb_bool_t hb_bool_t
write_file (const char *output_file, hb_blob_t *blob) { write_file (const char *output_file, hb_blob_t *blob) {
unsigned int data_length; unsigned int size;
const char* data = hb_blob_get_data (blob, &data_length); const char* data = hb_blob_get_data (blob, &size);
FILE *fp_out = fopen(output_file, "wb"); if (!output_file)
if (!fp_out) { fail (true, "No output file was specified");
fprintf(stderr, "Unable to open output file\n");
return false;
}
int bytes_written = fwrite(data, 1, data_length, fp_out);
fclose (fp_out); FILE *fp = fopen(output_file, "wb");
if (!fp)
fail (false, "Cannot open output file `%s': %s",
g_filename_display_name (output_file), strerror (errno));
if (bytes_written == -1) { while (size) {
fprintf(stderr, "Unable to write output file\n"); size_t ret = fwrite (data, 1, size, fp);
return false; size -= ret;
} data += ret;
if ((unsigned int) bytes_written != data_length) { if (size && ferror (fp))
fprintf(stderr, "Expected %u bytes written, got %d\n", data_length, fail (false, "Failed to write output: %s", strerror (errno));
bytes_written);
return false;
} }
fclose (fp);
return true; return true;
} }

View File

@ -910,31 +910,12 @@ format_options_t::add_options (option_parser_t *parser)
} }
void void
format_options_t::serialize_unicode (hb_buffer_t *buffer, format_options_t::serialize (hb_buffer_t *buffer,
GString *gs)
{
unsigned int num_glyphs = hb_buffer_get_length (buffer);
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
g_string_append_c (gs, '<');
for (unsigned int i = 0; i < num_glyphs; i++)
{
if (i)
g_string_append_c (gs, ',');
g_string_append_printf (gs, "U+%04X", info->codepoint);
info++;
}
g_string_append_c (gs, '>');
}
void
format_options_t::serialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_format_t output_format, hb_buffer_serialize_format_t output_format,
hb_buffer_serialize_flags_t flags, hb_buffer_serialize_flags_t flags,
GString *gs) GString *gs)
{ {
g_string_append_c (gs, '[');
unsigned int num_glyphs = hb_buffer_get_length (buffer); unsigned int num_glyphs = hb_buffer_get_length (buffer);
unsigned int start = 0; unsigned int start = 0;
@ -942,15 +923,15 @@ format_options_t::serialize_glyphs (hb_buffer_t *buffer,
{ {
char buf[32768]; char buf[32768];
unsigned int consumed; unsigned int consumed;
start += hb_buffer_serialize_glyphs (buffer, start, num_glyphs, start += hb_buffer_serialize (buffer, start, num_glyphs,
buf, sizeof (buf), &consumed, buf, sizeof (buf), &consumed,
font, output_format, flags); font, output_format, flags);
if (!consumed) if (!consumed)
break; break;
g_string_append (gs, buf); g_string_append (gs, buf);
} }
g_string_append_c (gs, ']');
} }
void void
format_options_t::serialize_line_no (unsigned int line_no, format_options_t::serialize_line_no (unsigned int line_no,
GString *gs) GString *gs)
@ -978,7 +959,7 @@ format_options_t::serialize_buffer_of_text (hb_buffer_t *buffer,
if (show_unicode) if (show_unicode)
{ {
serialize_line_no (line_no, gs); serialize_line_no (line_no, gs);
serialize_unicode (buffer, gs); serialize (buffer, font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_DEFAULT, gs);
g_string_append_c (gs, '\n'); g_string_append_c (gs, '\n');
} }
} }
@ -1003,6 +984,6 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer,
GString *gs) GString *gs)
{ {
serialize_line_no (line_no, gs); serialize_line_no (line_no, gs);
serialize_glyphs (buffer, font, output_format, format_flags, gs); serialize (buffer, font, output_format, format_flags, gs);
g_string_append_c (gs, '\n'); g_string_append_c (gs, '\n');
} }

View File

@ -635,9 +635,7 @@ struct format_options_t : option_group_t
void add_options (option_parser_t *parser) override; void add_options (option_parser_t *parser) override;
void serialize_unicode (hb_buffer_t *buffer, void serialize (hb_buffer_t *buffer,
GString *gs);
void serialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font, hb_font_t *font,
hb_buffer_serialize_format_t format, hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags, hb_buffer_serialize_flags_t flags,