update from master

This commit is contained in:
blueshade7 2019-07-08 17:13:29 -07:00
commit 8bf989ea70
191 changed files with 4700 additions and 2405 deletions

View File

@ -82,7 +82,7 @@ jobs:
# - run: xbps-install -Suy freetype gettext gcc glib graphite pkg-config ragel libtool autoconf automake make
# - run: ./autogen.sh && make -j32 && make check
clang-O3-O0:
clang-O3-O0-and-nobuildsystem:
docker:
- image: ubuntu:18.10
steps:
@ -97,6 +97,7 @@ jobs:
- run: CFLAGS="-O0" CXXFLAGS="-O0" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-fontconfig --with-glib --with-cairo --with-icu --with-graphite2
- run: make -j32
- run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh
- run: make clean && cd src && clang++ -c hb-*.cc
gcc-valgrind:
docker:
@ -263,7 +264,7 @@ jobs:
- image: dockcross/android-arm
steps:
- checkout
- run: cmake -Bbuild -H. -GNinja
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
- run: ninja -Cbuild
crosscompile-cmake-notest-browser-asmjs-hb_tiny:
@ -271,7 +272,7 @@ jobs:
- image: dockcross/browser-asmjs
steps:
- checkout
- run: cmake -Bbuild -H. -GNinja -DCMAKE_CXX_FLAGS="-DHB_TINY"
- run: cmake -Bbuild -H. -GNinja -DCMAKE_CXX_FLAGS="-DHB_TINY" -DHB_BUILD_TESTS=OFF
- run: ninja -Cbuild
crosscompile-cmake-notest-linux-arm64:
@ -279,7 +280,7 @@ jobs:
- image: dockcross/linux-arm64
steps:
- checkout
- run: cmake -Bbuild -H. -GNinja
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
- run: ninja -Cbuild
crosscompile-cmake-notest-linux-mips:
@ -287,7 +288,7 @@ jobs:
- image: dockcross/linux-mips
steps:
- checkout
- run: cmake -Bbuild -H. -GNinja
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
- run: ninja -Cbuild
#crosscompile-cmake-notest-windows-x64:
@ -315,7 +316,7 @@ workflows:
- archlinux-py3-all
#- void-notest
- gcc-valgrind
- clang-O3-O0
- clang-O3-O0-and-nobuildsystem
- clang-everything
- clang-asan
- clang-msan

View File

@ -88,8 +88,6 @@ include_directories(AFTER
${PROJECT_BINARY_DIR}/src
)
add_definitions(-DHAVE_FALLBACK)
# We need PYTHON_EXECUTABLE to be set for running the tests...
include (FindPythonInterp)
@ -159,12 +157,8 @@ endfunction ()
file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
extract_make_variable(HB_BASE_sources ${SRCSOURCES})
add_prefix_to_list(HB_BASE_sources "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_BASE_headers ${SRCSOURCES})
add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_FALLBACK_sources ${SRCSOURCES})
add_prefix_to_list(HB_FALLBACK_sources "${PROJECT_SOURCE_DIR}/src/")
extract_make_variable(HB_SUBSET_sources ${SRCSOURCES})
add_prefix_to_list(HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/")
@ -196,61 +190,12 @@ set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
## Define ragel tasks
# if (NOT IN_HB_DIST)
# foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources})
# string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
# set (target_name ${CMAKE_MATCH_1})
# add_custom_command(OUTPUT ${ragel_output}
# COMMAND ${RAGEL} -G2 -o ${ragel_output} ${PROJECT_SOURCE_DIR}/src/${target_name}.rl -I ${PROJECT_SOURCE_DIR} ${ARGN}
# DEPENDS ${PROJECT_SOURCE_DIR}/src/${target_name}.rl
# )
# add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
# endforeach ()
# mark_as_advanced(RAGEL)
# endif ()
## Generate hb-version.h
# if (NOT IN_HB_DIST)
# set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
# set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
# set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
# configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
# execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
# "${HB_VERSION_H}.tmp"
# "${HB_VERSION_H}"
# )
# file(REMOVE "${HB_VERSION_H}.tmp")
# endif ()
## Define sources and headers of the project
set (project_sources
${HB_BASE_sources}
${HB_BASE_RAGEL_GENERATED_sources}
${HB_FALLBACK_sources}
)
set (subset_project_sources
${HB_SUBSET_sources}
)
set (project_sources ${PROJECT_SOURCE_DIR}/src/harfbuzz.cc) # use amalgam source
set (subset_project_sources ${HB_SUBSET_sources})
set (project_extra_sources)
set (project_headers
#${HB_VERSION_H}
${HB_BASE_headers}
)
set (subset_project_headers
${HB_SUBSET_headers}
)
set (project_headers ${HB_BASE_headers})
set (subset_project_headers ${HB_SUBSET_headers})
## Find and include needed header folders and libraries
if (HB_HAVE_FREETYPE)
@ -263,7 +208,6 @@ if (HB_HAVE_FREETYPE)
include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
add_definitions(-DHAVE_FREETYPE=1)
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
# So check_funcs can find its headers
@ -281,7 +225,6 @@ if (HB_HAVE_GRAPHITE2)
include_directories(${GRAPHITE2_INCLUDE_DIR})
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-graphite2.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
@ -302,7 +245,6 @@ if (HB_HAVE_GLIB)
include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-glib.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
@ -322,7 +264,6 @@ if (HB_HAVE_ICU)
include_directories(${ICU_INCLUDE_DIR})
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-icu.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
@ -334,7 +275,6 @@ if (APPLE AND HB_HAVE_CORETEXT)
# Apple Advanced Typography
add_definitions(-DHAVE_CORETEXT)
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
if (HB_IOS)
@ -367,19 +307,13 @@ endif ()
if (WIN32 AND HB_HAVE_UNISCRIBE)
add_definitions(-DHAVE_UNISCRIBE)
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
endif ()
if (WIN32 AND HB_HAVE_DIRECTWRITE)
add_definitions(-DHAVE_DIRECTWRITE)
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-directwrite.cc)
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
endif ()
@ -487,7 +421,6 @@ if (HB_HAVE_GOBJECT)
)
endif ()
## Atomic ops availability detection
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
" void memory_barrier (void) { __sync_synchronize (); }
@ -596,7 +529,6 @@ if (WIN32)
endif ()
if (HB_HAVE_INTROSPECTION)
find_package(PkgConfig)
pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
@ -830,7 +762,7 @@ endif ()
if (HB_BUILD_TESTS)
## src/ executables
foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize test-unicode-ranges) # hb-ot-tag
set (prog_name ${prog})
if (${prog_name} STREQUAL "test")
# test can not be used as a valid executable name on cmake, lets special case it
@ -839,7 +771,7 @@ if (HB_BUILD_TESTS)
add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
endforeach ()
set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
# set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
## Tests
if (UNIX OR MINGW)

151
CONFIG.md Normal file
View File

@ -0,0 +1,151 @@
# Configuring HarfBuzz
Most of the time you will not need any custom configuration. The configuration
options provided by `configure` or `cmake` should be enough. In particular,
if you just want HarfBuzz library plus hb-shape / hb-view utilities, make sure
FreeType and Cairo are available and found during configuration.
If you are building for distribution, you should more carefully consider whether
you need Glib, ICU, Graphite2, as well as CoreText / Uniscribe / DWrite. Make
sure the relevant ones are enabled.
If you are building for custom environment (embedded, downloadable app, etc)
where you mostly just want to call `hb_shape()` and the binary size of the
resulting library is very important to you, the rest of this file guides you
through your options to disable features you may not need, in exchange for
binary size savings.
## Compiler Options
Make sure you build with your compiler's "optimize for size" option. On `gcc`
this is `-Os`, and can be enabled by passing `CXXFLAGS=-Os` either to `configure`
(sticky) or to `make` (non-sticky). On clang there is an even more extreme flag,
`-Oz`.
HarfBuzz heavily uses inline functions and the optimize-size flag can make the
library smaller by 20% or more. Moreover, sometimes, based on the target CPU,
the optimize-size builds perform *faster* as well, thanks to lower code
footprint and caching effects. So, definitely try that even if size is not
extremely tight but you have a huge application. For example, Chrome does
that. Note that this configuration also automatically enables certain internal
optimizations. Search for `HB_OPTIMIZE_SIZE` for details, if you are using
other compilers, or continue reading.
Another compiler option to consider is "link-time optimization", also known as
'lto'. To enable that, with `gcc` or `clang`, add `-flto` to both `CXXFLAGS`
and `LDFLAGS`, either on `configure` invocation (sticky) or on `make` (non-sticky).
This, also, can have a huge impact on the final size, 20% or more.
Finally, if you are making a static library build or otherwise linking the
library into your app, make sure your linker removes unused functions. This
can be tricky and differ from environment to environment, but you definitely
want to make sure this happens. Otherwise, every unused public function will
be adding unneeded bytes to your binary. The following pointers might come
handy:
* https://lwn.net/Articles/741494/ (all of the four-part series)
* https://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf
Combining the above three build options should already shrink your library a lot.
The rest of this file shows you ways to shrink the library even further at the
expense of removing functionality (that may not be needed). The remaining
options are all enabled by defining pre-processor macros, which can be done
via `CXXFLAGS` or `CPPFLAGS` similarly.
## Unicode-functions
Access to Unicode data can be configured at compile time as well as run-time.
By default, HarfBuzz ships with its own compact subset of properties from
Unicode Character Database that it needs. This is a highly-optimized
implementation that depending on compile settings (optimize-size or not)
takes around ~40kb or ~60kb. Using this implementation (default) is highly
recommended, as HarfBuzz always ships with data from latest version of Unicode.
This implementation can be disabled by defining `HB_NO_UCD`.
For example, if you are enabling ICU as a built-in option, or GLib, those
can provide Unicode data as well, so defining `HB_NO_UCD` might save you
space without reducing functionality (to the extent that the Unicode version
of those implementations is recent.)
If, however, you provide your own Unicode data to HarfBuzz at run-time by
calling `hb_buffer_set_unicode_funcs` on every buffer you create, and you do
not rely on `hb_unicode_funcs_get_default()` results, you can disable the
internal implementation by defining both `HB_NO_UCD` and `HB_NO_UNICODE_FUNCS`.
The latter is needed to guard against accidentally building a library without
any default Unicode implementations.
## Font-functions
Access to certain font functionalities can also be configured at run-time. By
default, HarfBuzz uses an efficient internal implementation of OpenType
functionality for this. This internal implementation is called `hb-ot-font`.
All newly-created `hb_font_t` objects by default use `hb-ot-font`. Using this
is highly recommended, and is what fonts use by default when they are created.
Most embedded uses will probably use HarfBuzz with FreeType using `hb-ft.h`.
In that case, or if you otherwise provide those functions by calling
`hb_font_set_funcs()` on every font you create, you can disable `hb-ot-font`
without loss of functionality by defining `HB_NO_OT_FONT`.
## Shapers
Most HarfBuzz clients use it for the main shaper, called "ot". However, it
is legitimate to want to compile HarfBuzz with only another backend, eg.
CoreText, for example for an iOS app. For that, you want `HB_NO_OT_SHAPE`.
If you are going down that route, check if you want `HB_NO_OT`.
This is very rarely what you need. Make sure you understand exactly what you
are doing.
Defining `HB_NO_FALLBACK_SHAPE` however is pretty harmless. That removes the
(unused) "fallback" shaper.
## Thread-safety
By default HarfBuzz builds as a thread-safe library. The exception is that
the `HB_TINY` predefined configuring (more below) disables thread-safety.
If you do /not/ need thread-safety in the library (eg. you always call into
HarfBuzz from the same thread), you can disable thread-safety by defining
`HB_NO_MT`. As noted already, this is enabled by `HB_TINY`.
## Pre-defined configurations
The [`hb-config.hh`](src/hb-config.hh) internal header supports three
pre-defined configurations as well grouping of various configuration options.
The pre-defined configurations are:
* `HB_MINI`: Disables shaping of AAT as well as legacy fonts. Ie. it produces
a capable OpenType shaper only.
* `HB_LEAN`: Disables various non-shaping functionality in the library, as well
as esoteric or rarely-used shaping features. See the definition for details.
* `HB_TINY`: Enables both `HB_MINI` and `HB_LEAN` configurations, as well as
disabling thread-safety and debugging, and use even more size-optimized data
tables.
## Tailoring configuration
Most of the time, one of the pre-defined configuration is exactly what one needs.
Sometimes, however, the pre-defined configuration cuts out features that might
be desired in the library. Unfortunately there is no quick way to undo those
configurations from the command-line. But one can add a header file called
`config-override.h` to undefine certain `HB_NO_*` symbols as desired. Then
define `HAVE_CONFIG_OVERRIDE_H` to make `hb-config.hh` include your configuration
overrides at the end.
## Notes
Note that the config option `HB_NO_CFF`, which is enabled by `HB_LEAN` and
`HB_TINY` does /not/ mean that the resulting library won't work with CFF fonts.
The library can shape valid CFF fonts just fine, with or without this option.
This option disables (among other things) the code to calculate glyph exntents
for CFF fonts.

View File

@ -13,6 +13,7 @@ EXTRA_DIST = \
README.mingw.md \
README.python.md \
BUILD.md \
CONFIG.md \
RELEASING.md \
TESTING.md \
CMakeLists.txt \

19
NEWS
View File

@ -1,3 +1,22 @@
Overview of changes leading to 2.5.3
Wednesday, June 26, 2019
====================================
- Fix UCD script data for Unicode 10+ scripts. This was broken since 2.5.0.
- More optimizations for HB_TINY.
Overview of changes leading to 2.5.2
Thursday, June 20, 2019
====================================
- More hb-config.hh facilities to shrink library size, namely when built as
HB_TINY.
- New documentation of custom configurations in CONFIG.md.
- Fix build on gcc 4.8. That's supported again.
- Universal Shaping Engine improvements thanks to David Corbett.
- API Changes: Undeprecate some horizontal-kerning API and re-enable in hb-ft,
such that Type1 fonts will continue kerning.
Overview of changes leading to 2.5.1
Friday, May 31, 2019
====================================

View File

@ -17,6 +17,8 @@ For license information, see [COPYING](COPYING).
For build information, see [BUILD.md](BUILD.md).
For custom configurations, see [CONFIG.md](CONFIG.md).
For test execution, see [TESTING.md](TESTING.md).
Documentation: https://harfbuzz.github.io

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[2.5.1],
[2.5.3],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
@ -77,7 +77,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
])
# Functions and headers
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign)
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
# Compiler flags
@ -136,14 +136,6 @@ AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread)
dnl ==========================================================================
have_fallback=true
if $have_fallback; then
AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
fi
AM_CONDITIONAL(HAVE_FALLBACK, $have_fallback)
dnl ===========================================================================
AC_ARG_WITH(glib,
[AS_HELP_STRING([--with-glib=@<:@yes/no/auto@:>@],
[Use glib @<:@default=auto@:>@])],,
@ -384,7 +376,7 @@ if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then
fi
if $have_directwrite; then
DIRECTWRITE_CXXFLAGS=
DIRECTWRITE_LIBS="-ldwrite"
DIRECTWRITE_LIBS=
AC_SUBST(DIRECTWRITE_CXXFLAGS)
AC_SUBST(DIRECTWRITE_LIBS)
AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library])

View File

@ -195,12 +195,7 @@ HB_UNICODE_MAX_DECOMPOSITION_LEN
hb_unicode_decompose_compatibility_func_t
hb_unicode_decompose_compatibility
hb_unicode_funcs_set_decompose_compatibility_func
hb_font_funcs_set_glyph_h_kerning_func
hb_font_funcs_set_glyph_v_kerning_func
hb_font_get_glyph_h_kerning
hb_font_get_glyph_h_kerning_func_t
hb_font_get_glyph_kerning_for_direction
hb_font_get_glyph_kerning_func_t
hb_font_get_glyph_v_kerning
hb_font_get_glyph_v_kerning_func_t
</SECTION>
@ -271,6 +266,7 @@ hb_font_funcs_set_glyph_extents_func
hb_font_funcs_set_glyph_from_name_func
hb_font_funcs_set_glyph_h_advance_func
hb_font_funcs_set_glyph_h_advances_func
hb_font_funcs_set_glyph_h_kerning_func
hb_font_funcs_set_glyph_h_origin_func
hb_font_funcs_set_glyph_name_func
hb_font_funcs_set_glyph_v_advance_func
@ -300,8 +296,12 @@ hb_font_get_glyph_h_advance
hb_font_get_glyph_h_advance_func_t
hb_font_get_glyph_h_advances
hb_font_get_glyph_h_advances_func_t
hb_font_get_glyph_h_kerning
hb_font_get_glyph_h_kerning_func_t
hb_font_get_glyph_h_origin
hb_font_get_glyph_h_origin_func_t
hb_font_get_glyph_kerning_for_direction
hb_font_get_glyph_kerning_func_t
hb_font_get_glyph_name
hb_font_get_glyph_name_func_t
hb_font_get_glyph_origin_for_direction

View File

@ -156,14 +156,16 @@
order.
</para>
<para>
For left-to-right scripts (LTR) and top-to-bottom scripts (TTB),
For buffers in the left-to-right (LTR)
or top-to-bottom (TTB) text flow direction,
HarfBuzz will preserve the monotonic property: client programs
are guaranteed that monotonically increasing initial cluster
values will be returned as monotonically increasing final
cluster values.
</para>
<para>
For right-to-left scripts (RTL) and bottom-to-top scripts (BTT),
For buffers in the right-to-left (RTL)
or bottom-to-top (BTT) text flow direction,
the directionality of the buffer itself is reversed for final
output as a matter of design. Therefore, HarfBuzz inverts the
monotonic property: client programs are guaranteed that

View File

@ -86,7 +86,7 @@
objects. <function>hb_font_set_ppem(font, x_ppem,
y_ppem)</function> sets the pixels-per-EM value of the font. You
can also set the point size of the font with
<function>hb_font_set_ppem(font, ptem)</function>. HarfBuzz uses the
<function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
industry standard 72 points per inch.
</para>
<para>

View File

@ -12,9 +12,15 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
TESTS =
check_PROGRAMS =
EXTRA_DIST += harfbuzz.cc
# Convenience targets:
lib: $(BUILT_SOURCES) libharfbuzz.la
libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
tiny:
$(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Os -DHB_TINY $(CPPFLAGS)" libs
tinyz:
$(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Oz -DHB_TINY $(CPPFLAGS)" libs
lib_LTLIBRARIES = libharfbuzz.la
@ -28,10 +34,6 @@ HBSOURCES = $(HB_BASE_sources)
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
HBHEADERS = $(HB_BASE_headers)
if HAVE_FALLBACK
HBSOURCES += $(HB_FALLBACK_sources)
endif
if HAVE_PTHREAD
HBCFLAGS += $(PTHREAD_CFLAGS)
HBNONPCLIBS += $(PTHREAD_LIBS)
@ -253,31 +255,38 @@ GENERATORS = \
$(NULL)
EXTRA_DIST += $(GENERATORS)
unicode-tables: arabic-table indic-table tag-table use-table emoji-table
unicode-tables: \
arabic-table \
emoji-table \
indic-table \
tag-table \
ucd-table \
use-table \
emoji-table \
$(NULL)
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
|| ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
emoji-table: gen-emoji-table.py emoji-data.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
|| ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
|| ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
tag-table: gen-tag-table.py languagetags language-subtag-registry
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
|| ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
ucd-table: gen-ucd-table.py ucd.nounihan.grouped.zip hb-common.h
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ucd-table.hh \
|| ($(RM) $(srcdir)/hb-ucd-table.hh; false)
use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
|| ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
vowel-constraints: gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc \
|| ($(RM) $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc; false)
emoji-table: gen-emoji-table.py emoji-data.txt
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
|| ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
built-sources: $(BUILT_SOURCES)
@ -296,6 +305,21 @@ $(srcdir)/%.hh: $(srcdir)/%.rl
$(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \
|| ($(RM) "$@"; false)
harfbuzz.cc: Makefile.sources
$(AM_V_GEN) \
for f in \
$(HB_BASE_sources) \
$(HB_GLIB_sources) \
$(HB_FT_sources) \
$(HB_GRAPHITE2_sources) \
$(HB_UNISCRIBE_sources) \
$(HB_DIRECTWRITE_sources) \
$(HB_CORETEXT_sources) \
; do echo '#include "'$$f'"'; done | \
grep '[.]cc"' > $(srcdir)/harfbuzz.cc \
|| ($(RM) $(srcdir)/harfbuzz.cc; false)
BUILT_SOURCES += harfbuzz.cc
noinst_PROGRAMS = \
main \
test \
@ -374,7 +398,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
dump_use_data_CPPFLAGS = $(HBCFLAGS)
dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges
COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges test-bimap
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
check_PROGRAMS += $(COMPILED_TESTS)
@ -400,6 +424,10 @@ test_unicode_ranges_SOURCES = test-unicode-ranges.cc
test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
test_bimap_SOURCES = test-bimap.cc hb-static.cc
test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
TESTS_ENVIRONMENT = \
srcdir="$(srcdir)" \
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
@ -428,6 +456,7 @@ HarfBuzz_0_0_gir_CFLAGS = \
-DHB_AAT_H_IN \
-DHB_GOBJECT_H \
-DHB_GOBJECT_H_IN \
-DHAVE_GOBJECT \
-DHB_EXTERN= \
$(NULL)
HarfBuzz_0_0_gir_LIBS = \

View File

@ -36,6 +36,7 @@ HB_BASE_sources = \
hb-dispatch.hh \
hb-face.cc \
hb-face.hh \
hb-fallback-shape.cc \
hb-font.cc \
hb-font.hh \
hb-iter.hh \
@ -64,6 +65,7 @@ HB_BASE_sources = \
hb-ot-color.cc \
hb-ot-face.cc \
hb-ot-face.hh \
hb-ot-face-table-list.hh \
hb-ot-font.cc \
hb-ot-gasp-table.hh \
hb-ot-glyf-table.hh \
@ -203,10 +205,6 @@ HB_BASE_headers = \
hb.h \
$(NULL)
HB_FALLBACK_sources = \
hb-fallback-shape.cc \
$(NULL)
# Optional Sources and Headers with external deps
HB_FT_sources = hb-ft.cc

View File

@ -4,6 +4,7 @@ from __future__ import print_function, division, absolute_import
import sys
import os.path
from collections import OrderedDict
import packTab
if len (sys.argv) != 2:
print("usage: ./gen-emoji-table.py emoji-data.txt", file=sys.stderr)
@ -52,14 +53,19 @@ print ()
print ('#include "hb-unicode.hh"')
print ()
for typ,s in ranges.items():
for typ, s in ranges.items():
if typ != "Extended_Pictographic": continue
arr = dict()
for start,end in s:
for i in range(start,end):
arr[i] = 1
sol = packTab.pack_table(arr, 0, compression=3)
code = packTab.Code('_hb_emoji')
sol.genCode(code, 'is_'+typ)
code.print_c(linkage='static inline')
print()
print("static const struct hb_unicode_range_t _hb_unicode_emoji_%s_table[] =" % typ)
print("{")
for pair in sorted(s):
print(" {0x%04X, 0x%04X}," % pair)
print("};")
print ()
print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */")

View File

@ -98,6 +98,10 @@ for h in headers:
print (" * %s" % (l.strip()))
print (" */")
print ()
print ('#include "hb.hh"')
print ()
print ('#ifndef HB_NO_OT_SHAPE')
print ()
print ('#include "hb-ot-shape-complex-indic.hh"')
print ()
@ -251,6 +255,8 @@ for i in range (2):
print ("#undef %s_%s" %
(what_short[i], short[i][v]))
print ()
print ()
print ('#endif')
print ("/* == End of generated table == */")
# Maintain at least 30% occupancy in the table */

View File

@ -3,19 +3,24 @@
from __future__ import print_function, division, absolute_import
import io, os.path, sys, re
import logging
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
if len (sys.argv) != 2:
print("usage: ./gen-ucd-table ucd.nonunihan.grouped.xml", file=sys.stderr)
if len (sys.argv) not in (2, 3):
print("usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h]", file=sys.stderr)
sys.exit(1)
# https://github.com/harfbuzz/packtab
import packTab
import packTab.ucdxml
logging.info('Loading UCDXML...')
ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)
hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2]
logging.info('Preparing data tables...')
gc = [u['gc'] for u in ucd]
ccc = [int(u['ccc']) for u in ucd]
@ -31,95 +36,129 @@ ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
assert not any(v for v in dm.values() if len(v) not in (1,2))
dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
dm1_u16_array = ['0x%04Xu' % v for v in dm1 if v[0] <= 0xFFFF]
dm1_u32_array = ['0x%04Xu' % v for v in dm1 if v[0] > 0xFFFF]
assert all((v[0] >> 16) in (0,2) for v in dm1)
dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0]
dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2]
dm1_order = {v:i+1 for i,v in enumerate(dm1)}
dm2 = sorted((v, i) for i,v in dm.items() if len(v) == 2)
dm2 = [("HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" %
(v+(i if i not in ce and not ccc[i] else 0,)), v)
for v,i in dm2]
dm2_array = [s for s,v in dm2]
l = 1 + len(dm1_u16_array) + len(dm1_u32_array)
dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v)
for i,v in dm.items() if len(v) == 2)
filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and
(v[1] & 0xFFFFFF80) == 0x0300 and
(v[2] & 0xFFF0C000) == 0x0000)
dm2_u32_array = [v for v in dm2 if filt(v[0])]
dm2_u64_array = [v for v in dm2 if not filt(v[0])]
assert dm2_u32_array + dm2_u64_array == dm2
dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array]
dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array]
l = 1 + len(dm1_p0_array) + len(dm1_p2_array)
dm2_order = {v[1]:i+l for i,v in enumerate(dm2)}
dm_order = {None: 0}
dm_order.update(dm1_order)
dm_order.update(dm2_order)
gc_order = packTab.AutoMapping()
for _ in ('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',):
gc_order[_]
gc_order = dict()
for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)):
gc_order[i] = v
gc_order[v] = i
sc_order = packTab.AutoMapping()
sc_order = dict()
sc_array = []
sc_re = re.compile(" (HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
for line in open('hb-common.h'):
sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
for line in open(hb_common_h):
m = sc_re.search (line)
if not m: continue
name = m.group(1)
tag = ''.join(m.group(i) for i in range(2, 6))
i = sc_order[tag]
assert i == len(sc_array)
i = len(sc_array)
sc_order[tag] = i
sc_order[i] = tag
sc_array.append(name)
# TODO Currently if gc_order or sc_order do not capture all values, we get in
# trouble because they silently add new values. We should be able to "freeze"
# them, or just do the mapping ourselves.
DEFAULT = 1
COMPACT = 3
SLOPPY = 5
logging.info('Generating output...')
print("/* == Start of generated table == */")
print("/*")
print(" * The following table is generated by running:")
print(" *")
print(" * ./gen-ucd-table.py ucd.nonunihan.grouped.xml")
print(" * ./gen-ucd-table.py ucd.nounihan.grouped.xml")
print(" *")
print(" * on file with this description:", ucdxml.description)
print(" */")
print()
print("#ifndef HB_UCD_TABLE_HH")
print("#define HB_UCD_TABLE_HH")
print()
print()
print('#include "hb.hh"')
print()
code = packTab.Code('_hb_ucd')
sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
dm1_16_array, _ = code.addArray('uint16_t', 'dm1_u16_map', dm1_u16_array)
dm1_32_array, _ = code.addArray('uint32_t', 'dm1_u32_map', dm1_u32_array)
dm2_array, _ = code.addArray('uint64_t', 'dm2_map', dm2_array)
dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array)
dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array)
dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array)
dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array)
code.print_c(linkage='static inline')
for compression in (DEFAULT, COMPACT):
datasets = [
('gc', gc, 'Cn', gc_order),
('ccc', ccc, 0, None),
('bmg', bmg, 0, None),
('sc', sc, 'Zzzz', sc_order),
('dm', dm, None, dm_order),
]
for compression in (DEFAULT, COMPACT, SLOPPY):
logging.info(' Compression=%d:' % compression)
print()
if compression == DEFAULT:
print('#ifndef HB_OPTIMIZE_SIZE')
elif compression == COMPACT:
print('#elif !defined(HB_NO_UCD_UNASSIGNED)')
else:
print('#else')
print()
if compression == SLOPPY:
for i in range(len(gc)):
if (i % 128) and gc[i] == 'Cn':
gc[i] = gc[i - 1]
for i in range(len(gc) - 2, -1, -1):
if ((i + 1) % 128) and gc[i] == 'Cn':
gc[i] = gc[i + 1]
for i in range(len(sc)):
if (i % 128) and sc[i] == 'Zzzz':
sc[i] = sc[i - 1]
for i in range(len(sc) - 2, -1, -1):
if ((i + 1) % 128) and sc[i] == 'Zzzz':
sc[i] = sc[i + 1]
code = packTab.Code('_hb_ucd')
packTab.pack_table(gc, 'Cn', mapping=gc_order, compression=compression).genCode(code, 'gc')
packTab.pack_table(ccc, 0, compression=compression).genCode(code, 'ccc')
packTab.pack_table(bmg, 0, compression=compression).genCode(code, 'bmg')
packTab.pack_table(sc, 'Zzzz', mapping=sc_order, compression=compression).genCode(code, 'sc')
packTab.pack_table(dm, None, mapping=dm_order, compression=compression).genCode(code, 'dm')
for name,data,default,mapping in datasets:
sol = packTab.pack_table(data, default, mapping=mapping, compression=compression)
logging.info(' Dataset=%-8s FullCost=%d' % (name, sol.fullCost))
sol.genCode(code, name)
code.print_c(linkage='static inline')
if compression != DEFAULT:
print()
print('#endif')
print()
print('#endif')
print()
print()
print("#endif /* HB_UCD_TABLE_HH */")
print()
print("/* == End of generated table == */")
logging.info('Done.')

View File

@ -419,6 +419,10 @@ for h in headers:
print (" * %s" % (l.strip()))
print (" */")
print ()
print ('#include "hb.hh"')
print ()
print ('#ifndef HB_NO_OT_SHAPE')
print ()
print ('#include "hb-ot-shape-complex-use.hh"')
print ()
@ -533,6 +537,8 @@ for k,v in sorted(use_positions.items()):
tag = k + suf
print ("#undef %s" % tag)
print ()
print ()
print ('#endif')
print ("/* == End of generated table == */")
# Maintain at least 50% occupancy in the table */

View File

@ -157,6 +157,11 @@ print (' *')
for line in scripts_header:
print (' * %s' % line.strip ())
print (' */')
print ()
print ('#include "hb.hh"')
print ()
print ('#ifndef HB_NO_OT_SHAPE')
print ()
print ('#include "hb-ot-shape-complex-vowel-constraints.hh"')
print ()
@ -223,4 +228,6 @@ print (' }')
print ('}')
print ()
print ()
print ('#endif')
print ('/* == End of generated functions == */')

50
src/harfbuzz.cc Normal file
View File

@ -0,0 +1,50 @@
#include "hb-aat-layout.cc"
#include "hb-aat-map.cc"
#include "hb-blob.cc"
#include "hb-buffer-serialize.cc"
#include "hb-buffer.cc"
#include "hb-common.cc"
#include "hb-face.cc"
#include "hb-fallback-shape.cc"
#include "hb-font.cc"
#include "hb-map.cc"
#include "hb-ot-cff1-table.cc"
#include "hb-ot-cff2-table.cc"
#include "hb-ot-color.cc"
#include "hb-ot-face.cc"
#include "hb-ot-font.cc"
#include "hb-ot-layout.cc"
#include "hb-ot-map.cc"
#include "hb-ot-math.cc"
#include "hb-ot-name.cc"
#include "hb-ot-shape-complex-arabic.cc"
#include "hb-ot-shape-complex-default.cc"
#include "hb-ot-shape-complex-hangul.cc"
#include "hb-ot-shape-complex-hebrew.cc"
#include "hb-ot-shape-complex-indic-table.cc"
#include "hb-ot-shape-complex-indic.cc"
#include "hb-ot-shape-complex-khmer.cc"
#include "hb-ot-shape-complex-myanmar.cc"
#include "hb-ot-shape-complex-thai.cc"
#include "hb-ot-shape-complex-use-table.cc"
#include "hb-ot-shape-complex-use.cc"
#include "hb-ot-shape-complex-vowel-constraints.cc"
#include "hb-ot-shape-fallback.cc"
#include "hb-ot-shape-normalize.cc"
#include "hb-ot-shape.cc"
#include "hb-ot-tag.cc"
#include "hb-ot-var.cc"
#include "hb-set.cc"
#include "hb-shape-plan.cc"
#include "hb-shape.cc"
#include "hb-shaper.cc"
#include "hb-static.cc"
#include "hb-ucd.cc"
#include "hb-unicode.cc"
#include "hb-warning.cc"
#include "hb-glib.cc"
#include "hb-ft.cc"
#include "hb-graphite2.cc"
#include "hb-uniscribe.cc"
#include "hb-directwrite.cc"
#include "hb-coretext.cc"

View File

@ -25,9 +25,8 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb-open-type.hh"
#include "hb.hh"
#include "hb-ot-face.hh"
#include "hb-aat-layout.hh"
#include "hb-aat-fdsc-table.hh" // Just so we compile it; unused otherwise.
#include "hb-aat-layout-ankr-table.hh"
@ -40,6 +39,42 @@
#include "hb-aat-ltag-table.hh"
/*
* hb_aat_apply_context_t
*/
/* Note: This context is used for kerning, even without AAT, hence the condition. */
#if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)
AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *blob) :
plan (plan_),
font (font_),
face (font->face),
buffer (buffer_),
sanitizer (),
ankr_table (&Null(AAT::ankr)),
lookup_index (0),
debug_depth (0)
{
sanitizer.init (blob);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
sanitizer.start_processing ();
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
}
AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
{ sanitizer.end_processing (); }
void
AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
{ ankr_table = ankr_table_; }
#endif
/**
* SECTION:hb-aat-layout
* @title: hb-aat-layout
@ -50,6 +85,8 @@
**/
#if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
/* Table data courtesy of Apple. Converted from mnemonics to integers
* when moving to this file. */
static const hb_aat_feature_mapping_t feature_mappings[] =
@ -135,50 +172,16 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{
#ifdef HB_NO_SHAPE_AAT
return nullptr;
#endif
return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag,
feature_mappings,
ARRAY_LENGTH (feature_mappings),
sizeof (feature_mappings[0]),
hb_aat_feature_mapping_t::cmp);
}
#endif
/*
* hb_aat_apply_context_t
*/
/* Note: This context is used for kerning, even without AAT. */
AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *blob) :
plan (plan_),
font (font_),
face (font->face),
buffer (buffer_),
sanitizer (),
ankr_table (&Null(AAT::ankr)),
lookup_index (0),
debug_depth (0)
{
sanitizer.init (blob);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
sanitizer.start_processing ();
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
}
AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
{ sanitizer.end_processing (); }
void
AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
{ ankr_table = ankr_table_; }
#ifndef HB_NO_AAT
/*
* mort/morx/kerx/trak
@ -189,10 +192,6 @@ void
hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::morx& morx = *mapper->face->table.morx;
if (morx.has_data ())
{
@ -219,10 +218,6 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.morx->has_data () ||
face->table.mort->has_data ();
}
@ -232,10 +227,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
if (morx.has_data ())
@ -258,10 +249,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
void
hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
@ -279,10 +266,6 @@ is_deleted_glyph (const hb_glyph_info_t *info)
void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
}
@ -296,10 +279,6 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
hb_bool_t
hb_aat_layout_has_positioning (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.kerx->has_data ();
}
@ -308,10 +287,6 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
@ -331,10 +306,6 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_bool_t
hb_aat_layout_has_tracking (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.trak->has_data ();
}
@ -343,10 +314,6 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::trak& trak = *font->face->table.trak;
AAT::hb_aat_apply_context_t c (plan, font, buffer);
@ -370,12 +337,6 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
unsigned int *feature_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (feature_count)
*feature_count = 0;
return 0;
#endif
return face->table.feat->get_feature_types (start_offset, feature_count, features);
}
@ -392,10 +353,6 @@ hb_ot_name_id_t
hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
hb_aat_layout_feature_type_t feature_type)
{
#ifdef HB_NO_SHAPE_AAT
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.feat->get_feature_name_id (feature_type);
}
@ -424,11 +381,8 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t
hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
unsigned int *default_index /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (selector_count)
*selector_count = 0;
return 0;
#endif
return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
}
#endif

View File

@ -78,12 +78,4 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer);
inline hb_language_t
_hb_aat_language_get (hb_face_t *face,
unsigned int i)
{
return face->table.ltag->get_language (i);
}
#endif /* HB_AAT_LAYOUT_HH */

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_AAT_SHAPE
#include "hb-aat-map.hh"
#include "hb-aat-layout.hh"
@ -34,10 +38,6 @@
void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
unsigned int value)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
if (tag == HB_TAG ('a','a','l','t'))
{
feature_info_t *info = features.push();
@ -57,10 +57,6 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
void
hb_aat_map_builder_t::compile (hb_aat_map_t &m)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
/* Sort features and merge duplicates */
if (features.length)
{
@ -74,3 +70,6 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m)
hb_aat_layout_compile_map (this, &m);
}
#endif

View File

@ -41,35 +41,40 @@
#define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
#define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
/* Custom encoding used by hb-ucd. */
#define HB_CODEPOINT_ENCODE3_11_7_14(x,y,z) (((uint32_t) ((x) & 0x07FFu) << 21) | (((uint32_t) (y) & 0x007Fu) << 14) | (uint32_t) ((z) & 0x3FFFu))
#define HB_CODEPOINT_DECODE3_11_7_14_1(v) ((hb_codepoint_t) ((v) >> 21))
#define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
#define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
struct
{
/* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
template <typename T> auto
template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) )
}
HB_FUNCOBJ (hb_identity);
struct
{
/* Like identity(), but only retains lvalue-references. Rvalues are returned as rvalues. */
template <typename T> T&
template <typename T> constexpr T&
operator () (T& v) const { return v; }
template <typename T> hb_remove_reference<T>
template <typename T> constexpr hb_remove_reference<T>
operator () (T&& v) const { return v; }
}
HB_FUNCOBJ (hb_lidentity);
struct
{
/* Like identity(), but always returns rvalue. */
template <typename T> hb_remove_reference<T>
template <typename T> constexpr hb_remove_reference<T>
operator () (T&& v) const { return v; }
}
HB_FUNCOBJ (hb_ridentity);
struct
{
template <typename T> bool
template <typename T> constexpr bool
operator () (T&& v) const { return bool (hb_forward<T> (v)); }
}
HB_FUNCOBJ (hb_bool);
@ -77,11 +82,11 @@ HB_FUNCOBJ (hb_bool);
struct
{
private:
template <typename T> auto
template <typename T> constexpr auto
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
template <typename T,
hb_enable_if (hb_is_integral (T))> auto
hb_enable_if (hb_is_integral (T))> constexpr auto
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
(
/* Knuth's multiplicative method: */
@ -90,7 +95,7 @@ struct
public:
template <typename T> auto
template <typename T> constexpr auto
operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
}
HB_FUNCOBJ (hb_hash);
@ -323,14 +328,14 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
struct
{
template <typename Pair> typename Pair::first_t
template <typename Pair> constexpr typename Pair::first_t
operator () (const Pair& pair) const { return pair.first; }
}
HB_FUNCOBJ (hb_first);
struct
{
template <typename Pair> typename Pair::second_t
template <typename Pair> constexpr typename Pair::second_t
operator () (const Pair& pair) const { return pair.second; }
}
HB_FUNCOBJ (hb_second);
@ -341,14 +346,14 @@ HB_FUNCOBJ (hb_second);
* comparing integers of different signedness. */
struct
{
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
}
HB_FUNCOBJ (hb_min);
struct
{
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
}
@ -912,7 +917,7 @@ struct hb_bitwise_and
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = false;
static constexpr bool passthru_right = false;
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
}
HB_FUNCOBJ (hb_bitwise_and);
@ -920,7 +925,7 @@ struct hb_bitwise_or
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
}
HB_FUNCOBJ (hb_bitwise_or);
@ -928,7 +933,7 @@ struct hb_bitwise_xor
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
}
HB_FUNCOBJ (hb_bitwise_xor);
@ -936,50 +941,56 @@ struct hb_bitwise_sub
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = false;
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
}
HB_FUNCOBJ (hb_bitwise_sub);
struct
{
template <typename T> constexpr auto
operator () (const T &a) const HB_AUTO_RETURN (~a)
}
HB_FUNCOBJ (hb_bitwise_neg);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
}
HB_FUNCOBJ (hb_add);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
}
HB_FUNCOBJ (hb_sub);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
}
HB_FUNCOBJ (hb_mul);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
}
HB_FUNCOBJ (hb_div);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
template <typename T, typename T2> constexpr auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
}
HB_FUNCOBJ (hb_mod);
struct
{
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a) const HB_AUTO_RETURN (+a)
}
HB_FUNCOBJ (hb_pos);
struct
{
template <typename T> auto
template <typename T> constexpr auto
operator () (const T &a) const HB_AUTO_RETURN (-a)
}
HB_FUNCOBJ (hb_neg);
@ -988,28 +999,29 @@ HB_FUNCOBJ (hb_neg);
/* Compiler-assisted vectorization. */
/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
* using vectorized operations if HB_VECTOR_SIZE is set to **bit** numbers (eg 128).
* Define that to 0 to disable. */
* basically a fixed-size bitset. */
template <typename elt_t, unsigned int byte_size>
struct hb_vector_size_t
{
elt_t& operator [] (unsigned int i) { return u.v[i]; }
const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
elt_t& operator [] (unsigned int i) { return v[i]; }
const elt_t& operator [] (unsigned int i) const { return v[i]; }
void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
template <typename Op>
hb_vector_size_t process (const Op& op) const
{
hb_vector_size_t r;
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
r.v[i] = op (v[i]);
return r;
}
template <typename Op>
hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
{
hb_vector_size_t r;
#if HB_VECTOR_SIZE
if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
r.u.vec[i] = op (u.vec[i], o.u.vec[i]);
else
#endif
for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
r.u.v[i] = op (u.v[i], o.u.v[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
r.v[i] = op (v[i], o.v[i]);
return r;
}
hb_vector_size_t operator | (const hb_vector_size_t &o) const
@ -1019,27 +1031,11 @@ struct hb_vector_size_t
hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
{ return process (hb_bitwise_xor, o); }
hb_vector_size_t operator ~ () const
{
hb_vector_size_t r;
#if HB_VECTOR_SIZE && 0
if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
r.u.vec[i] = ~u.vec[i];
else
#endif
for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
r.u.v[i] = ~u.v[i];
return r;
}
{ return process (hb_bitwise_neg); }
private:
static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
union {
elt_t v[byte_size / sizeof (elt_t)];
#if HB_VECTOR_SIZE
hb_vector_size_impl_t vec[byte_size / sizeof (hb_vector_size_impl_t)];
#endif
} u;
static_assert (0 == byte_size % sizeof (elt_t), "");
elt_t v[byte_size / sizeof (elt_t)];
};

View File

@ -28,11 +28,9 @@
#define HB_BIMAP_HH
#include "hb.hh"
#include "hb-map.hh"
/* Bi-directional map.
* new ids are assigned incrementally & contiguously to old ids
* which may be added randomly & sparsely
* all mappings are 1-to-1 in both directions */
/* Bi-directional map */
struct hb_bimap_t
{
hb_bimap_t () { init (); }
@ -40,70 +38,106 @@ struct hb_bimap_t
void init ()
{
count = 0;
old_to_new.init ();
new_to_old.init ();
forw_map.init ();
back_map.init ();
}
void fini ()
{
old_to_new.fini ();
new_to_old.fini ();
forw_map.fini ();
back_map.fini ();
}
bool has (hb_codepoint_t _old) const { return old_to_new.has (_old); }
hb_codepoint_t add (hb_codepoint_t _old)
void reset ()
{
hb_codepoint_t _new = old_to_new[_old];
if (_new == HB_MAP_VALUE_INVALID)
{
_new = count++;
old_to_new.set (_old, _new);
new_to_old.resize (count);
new_to_old[_new] = _old;
}
return _new;
forw_map.reset ();
back_map.reset ();
}
/* returns HB_MAP_VALUE_INVALID if unmapped */
hb_codepoint_t operator [] (hb_codepoint_t _old) const { return to_new (_old); }
hb_codepoint_t to_new (hb_codepoint_t _old) const { return old_to_new[_old]; }
hb_codepoint_t to_old (hb_codepoint_t _new) const { return (_new >= count)? HB_MAP_VALUE_INVALID: new_to_old[_new]; }
bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
{
if (unlikely (lhs == HB_MAP_VALUE_INVALID)) return;
if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; }
forw_map.set (lhs, rhs);
back_map.set (rhs, lhs);
}
hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); }
void del (hb_codepoint_t lhs)
{
back_map.del (get (lhs));
forw_map.del (lhs);
}
void clear ()
{
forw_map.clear ();
back_map.clear ();
}
bool is_empty () const { return get_population () == 0; }
unsigned int get_population () const { return forw_map.get_population (); }
protected:
hb_map_t forw_map;
hb_map_t back_map;
};
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
struct hb_inc_bimap_t : hb_bimap_t
{
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
* Return the rhs value as the result.
*/
hb_codepoint_t add (hb_codepoint_t lhs)
{
hb_codepoint_t rhs = forw_map[lhs];
if (rhs == HB_MAP_VALUE_INVALID)
{
rhs = get_population ();
set (lhs, rhs);
}
return rhs;
}
/* Create an identity map. */
bool identity (unsigned int size)
{
hb_codepoint_t i;
old_to_new.clear ();
new_to_old.resize (size);
for (i = 0; i < size; i++)
{
old_to_new.set (i, i);
new_to_old[i] = i;
}
count = i;
return old_to_new.successful && !new_to_old.in_error ();
clear ();
for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
return !in_error ();
}
protected:
static int cmp_id (const void* a, const void* b)
{ return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
public:
/* Optional: after finished adding all mappings in a random order,
* reassign new ids to old ids so that both are in the same order. */
void reorder ()
* reassign rhs to lhs so that they are in the same order. */
void sort ()
{
new_to_old.qsort (cmp_id);
for (hb_codepoint_t _new = 0; _new < count; _new++)
old_to_new.set (to_old (_new), _new);
hb_codepoint_t count = get_population ();
hb_vector_t <hb_codepoint_t> work;
work.resize (count);
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
work[rhs] = back_map[rhs];
work.qsort (cmp_id);
clear ();
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
set (work[rhs], rhs);
}
unsigned int get_count () const { return count; }
protected:
unsigned int count;
hb_map_t old_to_new;
hb_vector_t<hb_codepoint_t>
new_to_old;
};
#endif /* HB_BIMAP_HH */

View File

@ -487,6 +487,7 @@ hb_blob_t::try_make_writable ()
* Mmap
*/
#ifndef HB_NO_OPEN
#ifdef HAVE_MMAP
# include <sys/types.h>
# include <sys/stat.h>
@ -543,10 +544,6 @@ _hb_mapped_file_destroy (void *file_)
hb_blob_t *
hb_blob_create_from_file (const char *file_name)
{
#ifdef HB_NO_OPEN
return hb_blob_get_empty ();
#endif
/* Adopted from glib's gmappedfile.c with Matthias Clasen and
Allison Lortie permission but changed a lot to suit our need. */
#if defined(HAVE_MMAP) && !defined(HB_NO_MMAP)
@ -680,3 +677,4 @@ fread_fail_without_close:
free (data);
return hb_blob_get_empty ();
}
#endif /* !HB_NO_OPEN */

View File

@ -24,14 +24,16 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_BUFFER_SERIALIZE
#include "hb-buffer.hh"
static const char *serialize_formats[] = {
#ifndef HB_NO_BUFFER_SERIALIZE
"text",
"json",
#endif
nullptr
};
@ -89,10 +91,8 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch ((unsigned) format)
{
#ifndef HB_NO_BUFFER_SERIALIZE
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
#endif
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
@ -348,10 +348,6 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
#ifdef HB_NO_BUFFER_SERIALIZE
return 0;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@ -457,10 +453,6 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
end_ptr = &end;
*end_ptr = buf;
#ifdef HB_NO_BUFFER_SERIALIZE
return false;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@ -496,3 +488,6 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
}
}
#endif

View File

@ -1993,6 +1993,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
* Debugging.
*/
#ifndef HB_NO_BUFFER_MESSAGE
/**
* hb_buffer_set_message_func:
* @buffer: an #hb_buffer_t.
@ -2022,7 +2023,6 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
buffer->message_destroy = nullptr;
}
}
bool
hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
{
@ -2030,3 +2030,4 @@ hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
vsnprintf (buf, sizeof (buf), fmt, ap);
return (bool) this->message_func (this, font, buf, this->message_data);
}
#endif

View File

@ -124,7 +124,9 @@ struct hb_buffer_t
unsigned int context_len[2];
/* Debugging API */
#ifndef HB_NO_BUFFER_MESSAGE
hb_buffer_message_func_t message_func;
#endif
void *message_data;
hb_destroy_func_t message_destroy;
@ -351,11 +353,15 @@ struct hb_buffer_t
{
#ifdef HB_NO_BUFFER_MESSAGE
return false;
#endif
#else
return unlikely (message_func);
#endif
}
bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
{
#ifdef HB_NO_BUFFER_MESSAGE
return true;
#else
if (!messaging ())
return true;
va_list ap;
@ -363,6 +369,7 @@ struct hb_buffer_t
bool ret = message_impl (font, fmt, ap);
va_end (ap);
return ret;
#endif
}
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);

View File

@ -226,7 +226,7 @@ struct number_t
void set_fixed (int32_t v) { value = v / 65536.0; }
int32_t to_fixed () const { return (int32_t) (value * 65536.0); }
void set_real (double v) { value = v; }
void set_real (double v) { value = v; }
double to_real () const { return value; }
int ceil () const { return (int) ::ceil (value); }
@ -235,17 +235,10 @@ struct number_t
bool in_int_range () const
{ return ((double) (int16_t) to_int () == value); }
bool operator > (const number_t &n) const
{ return value > n.to_real (); }
bool operator < (const number_t &n) const
{ return n > *this; }
bool operator >= (const number_t &n) const
{ return !(*this < n); }
bool operator <= (const number_t &n) const
{ return !(*this > n); }
bool operator > (const number_t &n) const { return value > n.to_real (); }
bool operator < (const number_t &n) const { return n > *this; }
bool operator >= (const number_t &n) const { return !(*this < n); }
bool operator <= (const number_t &n) const { return !(*this > n); }
const number_t &operator += (const number_t &n)
{
@ -255,7 +248,7 @@ struct number_t
}
protected:
double value;
double value;
};
/* byte string */
@ -320,8 +313,7 @@ struct byte_str_t : hb_ubytes_t
/* A byte string associated with the current offset and an error condition */
struct byte_str_ref_t
{
byte_str_ref_t ()
{ init (); }
byte_str_ref_t () { init (); }
void init ()
{
@ -343,13 +335,12 @@ struct byte_str_ref_t
}
const unsigned char& operator [] (int i) {
if (unlikely ((unsigned int)(offset + i) >= str.length))
if (unlikely ((unsigned int) (offset + i) >= str.length))
{
set_error ();
return Null(unsigned char);
return Null (unsigned char);
}
else
return str[offset + i];
return str[offset + i];
}
/* Conversion to byte_str_t */
@ -359,9 +350,7 @@ struct byte_str_ref_t
{ return str.sub_str (offset_, len_); }
bool avail (unsigned int count=1) const
{
return (!in_error () && str.check_limit (offset, count));
}
{ return (!in_error () && str.check_limit (offset, count)); }
void inc (unsigned int count=1)
{
if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length)))
@ -389,7 +378,7 @@ typedef hb_vector_t<byte_str_t> byte_str_array_t;
/* stack */
template <typename ELEM, int LIMIT>
struct stack_t
struct cff_stack_t
{
void init ()
{
@ -400,11 +389,7 @@ struct stack_t
for (unsigned int i = 0; i < elements.length; i++)
elements[i].init ();
}
void fini ()
{
elements.fini_deep ();
}
void fini () { elements.fini_deep (); }
ELEM& operator [] (unsigned int i)
{
@ -419,7 +404,6 @@ struct stack_t
else
set_error ();
}
ELEM &push ()
{
if (likely (count < elements.length))
@ -441,7 +425,6 @@ struct stack_t
return Crap(ELEM);
}
}
void pop (unsigned int n)
{
if (likely (count >= n))
@ -452,13 +435,12 @@ struct stack_t
const ELEM& peek ()
{
if (likely (count > 0))
return elements[count-1];
else
if (unlikely (count < 0))
{
set_error ();
return Null(ELEM);
}
return elements[count - 1];
}
void unpop ()
@ -475,7 +457,7 @@ struct stack_t
void set_error () { error = true; }
unsigned int get_count () const { return count; }
bool is_empty () const { return count == 0; }
bool is_empty () const { return !count; }
static constexpr unsigned kSizeLimit = LIMIT;
@ -487,7 +469,7 @@ struct stack_t
/* argument stack */
template <typename ARG=number_t>
struct arg_stack_t : stack_t<ARG, 513>
struct arg_stack_t : cff_stack_t<ARG, 513>
{
void push_int (int v)
{
@ -519,7 +501,7 @@ struct arg_stack_t : stack_t<ARG, 513>
i = 0;
S::set_error ();
}
return (unsigned)i;
return (unsigned) i;
}
void push_longint_from_substr (byte_str_ref_t& str_ref)
@ -538,12 +520,10 @@ struct arg_stack_t : stack_t<ARG, 513>
}
hb_array_t<const ARG> get_subarray (unsigned int start) const
{
return S::elements.sub_array (start);
}
{ return S::elements.sub_array (start); }
private:
typedef stack_t<ARG, 513> S;
typedef cff_stack_t<ARG, 513> S;
};
/* an operator prefixed by its operands in a byte string */
@ -605,7 +585,7 @@ struct parsed_values_t
}
unsigned get_count () const { return values.length; }
const VAL &get_value (unsigned int i) const { return values[i]; }
const VAL &get_value (unsigned int i) const { return values[i]; }
const VAL &operator [] (unsigned int i) const { return get_value (i); }
unsigned int opStart;
@ -644,30 +624,19 @@ struct interp_env_t
return op;
}
const ARG& eval_arg (unsigned int i)
{
return argStack[i];
}
const ARG& eval_arg (unsigned int i) { return argStack[i]; }
ARG& pop_arg ()
{
return argStack.pop ();
}
ARG& pop_arg () { return argStack.pop (); }
void pop_n_args (unsigned int n) { argStack.pop (n); }
void pop_n_args (unsigned int n)
{
argStack.pop (n);
}
void clear_args () { pop_n_args (argStack.get_count ()); }
void clear_args ()
{
pop_n_args (argStack.get_count ());
}
byte_str_ref_t str_ref;
arg_stack_t<ARG> argStack;
byte_str_ref_t
str_ref;
arg_stack_t<ARG>
argStack;
protected:
bool error;
bool error;
};
typedef interp_env_t<> num_interp_env_t;
@ -711,8 +680,8 @@ struct opset_t
};
template <typename ENV>
struct interpreter_t {
struct interpreter_t
{
~interpreter_t() { fini (); }
void fini () { env.fini (); }

View File

@ -57,14 +57,14 @@ struct call_context_t
/* call stack */
const unsigned int kMaxCallLimit = 10;
struct call_stack_t : stack_t<call_context_t, kMaxCallLimit> {};
struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
template <typename SUBRS>
struct biased_subrs_t
{
void init (const SUBRS &subrs_)
void init (const SUBRS *subrs_)
{
subrs = &subrs_;
subrs = subrs_;
unsigned int nSubrs = get_count ();
if (nSubrs < 1240)
bias = 107;
@ -118,7 +118,7 @@ struct point_t
template <typename ARG, typename SUBRS>
struct cs_interp_env_t : interp_env_t<ARG>
{
void init (const byte_str_t &str, const SUBRS &globalSubrs_, const SUBRS &localSubrs_)
void init (const byte_str_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_)
{
interp_env_t<ARG>::init (str);

View File

@ -40,7 +40,7 @@ struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
template <typename ACC>
void init (const byte_str_t &str, ACC &acc, unsigned int fd)
{
SUPER::init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
processed_width = false;
has_width = false;
arg_start = 0;

View File

@ -82,7 +82,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs>
void init (const byte_str_t &str, ACC &acc, unsigned int fd,
const int *coords_=nullptr, unsigned int num_coords_=0)
{
SUPER::init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
coords = coords_;
num_coords = num_coords_;

View File

@ -70,7 +70,7 @@ _hb_options_init ()
p = c + strlen (c);
#define OPTION(name, symbol) \
if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) do { u.opts.symbol = true; } while (0)
if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
OPTION ("aat", aat);

View File

@ -40,6 +40,7 @@
#define HB_LEAN
#define HB_MINI
#define HB_NO_MT
#define HB_NO_UCD_UNASSIGNED
#ifndef NDEBUG
#define NDEBUG
#endif
@ -57,14 +58,23 @@
#define HB_NO_BITMAP
#define HB_NO_CFF
#define HB_NO_COLOR
#define HB_NO_FACE_COLLECT_UNICODES
#define HB_NO_GETENV
#define HB_NO_HINTING
#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
#define HB_NO_LAYOUT_FEATURE_PARAMS
#define HB_NO_LAYOUT_COLLECT_GLYPHS
#define HB_NO_LAYOUT_UNUSED
#define HB_NO_MATH
#define HB_NO_MMAP
#define HB_NO_NAME
#define HB_NO_OPEN
#define HB_NO_SETLOCALE
#define HB_NO_OT_FONT_GLYPH_NAMES
#define HB_NO_OT_SHAPE_FRACTIONS
#define HB_NO_STAT
#define HB_NO_SUBSET_LAYOUT
#define HB_NO_VAR
#endif
#ifdef HB_MINI
@ -72,7 +82,8 @@
#define HB_NO_LEGACY
#endif
/* Closure. */
/* Closure of options. */
#ifdef HB_DISABLE_DEPRECATED
#define HB_IF_NOT_DEPRECATED(x)
@ -82,7 +93,7 @@
#ifdef HB_NO_AAT
#define HB_NO_OT_NAME_LANGUAGE_AAT
#define HB_NO_SHAPE_AAT
#define HB_NO_AAT_SHAPE
#endif
#ifdef HB_NO_BITMAP
@ -99,6 +110,9 @@
#endif
#ifdef HB_NO_LEGACY
#define HB_NO_CMAP_LEGACY_SUBTABLES
#define HB_NO_FALLBACK_SHAPE
#define HB_NO_OT_KERN
#define HB_NO_OT_LAYOUT_BLACKLIST
#define HB_NO_OT_SHAPE_FALLBACK
#endif
@ -107,6 +121,17 @@
#define HB_NO_OT_NAME_LANGUAGE
#endif
#ifdef HB_NO_OT
#define HB_NO_OT_FONT
#define HB_NO_OT_LAYOUT
#define HB_NO_OT_TAG
#define HB_NO_OT_SHAPE
#endif
#ifdef HB_NO_OT_SHAPE
#define HB_NO_AAT_SHAPE
#endif
#ifdef HB_NO_OT_SHAPE_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK

View File

@ -27,6 +27,9 @@
*/
#include "hb.hh"
#ifdef HAVE_CORETEXT
#include "hb-shaper-impl.hh"
#include "hb-coretext.h"
@ -72,7 +75,7 @@ release_table_data (void *user_data)
}
static hb_blob_t *
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
{
CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
@ -296,7 +299,7 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
hb_face_t *
hb_coretext_face_create (CGFontRef cg_font)
{
return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
}
/*
@ -649,7 +652,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
ret = false; \
goto fail; \
} HB_STMT_END;
} HB_STMT_END
bool ret = true;
CFStringRef string_ref = nullptr;
@ -977,7 +980,7 @@ resize_and_retry:
#define SCRATCH_RESTORE() \
scratch_size = scratch_size_saved; \
scratch = scratch_saved;
scratch = scratch_saved
{ /* Setup glyphs */
SCRATCH_SAVE();
@ -1148,3 +1151,6 @@ fail:
return ret;
}
#endif

View File

@ -165,29 +165,8 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *decomposed);
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_v_kerning_func:
* @ffuncs: font functions.
@ -206,19 +185,9 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
#endif
HB_END_DECLS

View File

@ -23,13 +23,23 @@
*/
#include "hb.hh"
#ifdef HAVE_DIRECTWRITE
#include "hb-shaper-impl.hh"
#include <DWrite_1.h>
#include <dwrite_1.h>
#include "hb-directwrite.h"
/* Declare object creator for dynamic support of DWRITE */
typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
DWRITE_FACTORY_TYPE factoryType,
REFIID iid,
IUnknown **factory
);
/*
* hb-directwrite uses new/delete syntatically but as we let users
* to override malloc/free, we will redefine new/delete so users
@ -135,6 +145,7 @@ public:
struct hb_directwrite_face_data_t
{
HMODULE dwrite_dll;
IDWriteFactory *dwriteFactory;
IDWriteFontFile *fontFile;
DWriteFontFileStream *fontFileStream;
@ -150,12 +161,43 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
if (unlikely (!data))
return nullptr;
// TODO: factory and fontFileLoader should be cached separately
IDWriteFactory* dwriteFactory;
DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
(IUnknown**) &dwriteFactory);
#define FAIL(...) \
HB_STMT_START { \
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
return nullptr; \
} HB_STMT_END
data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
if (unlikely (!data->dwrite_dll))
FAIL ("Cannot find DWrite.DLL");
t_DWriteCreateFactory p_DWriteCreateFactory;
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
p_DWriteCreateFactory = (t_DWriteCreateFactory)
GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
if (unlikely (!p_DWriteCreateFactory))
FAIL ("Cannot find DWriteCreateFactory().");
HRESULT hr;
// TODO: factory and fontFileLoader should be cached separately
IDWriteFactory* dwriteFactory;
hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
(IUnknown**) &dwriteFactory);
if (unlikely (hr != S_OK))
FAIL ("Failed to run DWriteCreateFactory().");
hb_blob_t *blob = hb_face_reference_blob (face);
DWriteFontFileStream *fontFileStream;
fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr),
@ -169,12 +211,6 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey),
fontFileLoader, &fontFile);
#define FAIL(...) \
HB_STMT_START { \
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
return nullptr; \
} HB_STMT_END;
if (FAILED (hr))
FAIL ("Failed to load font file from data!");
@ -221,6 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
delete data->fontFileStream;
if (data->faceBlob)
hb_blob_destroy (data->faceBlob);
if (data->dwrite_dll)
FreeLibrary (data->dwrite_dll);
if (data)
delete data;
}
@ -501,10 +539,10 @@ protected:
Run mRunHead;
};
static inline uint16_t hb_uint16_swap (const uint16_t v)
static inline uint16_t hb_dw_uint16_swap (const uint16_t v)
{ return (v >> 8) | (v << 8); }
static inline uint32_t hb_uint32_swap (const uint32_t v)
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
static inline uint32_t hb_dw_uint32_swap (const uint32_t v)
{ return (hb_dw_uint16_swap (v) << 16) | hb_dw_uint16_swap (v >> 16); }
/*
* shaper
@ -615,7 +653,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
for (unsigned int i = 0; i < num_features; ++i)
{
typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
hb_uint32_swap (features[i].tag);
hb_dw_uint32_swap (features[i].tag);
typographic_features.features[i].parameter = features[i].value;
}
}
@ -896,14 +934,14 @@ _hb_directwrite_table_data_release (void *data)
}
static hb_blob_t *
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
_hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
{
IDWriteFontFace *dw_face = ((IDWriteFontFace *) user_data);
const void *data;
uint32_t length;
void *table_context;
BOOL exists;
if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data,
if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_dw_uint32_swap (tag), &data,
&length, &table_context, &exists)))
return nullptr;
@ -941,7 +979,7 @@ hb_directwrite_face_create (IDWriteFontFace *font_face)
{
if (font_face)
font_face->AddRef ();
return hb_face_create_for_tables (reference_table, font_face,
return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face,
_hb_directwrite_font_release);
}
@ -958,3 +996,6 @@ hb_directwrite_face_get_font_face (hb_face_t *face)
{
return face->data.directwrite->fontFace;
}
#endif

View File

@ -531,6 +531,7 @@ hb_face_get_table_tags (const hb_face_t *face,
*/
#ifndef HB_NO_FACE_COLLECT_UNICODES
/**
* hb_face_collect_unicodes:
* @face: font face.
@ -544,7 +545,6 @@ hb_face_collect_unicodes (hb_face_t *face,
{
face->table.cmap->collect_unicodes (out);
}
/**
* hb_face_collect_variation_selectors:
* @face: font face.
@ -560,7 +560,6 @@ hb_face_collect_variation_selectors (hb_face_t *face,
{
face->table.cmap->collect_variation_selectors (out);
}
/**
* hb_face_collect_variation_unicodes:
* @face: font face.
@ -577,7 +576,7 @@ hb_face_collect_variation_unicodes (hb_face_t *face,
{
face->table.cmap->collect_variation_unicodes (variation_selector, out);
}
#endif
/*

View File

@ -26,6 +26,7 @@
#include "hb-shaper-impl.hh"
#ifndef HB_NO_FALLBACK_SHAPE
/*
* shaper face data
@ -120,3 +121,5 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true;
}
#endif

View File

@ -336,7 +336,6 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font,
return ret;
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -356,6 +355,7 @@ hb_font_get_glyph_h_kerning_default (hb_font_t *font,
return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -927,7 +927,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
return font->get_glyph_v_origin (glyph, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_h_kerning:
* @font: a font.
@ -939,7 +938,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
* Return value:
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
@ -948,6 +946,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_v_kerning:
* @font: a font.
@ -1177,7 +1176,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_kerning_for_direction:
* @font: a font.
@ -1190,7 +1188,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
*
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
@ -1200,7 +1197,6 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
{
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
#endif
/**
* hb_font_get_glyph_extents_for_origin:
@ -1304,6 +1300,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */
1000, /* y_scale */
1<<16, /* x_mult */
1<<16, /* y_mult */
0, /* x_ppem */
0, /* y_ppem */
@ -1334,6 +1332,7 @@ _hb_font_create (hb_face_t *face)
font->klass = hb_font_funcs_get_empty ();
font->data.init0 (font);
font->x_scale = font->y_scale = hb_face_get_upem (face);
font->x_mult = font->y_mult = 1 << 16;
return font;
}
@ -1605,7 +1604,9 @@ hb_font_set_face (hb_font_t *font,
hb_face_t *old = font->face;
hb_face_make_immutable (face);
font->face = hb_face_reference (face);
font->mults_changed ();
hb_face_destroy (old);
}
@ -1715,6 +1716,7 @@ hb_font_set_scale (hb_font_t *font,
font->x_scale = x_scale;
font->y_scale = y_scale;
font->mults_changed ();
}
/**
@ -1828,6 +1830,7 @@ _hb_font_adopt_var_coords_normalized (hb_font_t *font,
font->num_coords = coords_length;
}
#ifndef HB_NO_VAR
/**
* hb_font_set_variations:
*
@ -1858,7 +1861,6 @@ hb_font_set_variations (hb_font_t *font,
normalized, coords_length);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
/**
* hb_font_set_var_coords_design:
*
@ -1879,6 +1881,7 @@ hb_font_set_var_coords_design (hb_font_t *font,
hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
#endif
/**
* hb_font_set_var_coords_normalized:

View File

@ -157,6 +157,11 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
@ -356,6 +361,22 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_extents_func:
* @ffuncs: font functions.
@ -469,6 +490,10 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
@ -531,6 +556,12 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,

View File

@ -51,7 +51,7 @@
HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning)) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
@ -107,8 +107,10 @@ struct hb_font_t
hb_font_t *parent;
hb_face_t *face;
int x_scale;
int y_scale;
int32_t x_scale;
int32_t y_scale;
int64_t x_mult;
int64_t y_mult;
unsigned int x_ppem;
unsigned int y_ppem;
@ -127,16 +129,16 @@ struct hb_font_t
/* Convert from font-space to user-space */
int dir_scale (hb_direction_t direction)
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
int64_t dir_mult (hb_direction_t direction)
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); }
hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
{ return em_scale (v, dir_scale (direction)); }
{ return em_mult (v, dir_mult (direction)); }
/* Convert from parent-font user-space to our user-space */
hb_position_t parent_scale_x_distance (hb_position_t v)
@ -607,12 +609,16 @@ struct hb_font_t
return false;
}
hb_position_t em_scale (int16_t v, int scale)
void mults_changed ()
{
int upem = face->get_upem ();
int64_t scaled = v * (int64_t) scale;
scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
return (hb_position_t) (scaled / upem);
signed upem = face->get_upem ();
x_mult = ((int64_t) x_scale << 16) / upem;
y_mult = ((int64_t) y_scale << 16) / upem;
}
hb_position_t em_mult (int16_t v, int64_t mult)
{
return (hb_position_t) ((v * mult) >> 16);
}
hb_position_t em_scalef (float v, int scale)
{ return (hb_position_t) roundf (v * scale / face->get_upem ()); }

View File

@ -29,6 +29,8 @@
#include "hb.hh"
#ifdef HAVE_FREETYPE
#include "hb-ft.h"
#include "hb-font.hh"
@ -346,6 +348,25 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
return true;
}
#ifndef HB_NO_OT_SHAPE_FALLBACK
static hb_position_t
hb_ft_get_glyph_h_kerning (hb_font_t *font,
void *font_data,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
FT_Vector kerningv;
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
return 0;
return kerningv.x;
}
#endif
static hb_bool_t
hb_ft_get_glyph_extents (hb_font_t *font,
void *font_data,
@ -497,6 +518,10 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
#ifndef HB_NO_OT_SHAPE_FALLBACK
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
#endif
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
@ -539,7 +564,7 @@ _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
static hb_blob_t *
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
_hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
{
FT_Face ft_face = (FT_Face) user_data;
FT_Byte *buffer;
@ -594,7 +619,7 @@ hb_ft_face_create (FT_Face ft_face,
face = hb_face_create (blob, ft_face->face_index);
hb_blob_destroy (blob);
} else {
face = hb_face_create_for_tables (reference_table, ft_face, destroy);
face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy);
}
hb_face_set_index (face, ft_face->face_index);
@ -854,3 +879,6 @@ hb_ft_font_set_funcs (hb_font_t *font)
_hb_ft_font_set_funcs (font, ft_face, true);
hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
}
#endif

View File

@ -28,6 +28,8 @@
#include "hb.hh"
#ifdef HAVE_GLIB
#include "hb-glib.h"
#include "hb-machinery.hh"
@ -404,3 +406,6 @@ hb_glib_blob_create (GBytes *gbytes)
_hb_g_bytes_unref);
}
#endif
#endif

View File

@ -27,6 +27,8 @@
#include "hb.hh"
#ifdef HAVE_GOBJECT
/* g++ didn't like older gtype.h gcc-only code path. */
#include <glib.h>
#if !GLIB_CHECK_VERSION(2,29,16)
@ -44,6 +46,11 @@
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
#endif
/*** END file-tail ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type ()

View File

@ -26,6 +26,8 @@
#include "hb.hh"
#ifdef HAVE_GOBJECT
/**
* SECTION:hb-gobject
@ -94,3 +96,6 @@ HB_DEFINE_VALUE_TYPE (user_data_key)
HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
#endif

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifdef HAVE_GRAPHITE2
#include "hb-shaper-impl.hh"
#include "hb-graphite2.h"
@ -447,3 +451,6 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true;
}
#endif

View File

@ -29,6 +29,8 @@
#include "hb.hh"
#ifdef HAVE_ICU
#include "hb-icu.h"
#include "hb-machinery.hh"
@ -351,3 +353,6 @@ hb_icu_get_unicode_funcs ()
{
return static_icu_funcs.get_unconst ();
}
#endif

View File

@ -80,8 +80,8 @@ template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::t
struct
{
template <typename T>
T* operator () (T& arg) const
template <typename T> constexpr T*
operator () (T& arg) const
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
@ -171,29 +171,29 @@ using hb_is_cr_convertible = hb_bool_constant<
/* std::move and std::forward */
template <typename T>
static hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
template <typename T>
static T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
template <typename T>
static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
struct
{
template <typename T> auto
template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
template <typename T> auto
template <typename T> constexpr auto
operator () (T *v) const HB_AUTO_RETURN (*v)
}
HB_FUNCOBJ (hb_deref);
struct
{
template <typename T> auto
template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
template <typename T> auto
template <typename T> constexpr auto
operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
}
HB_FUNCOBJ (hb_ref);

View File

@ -74,7 +74,7 @@ using hb_static_size = _hb_static_size<T, void>;
*/
extern HB_INTERNAL
hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
/* Generic nul-content Null objects. */
template <typename Type>
@ -128,7 +128,7 @@ struct NullHelper
* causing bad memory access. So, races there are not actually introducing incorrectness
* in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
extern HB_INTERNAL
/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
/* CRAP pool: Common Region for Access Protection. */
template <typename Type>

View File

@ -59,11 +59,11 @@ struct IntType
typedef Type type;
typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
IntType<Type, Size>& operator = (wide_type i) { v = i; return *this; }
IntType& operator = (wide_type i) { v = i; return *this; }
operator wide_type () const { return v; }
bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
HB_INTERNAL static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b)
bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType &o) const { return !(*this == o); }
HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
{ return b->cmp (*a); }
template <typename Type2>
int cmp (Type2 a) const
@ -146,7 +146,7 @@ struct LONGDATETIME
* system, feature, or baseline */
struct Tag : HBUINT32
{
Tag& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; }
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
operator const char* () const { return reinterpret_cast<const char *> (&this->v); }
operator char* () { return reinterpret_cast<char *> (&this->v); }

View File

@ -27,6 +27,7 @@
#define HB_OT_CFF_COMMON_HH
#include "hb-open-type.hh"
#include "hb-bimap.hh"
#include "hb-ot-layout-common.hh"
#include "hb-cff-interp-dict-common.hh"
#include "hb-subset-plan.hh"
@ -39,14 +40,14 @@ using namespace OT;
/* utility macro */
template<typename Type>
static inline const Type& StructAtOffsetOrNull(const void *P, unsigned int offset)
{ return offset? (* reinterpret_cast<const Type*> ((const char *) P + offset)): Null(Type); }
static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset)
{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
inline unsigned int calcOffSize(unsigned int dataSize)
inline unsigned int calcOffSize (unsigned int dataSize)
{
unsigned int size = 1;
unsigned int offset = dataSize + 1;
while ((offset & ~0xFF) != 0)
while (offset & ~0xFF)
{
size++;
offset >>= 8;
@ -57,8 +58,8 @@ inline unsigned int calcOffSize(unsigned int dataSize)
struct code_pair_t
{
hb_codepoint_t code;
hb_codepoint_t glyph;
hb_codepoint_t code;
hb_codepoint_t glyph;
};
typedef hb_vector_t<unsigned char> str_buff_t;
@ -91,10 +92,8 @@ struct CFFIndex
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count,
unsigned int dataSize)
{
if (count == 0)
return COUNT::static_size;
else
return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
if (count == 0) return COUNT::static_size;
return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
}
bool serialize (hb_serialize_context_t *c, const CFFIndex &src)
@ -158,9 +157,7 @@ struct CFFIndex
byteArray.init ();
byteArray.resize (buffArray.length);
for (unsigned int i = 0; i < byteArray.length; i++)
{
byteArray[i] = byte_str_t (buffArray[i].arrayZ, buffArray[i].length);
}
bool result = this->serialize (c, offSize_, byteArray);
byteArray.fini ();
return result;
@ -191,43 +188,35 @@ struct CFFIndex
unsigned int length_at (unsigned int index) const
{
if (likely ((offset_at (index + 1) >= offset_at (index)) &&
(offset_at (index + 1) <= offset_at (count))))
return offset_at (index + 1) - offset_at (index);
else
if (unlikely ((offset_at (index + 1) < offset_at (index)) ||
(offset_at (index + 1) > offset_at (count))))
return 0;
return offset_at (index + 1) - offset_at (index);
}
const unsigned char *data_base () const
{ return (const unsigned char *)this + min_size + offset_array_size (); }
{ return (const unsigned char *) this + min_size + offset_array_size (); }
unsigned int data_size () const { return HBINT8::static_size; }
byte_str_t operator [] (unsigned int index) const
{
if (likely (index < count))
return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
else
return Null (byte_str_t);
if (unlikely (index >= count)) return Null (byte_str_t);
return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
}
unsigned int get_size () const
{
if (this != &Null (CFFIndex))
{
if (count > 0)
return min_size + offset_array_size () + (offset_at (count) - 1);
else
return count.static_size; /* empty CFFIndex contains count only */
}
else
return 0;
if (this == &Null (CFFIndex)) return 0;
if (count > 0)
return min_size + offset_array_size () + (offset_at (count) - 1);
return count.static_size; /* empty CFFIndex contains count only */
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
return_trace (likely ((c->check_struct (this) && count == 0) || /* empty INDEX */
(c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
c->check_array (offsets, offSize, count + 1) &&
c->check_array ((const HBUINT8*) data_base (), 1, max_offset () - 1))));
@ -453,7 +442,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
unsigned int offSize_,
const hb_vector_t<DICTVAL> &fontDicts,
unsigned int fdCount,
const hb_bimap_t &fdmap,
const hb_inc_bimap_t &fdmap,
OP_SERIALIZER& opszr,
const hb_vector_t<table_info_t> &privateInfos)
{
@ -492,7 +481,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
const hb_vector_t<DICTVAL> &fontDicts,
unsigned int fdCount,
const hb_bimap_t &fdmap,
const hb_inc_bimap_t &fdmap,
OP_SERIALIZER& opszr)
{
unsigned int dictsSize = 0;

View File

@ -24,11 +24,13 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb-ot-cff1-table.hh"
#include "hb-cff1-interp-cs.hh"
#include "hb.hh"
#ifndef HB_NO_CFF
#include "hb-ot-cff1-table.hh"
#include "hb-cff1-interp-cs.hh"
using namespace CFF;
/* SID to code */
@ -208,7 +210,7 @@ struct bounds_t
point_t max;
};
struct extents_param_t
struct cff1_extents_param_t
{
void init (const OT::cff1::accelerator_t *_cff)
{
@ -227,15 +229,15 @@ struct extents_param_t
const OT::cff1::accelerator_t *cff;
};
struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, extents_param_t>
struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, cff1_extents_param_t>
{
static void moveto (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
static void moveto (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt)
{
param.end_path ();
env.moveto (pt);
}
static void line (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
static void line (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1)
{
if (!param.is_path_open ())
{
@ -246,7 +248,7 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
param.bounds.update (env.get_pt ());
}
static void curve (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
static void curve (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
{
if (!param.is_path_open ())
{
@ -263,9 +265,9 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
static bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, extents_param_t, cff1_path_procs_extents_t>
struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, cff1_extents_param_t, cff1_path_procs_extents_t>
{
static void process_seac (cff1_cs_interp_env_t &env, extents_param_t& param)
static void process_seac (cff1_cs_interp_env_t &env, cff1_extents_param_t& param)
{
unsigned int n = env.argStack.get_count ();
point_t delta;
@ -294,11 +296,11 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
unsigned int fd = cff->fdSelect->get_fd (glyph);
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, extents_param_t> interp;
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp;
const byte_str_t str = (*cff->charStrings)[glyph];
interp.env.init (str, *cff, fd);
interp.env.set_in_seac (in_seac);
extents_param_t param;
cff1_extents_param_t param;
param.init (cff);
if (unlikely (!interp.interpret (param))) return false;
bounds = param.bounds;
@ -391,4 +393,5 @@ bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_code
return false;
}
#endif

View File

@ -594,10 +594,10 @@ struct Charset
struct CFF1StringIndex : CFF1Index
{
bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
unsigned int offSize_, const hb_bimap_t &sidmap)
unsigned int offSize_, const hb_inc_bimap_t &sidmap)
{
TRACE_SERIALIZE (this);
if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
{
if (unlikely (!c->extend_min (this->count)))
return_trace (false);
@ -607,7 +607,7 @@ struct CFF1StringIndex : CFF1Index
byte_str_array_t bytesArray;
bytesArray.init ();
if (!bytesArray.resize (sidmap.get_count ()))
if (!bytesArray.resize (sidmap.get_population ()))
return_trace (false);
for (unsigned int i = 0; i < strings.count; i++)
{
@ -622,10 +622,10 @@ struct CFF1StringIndex : CFF1Index
}
/* in parallel to above */
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_bimap_t &sidmap) const
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const
{
offSize_ = 0;
if ((count == 0) || (sidmap.get_count () == 0))
if ((count == 0) || (sidmap.get_population () == 0))
return count.static_size;
unsigned int dataSize = 0;
@ -634,7 +634,7 @@ struct CFF1StringIndex : CFF1Index
dataSize += length_at (i);
offSize_ = calcOffSize(dataSize);
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_count (), dataSize);
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize);
}
};

View File

@ -24,14 +24,16 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb-ot-cff2-table.hh"
#include "hb-cff2-interp-cs.hh"
#include "hb.hh"
#ifndef HB_NO_OT_FONT_CFF
#include "hb-ot-cff2-table.hh"
#include "hb-cff2-interp-cs.hh"
using namespace CFF;
struct extents_param_t
struct cff2_extents_param_t
{
void init ()
{
@ -61,15 +63,15 @@ struct extents_param_t
number_t max_y;
};
struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, extents_param_t>
struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, cff2_extents_param_t>
{
static void moveto (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
static void moveto (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt)
{
param.end_path ();
env.moveto (pt);
}
static void line (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
static void line (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1)
{
if (!param.is_path_open ())
{
@ -80,7 +82,7 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
param.update_bounds (env.get_pt ());
}
static void curve (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
static void curve (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
{
if (!param.is_path_open ())
{
@ -95,7 +97,7 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
}
};
struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, extents_param_t, cff2_path_procs_extents_t> {};
struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_extents_param_t, cff2_path_procs_extents_t> {};
bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
hb_codepoint_t glyph,
@ -111,10 +113,10 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
unsigned int num_coords;
const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
unsigned int fd = fdSelect->get_fd (glyph);
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, extents_param_t> interp;
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t> interp;
const byte_str_t str = (*charStrings)[glyph];
interp.env.init (str, *this, fd, coords, num_coords);
extents_param_t param;
cff2_extents_param_t param;
param.init ();
if (unlikely (!interp.interpret (param))) return false;
@ -142,4 +144,5 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
return true;
}
#endif

View File

@ -756,10 +756,12 @@ struct CmapSubtable
hb_codepoint_t *glyph) const
{
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: return u.format0 .get_glyph (codepoint, glyph);
case 4: return u.format4 .get_glyph (codepoint, glyph);
case 6: return u.format6 .get_glyph (codepoint, glyph);
case 10: return u.format10.get_glyph (codepoint, glyph);
#endif
case 4: return u.format4 .get_glyph (codepoint, glyph);
case 12: return u.format12.get_glyph (codepoint, glyph);
case 13: return u.format13.get_glyph (codepoint, glyph);
case 14:
@ -769,10 +771,12 @@ struct CmapSubtable
void collect_unicodes (hb_set_t *out) const
{
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: u.format0 .collect_unicodes (out); return;
case 4: u.format4 .collect_unicodes (out); return;
case 6: u.format6 .collect_unicodes (out); return;
case 10: u.format10.collect_unicodes (out); return;
#endif
case 4: u.format4 .collect_unicodes (out); return;
case 12: u.format12.collect_unicodes (out); return;
case 13: u.format13.collect_unicodes (out); return;
case 14:
@ -785,10 +789,12 @@ struct CmapSubtable
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: return_trace (u.format0 .sanitize (c));
case 4: return_trace (u.format4 .sanitize (c));
case 6: return_trace (u.format6 .sanitize (c));
case 10: return_trace (u.format10.sanitize (c));
#endif
case 4: return_trace (u.format4 .sanitize (c));
case 12: return_trace (u.format12.sanitize (c));
case 13: return_trace (u.format13.sanitize (c));
case 14: return_trace (u.format14.sanitize (c));
@ -799,10 +805,12 @@ struct CmapSubtable
public:
union {
HBUINT16 format; /* Format identifier */
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
CmapSubtableFormat0 format0;
CmapSubtableFormat4 format4;
CmapSubtableFormat6 format6;
CmapSubtableFormat10 format10;
#endif
CmapSubtableFormat4 format4;
CmapSubtableFormat12 format12;
CmapSubtableFormat13 format13;
CmapSubtableFormat14 format14;
@ -848,11 +856,16 @@ struct cmap
size_t final_size () const
{
return 4 // header
+ 8 * 3 // 3 EncodingRecord
+ 8 * num_enc_records
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
}
unsigned int num_enc_records;
bool has_unicode_bmp;
bool has_unicode_ucs4;
bool has_ms_bmp;
bool has_ms_ucs4;
hb_sorted_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
hb_sorted_vector_t<CmapSubtableLongGroup> format12_groups;
};
@ -860,6 +873,12 @@ struct cmap
bool _create_plan (const hb_subset_plan_t *plan,
subset_plan *cmap_plan) const
{
cmap_plan->has_unicode_bmp = find_subtable (0, 3);
cmap_plan->has_unicode_ucs4 = find_subtable (0, 4);
cmap_plan->has_ms_bmp = find_subtable (3, 1);
cmap_plan->has_ms_ucs4 = find_subtable (3, 10);
cmap_plan->num_enc_records = cmap_plan->has_unicode_bmp + cmap_plan->has_unicode_ucs4 + cmap_plan->has_ms_bmp + cmap_plan->has_ms_ucs4;
if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
return false;
@ -882,32 +901,60 @@ struct cmap
table->version = 0;
if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ cmap_subset_plan.format12_groups ? 3 : 2))) return false;
if (unlikely (!table->encodingRecord.serialize (&c, cmap_subset_plan.num_enc_records))) return false;
// TODO(grieger): Convert the below to a for loop
int enc_index = 0;
int unicode_bmp_index = 0;
int unicode_ucs4_index = 0;
int ms_bmp_index = 0;
int ms_ucs4_index = 0;
// Format 4, Plat 0 Encoding Record
EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
format4_plat0_rec.platformID = 0; // Unicode
format4_plat0_rec.encodingID = 3;
if (cmap_subset_plan.has_unicode_bmp)
{
unicode_bmp_index = enc_index;
EncodingRecord &format4_plat0_rec = table->encodingRecord[enc_index++];
format4_plat0_rec.platformID = 0; // Unicode
format4_plat0_rec.encodingID = 3;
}
// Format 12, Plat 0 Encoding Record
if (cmap_subset_plan.has_unicode_ucs4)
{
unicode_ucs4_index = enc_index;
EncodingRecord &format12_rec = table->encodingRecord[enc_index++];
format12_rec.platformID = 0; // Unicode
format12_rec.encodingID = 4; // Unicode UCS-4
}
// Format 4, Plat 3 Encoding Record
EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
format4_plat3_rec.platformID = 3; // Windows
format4_plat3_rec.encodingID = 1; // Unicode BMP
// Format 12 Encoding Record
if (cmap_subset_plan.format12_groups)
if (cmap_subset_plan.has_ms_bmp)
{
EncodingRecord &format12_rec = table->encodingRecord[2];
ms_bmp_index = enc_index;
EncodingRecord &format4_plat3_rec = table->encodingRecord[enc_index++];
format4_plat3_rec.platformID = 3; // Windows
format4_plat3_rec.encodingID = 1; // Unicode BMP
}
// Format 12, Plat 3 Encoding Record
if (cmap_subset_plan.has_ms_ucs4)
{
ms_ucs4_index = enc_index;
EncodingRecord &format12_rec = table->encodingRecord[enc_index++];
format12_rec.platformID = 3; // Windows
format12_rec.encodingID = 10; // Unicode UCS-4
}
// Write out format 4 sub table
{
CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
format4_plat3_rec.subtable = (unsigned int) format4_plat0_rec.subtable;
if (unlikely (!cmap_subset_plan.has_unicode_bmp && !cmap_subset_plan.has_ms_bmp)) return false;
EncodingRecord &format4_rec = cmap_subset_plan.has_unicode_bmp?
table->encodingRecord[unicode_bmp_index]:
table->encodingRecord[ms_bmp_index];
CmapSubtable &subtable = format4_rec.subtable.serialize (&c, table);
if (cmap_subset_plan.has_unicode_bmp && cmap_subset_plan.has_ms_bmp)
table->encodingRecord[ms_bmp_index].subtable = (unsigned int) format4_rec.subtable;
subtable.u.format = 4;
CmapSubtableFormat4 &format4 = subtable.u.format4;
@ -918,8 +965,14 @@ struct cmap
// Write out format 12 sub table.
if (cmap_subset_plan.format12_groups)
{
EncodingRecord &format12_rec = table->encodingRecord[2];
if (unlikely (!cmap_subset_plan.has_unicode_ucs4 && !cmap_subset_plan.has_ms_ucs4)) return false;
EncodingRecord &format12_rec = cmap_subset_plan.has_unicode_ucs4?
table->encodingRecord[unicode_ucs4_index]:
table->encodingRecord[ms_ucs4_index];
CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
if (cmap_subset_plan.has_unicode_ucs4 && cmap_subset_plan.has_ms_ucs4)
table->encodingRecord[ms_ucs4_index].subtable = (unsigned int) format12_rec.subtable;
subtable.u.format = 12;
CmapSubtableFormat12 &format12 = subtable.u.format12;

View File

@ -25,20 +25,21 @@
* Google Author(s): Sascha Brawer, Behdad Esfahbod
*/
#include "hb-open-type.hh"
#include "hb.hh"
#ifndef HB_NO_COLOR
#include "hb-ot.h"
#include "hb-ot-color-cbdt-table.hh"
#include "hb-ot-color-colr-table.hh"
#include "hb-ot-color-cpal-table.hh"
#include "hb-ot-color-sbix-table.hh"
#include "hb-ot-color-svg-table.hh"
#include "hb-ot-face.hh"
#include "hb-ot.h"
#include <stdlib.h>
#include <string.h>
#include "hb-ot-layout.hh"
/**
* SECTION:hb-ot-color
@ -70,9 +71,6 @@
hb_bool_t
hb_ot_color_has_palettes (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CPAL->has_data ();
}
@ -89,9 +87,6 @@ hb_ot_color_has_palettes (hb_face_t *face)
unsigned int
hb_ot_color_palette_get_count (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return 0;
#endif
return face->table.CPAL->get_palette_count ();
}
@ -115,9 +110,6 @@ hb_ot_name_id_t
hb_ot_color_palette_get_name_id (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_palette_name_id (palette_index);
}
@ -140,9 +132,6 @@ hb_ot_name_id_t
hb_ot_color_palette_color_get_name_id (hb_face_t *face,
unsigned int color_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_color_name_id (color_index);
}
@ -161,9 +150,6 @@ hb_ot_color_palette_flags_t
hb_ot_color_palette_get_flags (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
#endif
return face->table.CPAL->get_palette_flags (palette_index);
}
@ -195,11 +181,6 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
unsigned int *colors_count /* IN/OUT. May be NULL. */,
hb_color_t *colors /* OUT. May be NULL. */)
{
#ifdef HB_NO_COLOR
if (colors_count)
*colors_count = 0;
return 0;
#endif
return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
}
@ -221,9 +202,6 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
hb_bool_t
hb_ot_color_has_layers (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.COLR->has_data ();
}
@ -250,11 +228,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
unsigned int *layer_count, /* IN/OUT. May be NULL. */
hb_ot_color_layer_t *layers /* OUT. May be NULL. */)
{
#ifdef HB_NO_COLOR
if (layer_count)
*layer_count = 0;
return 0;
#endif
return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
}
@ -276,9 +249,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
hb_bool_t
hb_ot_color_has_svg (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.SVG->has_data ();
}
@ -296,9 +266,6 @@ hb_ot_color_has_svg (hb_face_t *face)
hb_blob_t *
hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
return face->table.SVG->reference_blob_for_glyph (glyph);
}
@ -320,9 +287,6 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
hb_bool_t
hb_ot_color_has_png (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CBDT->has_data () || face->table.sbix->has_data ();
}
@ -342,10 +306,6 @@ hb_ot_color_has_png (hb_face_t *face)
hb_blob_t *
hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
hb_blob_t *blob = hb_blob_get_empty ();
if (font->face->table.sbix->has_data ())
@ -356,3 +316,6 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
return blob;
}
#endif

View File

@ -0,0 +1,128 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
* Copyright © 2012,2013 Google, Inc.
* Copyright © 2019, Facebook Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
* Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_FACE_TABLE_LIST_HH
#define HB_OT_FACE_TABLE_LIST_HH
#endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
#ifndef HB_OT_ACCELERATOR
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
#define _HB_OT_ACCELERATOR_UNDEF
#endif
/* This lists font tables that the hb_face_t will contain and lazily
* load. Don't add a table unless it's used though. This is not
* exactly free. */
/* v--- Add new tables in the right place here. */
/* OpenType fundamentals. */
HB_OT_TABLE (OT, head)
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
HB_OT_ACCELERATOR (OT, cmap)
#endif
HB_OT_ACCELERATOR (OT, hmtx)
HB_OT_TABLE (OT, OS2)
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
HB_OT_ACCELERATOR (OT, post)
#endif
#ifndef HB_NO_NAME
HB_OT_ACCELERATOR (OT, name)
#endif
#ifndef HB_NO_STAT
HB_OT_TABLE (OT, STAT)
#endif
/* Vertical layout. */
HB_OT_ACCELERATOR (OT, vmtx)
/* TrueType outlines. */
HB_OT_ACCELERATOR (OT, glyf)
/* CFF outlines. */
#ifndef HB_NO_CFF
HB_OT_ACCELERATOR (OT, cff1)
HB_OT_ACCELERATOR (OT, cff2)
HB_OT_TABLE (OT, VORG)
#endif
/* OpenType variations. */
#ifndef HB_NO_VAR
HB_OT_TABLE (OT, fvar)
HB_OT_TABLE (OT, avar)
HB_OT_TABLE (OT, MVAR)
#endif
/* Legacy kern. */
#ifndef HB_NO_OT_KERN
HB_OT_TABLE (OT, kern)
#endif
/* OpenType shaping. */
#ifndef HB_NO_OT_LAYOUT
HB_OT_ACCELERATOR (OT, GDEF)
HB_OT_ACCELERATOR (OT, GSUB)
HB_OT_ACCELERATOR (OT, GPOS)
//HB_OT_TABLE (OT, BASE)
//HB_OT_TABLE (OT, JSTF)
#endif
/* AAT shaping. */
#ifndef HB_NO_AAT
HB_OT_TABLE (AAT, morx)
HB_OT_TABLE (AAT, mort)
HB_OT_TABLE (AAT, kerx)
HB_OT_TABLE (AAT, ankr)
HB_OT_TABLE (AAT, trak)
HB_OT_TABLE (AAT, lcar)
HB_OT_TABLE (AAT, ltag)
HB_OT_TABLE (AAT, feat)
#endif
/* OpenType color fonts. */
#ifndef HB_NO_COLOR
HB_OT_TABLE (OT, COLR)
HB_OT_TABLE (OT, CPAL)
HB_OT_ACCELERATOR (OT, CBDT)
HB_OT_ACCELERATOR (OT, sbix)
HB_OT_ACCELERATOR (OT, SVG)
#endif
/* OpenType math. */
#ifndef HB_NO_MATH
HB_OT_TABLE (OT, MATH)
#endif
#ifdef _HB_OT_ACCELERATOR_UNDEF
#undef HB_OT_ACCELERATOR
#endif

View File

@ -46,16 +46,12 @@ void hb_ot_face_t::init0 (hb_face_t *face)
{
this->face = face;
#define HB_OT_TABLE(Namespace, Type) Type.init0 ();
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
}
void hb_ot_face_t::fini ()
{
#define HB_OT_TABLE(Namespace, Type) Type.fini ();
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
}

View File

@ -38,54 +38,10 @@
* hb_ot_face_t
*/
#define HB_OT_TABLES \
/* OpenType fundamentals. */ \
HB_OT_TABLE(OT, head) \
HB_OT_ACCELERATOR(OT, cmap) \
HB_OT_ACCELERATOR(OT, hmtx) \
HB_OT_ACCELERATOR(OT, vmtx) \
HB_OT_ACCELERATOR(OT, post) \
HB_OT_TABLE(OT, kern) \
HB_OT_ACCELERATOR(OT, glyf) \
HB_OT_ACCELERATOR(OT, cff1) \
HB_OT_ACCELERATOR(OT, cff2) \
HB_OT_TABLE(OT, VORG) \
HB_OT_ACCELERATOR(OT, name) \
HB_OT_TABLE(OT, OS2) \
HB_OT_TABLE(OT, STAT) \
/* OpenType shaping. */ \
HB_OT_ACCELERATOR(OT, GDEF) \
HB_OT_ACCELERATOR(OT, GSUB) \
HB_OT_ACCELERATOR(OT, GPOS) \
HB_OT_TABLE(OT, BASE) \
HB_OT_TABLE(OT, JSTF) \
/* AAT shaping. */ \
HB_OT_TABLE(AAT, mort) \
HB_OT_TABLE(AAT, morx) \
HB_OT_TABLE(AAT, kerx) \
HB_OT_TABLE(AAT, ankr) \
HB_OT_TABLE(AAT, trak) \
HB_OT_TABLE(AAT, lcar) \
HB_OT_TABLE(AAT, ltag) \
HB_OT_TABLE(AAT, feat) \
/* OpenType variations. */ \
HB_OT_TABLE(OT, fvar) \
HB_OT_TABLE(OT, avar) \
HB_OT_TABLE(OT, MVAR) \
/* OpenType math. */ \
HB_OT_TABLE(OT, MATH) \
/* OpenType color fonts. */ \
HB_OT_TABLE(OT, COLR) \
HB_OT_TABLE(OT, CPAL) \
HB_OT_ACCELERATOR(OT, CBDT) \
HB_OT_ACCELERATOR(OT, sbix) \
HB_OT_ACCELERATOR(OT, SVG) \
/* */
/* Declare tables. */
#define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t)
HB_OT_TABLES
#include "hb-ot-face-table-list.hh"
#undef HB_OT_ACCELERATOR
#undef HB_OT_TABLE
@ -100,9 +56,7 @@ struct hb_ot_face_t
{
ORDER_ZERO,
#define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type),
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
};
@ -111,7 +65,7 @@ struct hb_ot_face_t
hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
#define HB_OT_ACCELERATOR(Namespace, Type) \
hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
HB_OT_TABLES
#include "hb-ot-face-table-list.hh"
#undef HB_OT_ACCELERATOR
#undef HB_OT_TABLE
};

View File

@ -26,6 +26,8 @@
#include "hb.hh"
#ifndef HB_NO_OT_FONT
#include "hb-ot.h"
#include "hb-font.hh"
@ -37,7 +39,6 @@
#include "hb-ot-cff1-table.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-kern-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-post-table.hh"
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
@ -150,12 +151,14 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
*x = font->get_glyph_h_advance (glyph) / 2;
#ifndef HB_NO_OT_FONT_CFF
const OT::VORG &VORG = *ot_face->VORG;
if (VORG.has_data ())
{
*y = font->em_scale_y (VORG.get_y_origin (glyph));
return true;
}
#endif
hb_glyph_extents_t extents = {0};
if (ot_face->glyf->get_extents (font, glyph, &extents))
@ -203,6 +206,7 @@ hb_ot_get_glyph_extents (hb_font_t *font,
return ret;
}
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
static hb_bool_t
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
void *font_data,
@ -213,7 +217,6 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_name (glyph, name, size);
}
static hb_bool_t
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
void *font_data,
@ -224,6 +227,7 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_from_name (name, len, glyph);
}
#endif
static hb_bool_t
hb_ot_get_font_h_extents (hb_font_t *font,
@ -276,8 +280,10 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
#endif
hb_font_funcs_make_immutable (funcs);
@ -317,3 +323,6 @@ hb_ot_font_set_funcs (hb_font_t *font)
&font->face->table,
nullptr);
}
#endif

View File

@ -128,11 +128,11 @@ struct KernSubTable
TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) {
case 0: return_trace (c->dispatch (u.format0));
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
#endif
case 2: return_trace (c->dispatch (u.format2));
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
#endif
default: return_trace (c->default_return_value ());
@ -282,7 +282,7 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.has_state_machine ();
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 1: return u.aat.has_state_machine ();
#endif
default:return false;
@ -293,7 +293,7 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.has_cross_stream ();
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 1: return u.aat.has_cross_stream ();
#endif
default:return false;
@ -304,7 +304,7 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.get_h_kerning (left, right);
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 1: return u.aat.get_h_kerning (left, right);
#endif
default:return 0;
@ -321,7 +321,7 @@ struct kern
TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) {
case 0: return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
case 1: return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
#endif
default: return_trace (c->default_return_value ());
@ -340,7 +340,7 @@ struct kern
HBUINT32 version32;
HBUINT16 major;
KernOT ot;
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
KernAAT aat;
#endif
} u;

View File

@ -500,6 +500,9 @@ struct FeatureParams
{
bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
{
#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
return true;
#endif
TRACE_SANITIZE (this);
if (tag == HB_TAG ('s','i','z','e'))
return_trace (u.size.sanitize (c));
@ -510,26 +513,26 @@ struct FeatureParams
return_trace (true);
}
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
const FeatureParamsSize& get_size_params (hb_tag_t tag) const
{
if (tag == HB_TAG ('s','i','z','e'))
return u.size;
return Null (FeatureParamsSize);
}
const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
{
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
return u.stylisticSet;
return Null (FeatureParamsStylisticSet);
}
const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
{
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
return u.characterVariants;
return Null (FeatureParamsCharacterVariants);
}
#endif
private:
union {
@ -1695,10 +1698,10 @@ struct VarRegionList
VarRegionList *out = c->allocate_min<VarRegionList> ();
if (unlikely (!out)) return_trace (false);
axisCount = src->axisCount;
regionCount = region_map.get_count ();
regionCount = region_map.get_population ();
if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false);
for (unsigned int r = 0; r < regionCount; r++)
memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.to_old (r)], VarRegionAxis::static_size * axisCount);
memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.backward (r)], VarRegionAxis::static_size * axisCount);
return_trace (true);
}
@ -1760,11 +1763,11 @@ struct VarData
float *scalars /*OUT */,
unsigned int num_scalars) const
{
assert (num_scalars == regionIndices.len);
for (unsigned int i = 0; i < num_scalars; i++)
{
scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
}
unsigned count = hb_min (num_scalars, regionIndices.len);
for (unsigned int i = 0; i < count; i++)
scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
for (unsigned int i = count; i < num_scalars; i++)
scalars[i] = 0.f;
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1785,7 +1788,7 @@ struct VarData
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
itemCount = inner_map.get_count ();
itemCount = inner_map.get_population ();
/* Optimize short count */
unsigned short ri_count = src->regionIndices.len;
@ -1799,9 +1802,9 @@ struct VarData
for (r = 0; r < ri_count; r++)
{
delta_sz[r] = kZero;
for (unsigned int i = 0; i < inner_map.get_count (); i++)
for (unsigned int i = 0; i < inner_map.get_population (); i++)
{
unsigned int old = inner_map.to_old (i);
unsigned int old = inner_map.backward (i);
int16_t delta = src->get_item_delta (old, r);
if (delta < -128 || 127 < delta)
{
@ -1831,11 +1834,11 @@ struct VarData
return_trace (false);
for (r = 0; r < ri_count; r++)
if (delta_sz[r]) regionIndices[ri_map[r]] = region_map.to_new (src->regionIndices[r]);
if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]];
for (unsigned int i = 0; i < itemCount; i++)
{
hb_codepoint_t old = inner_map.to_old (i);
hb_codepoint_t old = inner_map.backward (i);
if (unlikely (old >= src->itemCount)) return_trace (false);
for (unsigned int r = 0; r < ri_count; r++)
if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
@ -1844,14 +1847,14 @@ struct VarData
return_trace (true);
}
void collect_region_refs (hb_bimap_t &region_map, const hb_bimap_t &inner_map) const
void collect_region_refs (hb_inc_bimap_t &region_map, const hb_bimap_t &inner_map) const
{
for (unsigned int r = 0; r < regionIndices.len; r++)
{
unsigned int region = regionIndices[r];
if (region_map.has (region)) continue;
for (unsigned int i = 0; i < inner_map.get_count (); i++)
if (get_item_delta (inner_map.to_old (i), r) != 0)
for (unsigned int i = 0; i < inner_map.get_population (); i++)
if (get_item_delta (inner_map.backward (i), r) != 0)
{
region_map.add (region);
break;
@ -1902,8 +1905,12 @@ struct VariationStore
float get_delta (unsigned int outer, unsigned int inner,
const int *coords, unsigned int coord_count) const
{
#ifdef HB_NO_VAR
return 0.f;
#endif
if (unlikely (outer >= dataSets.len))
return 0.;
return 0.f;
return (this+dataSets[outer]).get_delta (inner,
coords, coord_count,
@ -1920,6 +1927,10 @@ struct VariationStore
bool sanitize (hb_sanitize_context_t *c) const
{
#ifdef HB_NO_VAR
return true;
#endif
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
format == 1 &&
@ -1929,21 +1940,21 @@ struct VariationStore
bool serialize (hb_serialize_context_t *c,
const VariationStore *src,
const hb_array_t <hb_bimap_t> &inner_remaps)
const hb_array_t <hb_inc_bimap_t> &inner_remaps)
{
TRACE_SERIALIZE (this);
unsigned int set_count = 0;
for (unsigned int i = 0; i < inner_remaps.length; i++)
if (inner_remaps[i].get_count () > 0) set_count++;
if (inner_remaps[i].get_population () > 0) set_count++;
unsigned int size = min_size + HBUINT32::static_size * set_count;
if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
format = 1;
hb_bimap_t region_map;
hb_inc_bimap_t region_map;
for (unsigned int i = 0; i < inner_remaps.length; i++)
(src+src->dataSets[i]).collect_region_refs (region_map, inner_remaps[i]);
region_map.reorder ();
region_map.sort ();
if (unlikely (!regions.serialize (c, this)
.serialize (c, &(src+src->regions), region_map))) return_trace (false);
@ -1955,7 +1966,7 @@ struct VariationStore
unsigned int set_index = 0;
for (unsigned int i = 0; i < inner_remaps.length; i++)
{
if (inner_remaps[i].get_count () == 0) continue;
if (inner_remaps[i].get_population () == 0) continue;
if (unlikely (!dataSets[set_index++].serialize (c, this)
.serialize (c, &(src+src->dataSets[i]), inner_remaps[i], region_map)))
return_trace (false);
@ -1972,6 +1983,12 @@ struct VariationStore
float *scalars /*OUT*/,
unsigned int num_scalars) const
{
#ifdef HB_NO_VAR
for (unsigned i = 0; i < num_scalars; i++)
scalars[i] = 0.f;
return;
#endif
(this+dataSets[ivs]).get_scalars (coords, coord_count, this+regions,
&scalars[0], num_scalars);
}
@ -2316,10 +2333,14 @@ struct Device
{
switch (u.b.format)
{
#ifndef HB_NO_HINTING
case 1: case 2: case 3:
return u.hinting.get_x_delta (font);
#endif
#ifndef HB_NO_VAR
case 0x8000:
return u.variation.get_x_delta (font, store);
#endif
default:
return 0;
}
@ -2329,9 +2350,13 @@ struct Device
switch (u.b.format)
{
case 1: case 2: case 3:
#ifndef HB_NO_HINTING
return u.hinting.get_y_delta (font);
#endif
#ifndef HB_NO_VAR
case 0x8000:
return u.variation.get_y_delta (font, store);
#endif
default:
return 0;
}
@ -2342,10 +2367,14 @@ struct Device
TRACE_SANITIZE (this);
if (!u.b.format.sanitize (c)) return_trace (false);
switch (u.b.format) {
#ifndef HB_NO_HINTING
case 1: case 2: case 3:
return_trace (u.hinting.sanitize (c));
#endif
#ifndef HB_NO_VAR
case 0x8000:
return_trace (u.variation.sanitize (c));
#endif
default:
return_trace (true);
}
@ -2355,7 +2384,9 @@ struct Device
union {
DeviceHeader b;
HintingDevice hinting;
#ifndef HB_NO_VAR
VariationDevice variation;
#endif
} u;
public:
DEFINE_SIZE_UNION (6, b);

View File

@ -267,6 +267,13 @@ struct AnchorFormat2
float *x, float *y) const
{
hb_font_t *font = c->font;
#ifdef HB_NO_HINTING
*x = font->em_fscale_x (xCoordinate);
*y = font->em_fscale_y (yCoordinate);
return;
#endif
unsigned int x_ppem = font->x_ppem;
unsigned int y_ppem = font->y_ppem;
hb_position_t cx = 0, cy = 0;
@ -1730,13 +1737,13 @@ struct GPOS_accelerator_t : GPOS::accelerator_t {};
/* Out-of-class implementation for methods recursing */
#ifndef HB_NO_OT_LAYOUT
template <typename context_t>
/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
{
const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
return l.dispatch (c);
}
/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
@ -1749,6 +1756,7 @@ template <typename context_t>
c->set_lookup_props (saved_lookup_props);
return ret;
}
#endif
} /* namespace OT */

View File

@ -1409,6 +1409,7 @@ struct GSUB_accelerator_t : GSUB::accelerator_t {};
/* Out-of-class implementation for methods recursing */
#ifndef HB_NO_OT_LAYOUT
/*static*/ inline bool ExtensionSubst::is_reverse () const
{
unsigned int type = get_type ();
@ -1416,14 +1417,12 @@ struct GSUB_accelerator_t : GSUB::accelerator_t {};
return CastR<ExtensionSubst> (get_subtable<SubTable>()).is_reverse ();
return SubstLookup::lookup_type_is_reverse (type);
}
template <typename context_t>
/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
{
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
return l.dispatch (c);
}
/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
@ -1436,6 +1435,8 @@ template <typename context_t>
c->set_lookup_props (saved_lookup_props);
return ret;
}
#endif
} /* namespace OT */

View File

@ -483,7 +483,13 @@ struct hb_ot_apply_context_t :
iter_input (), iter_context (),
font (font_), face (font->face), buffer (buffer_),
recurse_func (nullptr),
gdef (*face->table.GDEF->table),
gdef (
#ifndef HB_NO_OT_LAYOUT
*face->table.GDEF->table
#else
Null(GDEF)
#endif
),
var_store (gdef.get_var_store ()),
direction (buffer_->props.direction),
lookup_mask (1),
@ -2661,11 +2667,17 @@ struct GSUBGPOS
bool find_variations_index (const int *coords, unsigned int num_coords,
unsigned int *index) const
{ return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
.find_index (coords, num_coords, index); }
{
#ifdef HB_NOVAR
return false;
#endif
return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
.find_index (coords, num_coords, index);
}
const Feature& get_feature_variation (unsigned int feature_index,
unsigned int variations_index) const
{
#ifndef HB_NO_VAR
if (FeatureVariations::NOT_FOUND_INDEX != variations_index &&
version.to_int () >= 0x00010001u)
{
@ -2674,6 +2686,7 @@ struct GSUBGPOS
if (feature)
return *feature;
}
#endif
return get_feature (feature_index);
}
@ -2695,8 +2708,10 @@ struct GSUBGPOS
this,
out);
#ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u)
out->featureVars.serialize_copy (c->serializer, featureVars, this, out);
#endif
return_trace (true);
}
@ -2712,12 +2727,19 @@ struct GSUBGPOS
{
TRACE_SANITIZE (this);
typedef OffsetListOf<TLookup> TLookupList;
return_trace (version.sanitize (c) &&
likely (version.major == 1) &&
scriptList.sanitize (c, this) &&
featureList.sanitize (c, this) &&
CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this) &&
(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
if (unlikely (!(version.sanitize (c) &&
likely (version.major == 1) &&
scriptList.sanitize (c, this) &&
featureList.sanitize (c, this) &&
CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this))))
return_trace (false);
#ifndef HB_NO_VAR
if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this))))
return_trace (false);
#endif
return_trace (true);
}
template <typename T>

View File

@ -28,6 +28,14 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_LAYOUT
#ifdef HB_NO_OT_TAG
#error "Cannot compile hb-ot-layout.cc with HB_NO_OT_TAG."
#endif
#include "hb-open-type.hh"
#include "hb-ot-layout.hh"
#include "hb-ot-face.hh"
@ -62,6 +70,7 @@
* kern
*/
#ifndef HB_NO_OT_KERN
/**
* hb_ot_layout_has_kerning:
* @face: The #hb_face_t to work on
@ -78,7 +87,6 @@ hb_ot_layout_has_kerning (hb_face_t *face)
return face->table.kern->has_data ();
}
/**
* hb_ot_layout_has_machine_kerning:
* @face: The #hb_face_t to work on
@ -95,7 +103,6 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
return face->table.kern->has_state_machine ();
}
/**
* hb_ot_layout_has_cross_kerning:
* @face: The #hb_face_t to work on
@ -128,6 +135,7 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
kern.apply (&c);
}
#endif
/*
@ -311,6 +319,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
}
#ifndef HB_NO_LAYOUT_UNUSED
/**
* hb_ot_layout_get_attach_points:
* @face: The #hb_face_t to work on
@ -333,19 +342,11 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (point_count)
*point_count = 0;
return 0;
#endif
return face->table.GDEF->table->get_attach_points (glyph,
start_offset,
point_count,
point_array);
}
/**
* hb_ot_layout_get_ligature_carets:
* @font: The #hb_font_t to work on
@ -368,22 +369,19 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (caret_count)
*caret_count = 0;
return 0;
#endif
unsigned int result_caret_count = 0;
unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array);
if (result)
{
if (caret_count) *caret_count = result_caret_count;
}
#ifndef HB_NO_AAT
else
result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
#endif
return result;
}
#endif
/*
@ -397,6 +395,8 @@ OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
return false;
#endif
#ifndef HB_NO_AAT_SHAPE
/* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts,
* all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
* GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by
@ -414,6 +414,7 @@ OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') &&
face->table.morx->has_data ()))
return true;
#endif
return false;
}
@ -1210,6 +1211,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
}
#ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
/**
* hb_ot_layout_lookup_collect_glyphs:
* @face: #hb_face_t to work upon
@ -1256,6 +1258,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
}
}
}
#endif
/* Variations support */
@ -1564,6 +1567,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
}
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
/**
* hb_ot_layout_get_size_params:
* @face: #hb_face_t to work upon
@ -1626,8 +1630,6 @@ hb_ot_layout_get_size_params (hb_face_t *face,
return false;
}
/**
* hb_ot_layout_feature_get_name_ids:
* @face: #hb_face_t to work upon
@ -1702,8 +1704,6 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face,
if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID;
return false;
}
/**
* hb_ot_layout_feature_get_characters:
* @face: #hb_face_t to work upon
@ -1757,6 +1757,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
if (char_count) *char_count = len;
return cv_params.characters.len;
}
#endif
/*
@ -1941,11 +1942,6 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
}
#if 0
static const OT::BASE& _get_base (hb_face_t *face)
{
return *face->table.BASE;
}
hb_bool_t
hb_ot_layout_get_baseline (hb_font_t *font,
hb_ot_layout_baseline_t baseline,
@ -1954,9 +1950,8 @@ hb_ot_layout_get_baseline (hb_font_t *font,
hb_tag_t language_tag,
hb_position_t *coord /* OUT. May be NULL. */)
{
const OT::BASE &base = _get_base (font->face);
bool result = base.get_baseline (font, baseline, direction, script_tag,
language_tag, coord);
bool result = font->face->table.BASE->get_baseline (font, baseline, direction, script_tag,
language_tag, coord);
/* TODO: Simulate https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideographic-em-box */
if (!result && coord) *coord = 0;
@ -2013,3 +2008,6 @@ hb_ot_layout_get_baseline (hb_font_t *font,
hb_position_t *coord /* OUT. May be NULL. */);
#endif
#endif

View File

@ -168,6 +168,17 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
return start;
}
static inline void
_hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
/* unicode_props */
@ -551,6 +562,17 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
}
static inline void
_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_clear_substituted (&info[i]);
}
/* Allocation / deallocation. */

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-map.hh"
#include "hb-ot-shape.hh"
#include "hb-ot-layout.hh"
@ -332,3 +336,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
}
}
}
#endif

View File

@ -154,8 +154,8 @@ struct hb_ot_map_t
HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
template <typename Proxy>
HB_INTERNAL inline void apply (const Proxy &proxy,
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void apply (const Proxy &proxy,
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;

View File

@ -453,14 +453,14 @@ struct MathGlyphPartRecord
}
void extract (hb_ot_math_glyph_part_t &out,
int scale,
int64_t mult,
hb_font_t *font) const
{
out.glyph = glyph;
out.start_connector_length = font->em_scale (startConnectorLength, scale);
out.end_connector_length = font->em_scale (endConnectorLength, scale);
out.full_advance = font->em_scale (fullAdvance, scale);
out.start_connector_length = font->em_mult (startConnectorLength, mult);
out.end_connector_length = font->em_mult (endConnectorLength, mult);
out.full_advance = font->em_mult (fullAdvance, mult);
static_assert ((unsigned int) HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER ==
(unsigned int) PartFlags::Extender, "");
@ -508,11 +508,11 @@ struct MathGlyphAssembly
{
if (parts_count)
{
int scale = font->dir_scale (direction);
int64_t mult = font->dir_mult (direction);
hb_array_t<const MathGlyphPartRecord> arr = partRecords.sub_array (start_offset, parts_count);
unsigned int count = arr.length;
for (unsigned int i = 0; i < count; i++)
arr[i].extract (parts[i], scale, font);
arr[i].extract (parts[i], mult, font);
}
if (italics_correction)
@ -553,13 +553,13 @@ struct MathGlyphConstruction
{
if (variants_count)
{
int scale = font->dir_scale (direction);
int64_t mult = font->dir_mult (direction);
hb_array_t<const MathGlyphVariantRecord> arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count);
unsigned int count = arr.length;
for (unsigned int i = 0; i < count; i++)
{
variants[i].glyph = arr[i].variantGlyph;
variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
variants[i].advance = font->em_mult (arr[i].advanceMeasurement, mult);
}
}
return mathGlyphVariantRecord.len;

View File

@ -24,9 +24,10 @@
* Igalia Author(s): Frédéric Wang
*/
#include "hb-open-type.hh"
#include "hb.hh"
#ifndef HB_NO_MATH
#include "hb-ot-face.hh"
#include "hb-ot-math-table.hh"
@ -62,10 +63,6 @@
hb_bool_t
hb_ot_math_has_data (hb_face_t *face)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->has_data ();
}
@ -90,10 +87,6 @@ hb_position_t
hb_ot_math_get_constant (hb_font_t *font,
hb_ot_math_constant_t constant)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_constant(constant, font);
}
@ -113,10 +106,6 @@ hb_position_t
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
}
@ -143,10 +132,6 @@ hb_position_t
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
}
@ -165,10 +150,6 @@ hb_bool_t
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
}
@ -197,10 +178,6 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
hb_ot_math_kern_t kern,
hb_position_t correction_height)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
kern,
correction_height,
@ -238,12 +215,6 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
unsigned int *variants_count, /* IN/OUT */
hb_ot_math_glyph_variant_t *variants /* OUT */)
{
#ifdef HB_NO_MATH
if (variants_count)
*variants_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
start_offset,
variants_count,
@ -272,10 +243,6 @@ hb_position_t
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
hb_direction_t direction)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
}
@ -313,12 +280,6 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
hb_ot_math_glyph_part_t *parts, /* OUT */
hb_position_t *italics_correction /* OUT */)
{
#ifdef HB_NO_MATH
if (parts_count)
*parts_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
direction,
font,
@ -327,3 +288,6 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
parts,
italics_correction);
}
#endif

View File

@ -63,7 +63,7 @@ struct NameRecord
#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
if (p == 0)
return _hb_aat_language_get (face, l);
return face->table.ltag->get_language (l);
#endif
#endif

View File

@ -26,9 +26,10 @@
#include "hb.hh"
#ifndef HB_NO_NAME
#include "hb-ot-name-table.hh"
#include "hb-ot-face.hh"
#include "hb-utf.hh"
@ -58,11 +59,6 @@ const hb_ot_name_entry_t *
hb_ot_name_list_names (hb_face_t *face,
unsigned int *num_entries /* OUT */)
{
#ifdef HB_NO_NAME
if (num_entries)
*num_entries = 0;
return 0;
#endif
const OT::name_accelerator_t &name = *face->table.name;
if (num_entries) *num_entries = name.names.length;
return (const hb_ot_name_entry_t *) name.names;
@ -172,11 +168,6 @@ hb_ot_name_get_utf8 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
char *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf8_t> (face, name_id, language, text_size,
(hb_utf8_t::codepoint_t *) text);
}
@ -204,11 +195,6 @@ hb_ot_name_get_utf16 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint16_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf16_t> (face, name_id, language, text_size, text);
}
@ -235,10 +221,8 @@ hb_ot_name_get_utf32 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint32_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
}
#endif

View File

@ -164,8 +164,9 @@ struct OS2
void _update_unicode_ranges (const hb_set_t *codepoints,
HBUINT32 ulUnicodeRange[4]) const
{
HBUINT32 newBits[4];
for (unsigned int i = 0; i < 4; i++)
ulUnicodeRange[i] = 0;
newBits[i] = 0;
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
while (codepoints->next (&cp)) {
@ -175,16 +176,19 @@ struct OS2
unsigned int block = bit / 32;
unsigned int bit_in_block = bit % 32;
unsigned int mask = 1 << bit_in_block;
ulUnicodeRange[block] = ulUnicodeRange[block] | mask;
newBits[block] = newBits[block] | mask;
}
if (cp >= 0x10000 && cp <= 0x110000)
{
/* the spec says that bit 57 ("Non Plane 0") implies that there's
at least one codepoint beyond the BMP; so I also include all
the non-BMP codepoints here */
ulUnicodeRange[1] = ulUnicodeRange[1] | (1 << 25);
newBits[1] = newBits[1] | (1 << 25);
}
}
for (unsigned int i = 0; i < 4; i++)
ulUnicodeRange[i] = ulUnicodeRange[i] & newBits[i]; // set bits only if set in the original
}
static void find_min_and_max_codepoint (const hb_set_t *codepoints,

View File

@ -25,6 +25,9 @@
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-arabic.hh"
#include "hb-ot-shape.hh"
@ -710,3 +713,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
#endif

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex.hh"
@ -44,3 +48,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
#endif

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex.hh"
@ -430,3 +434,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
#endif

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex.hh"
@ -176,3 +180,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
#endif

View File

@ -395,13 +395,13 @@ static const int indic_syllable_machine_en_main = 39;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_indic (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
@ -569,4 +569,6 @@ _again:
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */

View File

@ -96,13 +96,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_indic (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
@ -121,4 +121,6 @@ find_syllables (hb_buffer_t *buffer)
}%%
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */

View File

@ -14,6 +14,10 @@
* # Date: 2018-07-30, 19:40:00 GMT [KW]
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-indic.hh"
#pragma GCC diagnostic push
@ -487,4 +491,6 @@ hb_indic_get_categories (hb_codepoint_t u)
#undef IMC_TR
#undef IMC_VOL
#endif
/* == End of generated table == */

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-indic.hh"
#include "hb-ot-shape-complex-vowel-constraints.hh"
#include "hb-ot-layout.hh"
@ -140,49 +144,45 @@ indic_features[] =
* Must be in the same order as the indic_features array.
*/
enum {
_NUKT,
_AKHN,
RPHF,
_RKRF,
PREF,
BLWF,
ABVF,
HALF,
PSTF,
_VATU,
_CJCT,
_INDIC_NUKT,
_INDIC_AKHN,
INDIC_RPHF,
_INDIC_RKRF,
INDIC_PREF,
INDIC_BLWF,
INDIC_ABVF,
INDIC_HALF,
INDIC_PSTF,
_INDIC_VATU,
_INDIC_CJCT,
INIT,
_PRES,
_ABVS,
_BLWS,
_PSTS,
_HALN,
INDIC_INIT,
_INDIC_PRES,
_INDIC_ABVS,
_INDIC_BLWS,
_INDIC_PSTS,
_INDIC_HALN,
_DIST,
_ABVM,
_BLWM,
_INDIC_DIST,
_INDIC_ABVM,
_INDIC_BLWM,
INDIC_NUM_FEATURES,
INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@ -190,7 +190,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_indic);
map->enable_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
@ -199,14 +199,14 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
map->add_gsub_pause (initial_reordering_indic);
for (; i < INDIC_BASIC_FEATURES; i++) {
map->add_feature (indic_features[i]);
map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (final_reordering);
map->add_gsub_pause (final_reordering_indic);
for (; i < INDIC_NUM_FEATURES; i++)
map->add_feature (indic_features[i]);
@ -214,7 +214,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('c','a','l','t'));
map->enable_feature (HB_TAG('c','l','i','g'));
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
}
static void
@ -224,32 +224,6 @@ override_features_indic (hb_ot_shape_planner_t *plan)
}
struct would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
struct indic_shape_plan_t
{
bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@ -281,10 +255,10 @@ struct indic_shape_plan_t
#endif
mutable hb_atomic_int_t virama_glyph;
would_substitute_feature_t rphf;
would_substitute_feature_t pref;
would_substitute_feature_t blwf;
would_substitute_feature_t pstf;
hb_indic_would_substitute_feature_t rphf;
hb_indic_would_substitute_feature_t pref;
hb_indic_would_substitute_feature_t blwf;
hb_indic_would_substitute_feature_t pstf;
hb_mask_t mask_array[INDIC_NUM_FEATURES];
};
@ -367,13 +341,13 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
}
enum syllable_type_t {
consonant_syllable,
vowel_syllable,
standalone_cluster,
symbol_cluster,
broken_cluster,
non_indic_cluster,
enum indic_syllable_type_t {
indic_consonant_syllable,
indic_vowel_syllable,
indic_standalone_cluster,
indic_symbol_cluster,
indic_broken_cluster,
indic_non_indic_cluster,
};
#include "hb-ot-shape-complex-indic-machine.hh"
@ -397,11 +371,11 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_indic (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -418,9 +392,9 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
static void
update_consonant_positions (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
@ -493,7 +467,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
if (indic_plan->mask_array[RPHF] &&
if (indic_plan->mask_array[INDIC_RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@ -829,13 +803,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Reph */
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
info[i].mask |= indic_plan->mask_array[RPHF];
info[i].mask |= indic_plan->mask_array[INDIC_RPHF];
/* Pre-base */
mask = indic_plan->mask_array[HALF];
mask = indic_plan->mask_array[INDIC_HALF];
if (!indic_plan->is_old_spec &&
indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
mask |= indic_plan->mask_array[BLWF];
mask |= indic_plan->mask_array[INDIC_BLWF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
/* Base */
@ -843,7 +817,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end)
info[base].mask |= mask;
/* Post-base */
mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
mask = indic_plan->mask_array[INDIC_BLWF] |
indic_plan->mask_array[INDIC_ABVF] |
indic_plan->mask_array[INDIC_PSTF];
for (unsigned int i = base + 1; i < end; i++)
info[i].mask |= mask;
}
@ -875,13 +851,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
(i + 2 == base ||
info[i+2].indic_category() != OT_ZWJ))
{
info[i ].mask |= indic_plan->mask_array[BLWF];
info[i+1].mask |= indic_plan->mask_array[BLWF];
info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
}
}
unsigned int pref_len = 2;
if (indic_plan->mask_array[PREF] && base + pref_len < end)
if (indic_plan->mask_array[INDIC_PREF] && base + pref_len < end)
{
/* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
@ -891,7 +867,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
for (unsigned int j = 0; j < pref_len; j++)
info[i++].mask |= indic_plan->mask_array[PREF];
info[i++].mask |= indic_plan->mask_array[INDIC_PREF];
break;
}
}
@ -912,7 +888,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* A ZWNJ disables HALF. */
if (non_joiner)
info[j].mask &= ~indic_plan->mask_array[HALF];
info[j].mask &= ~indic_plan->mask_array[INDIC_HALF];
} while (j > start && !is_consonant (info[j]));
}
@ -941,34 +917,34 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
}
static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
case consonant_syllable:
case indic_vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
case indic_consonant_syllable:
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
break;
case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
case standalone_cluster:
case indic_broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
case indic_standalone_cluster:
initial_reordering_standalone_cluster (plan, face, buffer, start, end);
break;
case symbol_cluster:
case non_indic_cluster:
case indic_symbol_cluster:
case indic_non_indic_cluster:
break;
}
}
static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
@ -979,7 +955,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == indic_broken_cluster)
{
has_broken_syllables = true;
break;
@ -1004,8 +980,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster))
{
last_syllable = syllable;
@ -1029,21 +1005,21 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
update_consonant_positions (plan, font, buffer);
insert_dotted_circles (plan, font, buffer);
update_consonant_positions_indic (plan, font, buffer);
insert_dotted_circles_indic (plan, font, buffer);
foreach_syllable (buffer, start, end)
initial_reordering_syllable (plan, font->face, buffer, start, end);
initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
}
static void
final_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
@ -1079,7 +1055,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* syllable.
*/
bool try_pref = !!indic_plan->mask_array[PREF];
bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
/* Find base again */
unsigned int base;
@ -1089,7 +1065,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end)
{
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
{
if (!(_hb_glyph_info_substituted (&info[i]) &&
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
@ -1411,7 +1387,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
{
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
{
/* 1. Only reorder a glyph produced by substitution during application
* of the <pref> feature. (Note that a font may shape a Ra consonant with
@ -1474,7 +1450,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (!start ||
!(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
info[start].mask |= indic_plan->mask_array[INIT];
info[start].mask |= indic_plan->mask_array[INDIC_INIT];
else
buffer->unsafe_to_break (start - 1, start + 1);
}
@ -1504,33 +1480,21 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (unlikely (!count)) return;
foreach_syllable (buffer, start, end)
final_reordering_syllable (plan, buffer, start, end);
final_reordering_syllable_indic (plan, buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static void
preprocess_text_indic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@ -1648,3 +1612,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
#endif

View File

@ -64,7 +64,14 @@ enum indic_category_t {
OT_Ra = 16,
OT_CM = 17, /* Consonant-Medial. */
OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
OT_CS = 19
OT_CS = 19,
/* The following are used by Khmer & Myanmar shapers. Defined
* here for them to share. */
OT_VAbv = 26,
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
};
#define MEDIAL_FLAGS (FLAG (OT_CM))
@ -359,7 +366,7 @@ set_indic_properties (hb_glyph_info_t &info)
/* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
* so the Indic shaper needs to know their categories. */
else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM;
else if (unlikely (u == 0x1133cu)) cat = OT_N;
else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N;
else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */
@ -398,5 +405,31 @@ set_indic_properties (hb_glyph_info_t &info)
info.indic_position() = pos;
}
struct hb_indic_would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */

View File

@ -226,13 +226,13 @@ static const int khmer_syllable_machine_en_main = 20;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_khmer (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
@ -367,4 +367,6 @@ _again:
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

View File

@ -83,13 +83,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_khmer (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
@ -108,4 +108,6 @@ find_syllables (hb_buffer_t *buffer)
}%%
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-khmer.hh"
#include "hb-ot-layout.hh"
@ -65,37 +69,33 @@ khmer_features[] =
* Must be in the same order as the khmer_features array.
*/
enum {
PREF,
BLWF,
ABVF,
PSTF,
CFAR,
KHMER_PREF,
KHMER_BLWF,
KHMER_ABVF,
KHMER_PSTF,
KHMER_CFAR,
_PRES,
_ABVS,
_BLWS,
_PSTS,
_KHMER_PRES,
_KHMER_ABVS,
_KHMER_BLWS,
_KHMER_PSTS,
_DIST,
_ABVM,
_BLWM,
_KHMER_DIST,
_KHMER_ABVM,
_KHMER_BLWM,
KHMER_NUM_FEATURES,
KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_khmer (hb_ot_shape_planner_t *plan)
@ -103,8 +103,8 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (reorder);
map->add_gsub_pause (setup_syllables_khmer);
map->add_gsub_pause (reorder_khmer);
/* Testing suggests that Uniscribe does NOT pause between basic
* features. Test with KhmerUI.ttf and the following three
@ -123,7 +123,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
for (; i < KHMER_BASIC_FEATURES; i++)
map->add_feature (khmer_features[i]);
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
for (; i < KHMER_NUM_FEATURES; i++)
map->add_feature (khmer_features[i]);
@ -149,32 +149,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
}
struct would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
struct khmer_shape_plan_t
{
bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@ -198,7 +172,7 @@ struct khmer_shape_plan_t
mutable hb_codepoint_t virama_glyph;
would_substitute_feature_t pref;
hb_indic_would_substitute_feature_t pref;
hb_mask_t mask_array[KHMER_NUM_FEATURES];
};
@ -228,10 +202,10 @@ data_destroy_khmer (void *data)
}
enum syllable_type_t {
consonant_syllable,
broken_cluster,
non_khmer_cluster,
enum khmer_syllable_type_t {
khmer_consonant_syllable,
khmer_broken_cluster,
khmer_non_khmer_cluster,
};
#include "hb-ot-shape-complex-khmer-machine.hh"
@ -253,11 +227,11 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_khmer (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -278,7 +252,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Setup masks. */
{
/* Post-base */
hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
hb_mask_t mask = khmer_plan->mask_array[KHMER_BLWF] |
khmer_plan->mask_array[KHMER_ABVF] |
khmer_plan->mask_array[KHMER_PSTF];
for (unsigned int i = start + 1; i < end; i++)
info[i].mask |= mask;
}
@ -305,7 +281,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[i + 1].khmer_category() == OT_Ra)
{
for (unsigned int j = 0; j < 2; j++)
info[i + j].mask |= khmer_plan->mask_array[PREF];
info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
/* Move the Coeng,Ro sequence to the start. */
buffer->merge_clusters (start, i + 2);
@ -321,9 +297,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
if (khmer_plan->mask_array[CFAR])
if (khmer_plan->mask_array[KHMER_CFAR])
for (unsigned int j = i + 2; j < end; j++)
info[j].mask |= khmer_plan->mask_array[CFAR];
info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
num_coengs = 2; /* Done. */
}
@ -342,28 +318,28 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case consonant_syllable:
case khmer_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case khmer_consonant_syllable:
reorder_consonant_syllable (plan, face, buffer, start, end);
break;
case non_khmer_cluster:
case khmer_non_khmer_cluster:
break;
}
}
static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
@ -374,7 +350,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == khmer_broken_cluster)
{
has_broken_syllables = true;
break;
@ -399,8 +375,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster))
{
last_syllable = syllable;
@ -424,29 +400,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
insert_dotted_circles_khmer (plan, font, buffer);
foreach_syllable (buffer, start, end)
initial_reordering_syllable (plan, font->face, buffer, start, end);
reorder_syllable_khmer (plan, font->face, buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static bool
decompose_khmer (const hb_ot_shape_normalize_context_t *c,
@ -502,3 +467,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
#endif

View File

@ -43,11 +43,10 @@ enum khmer_category_t
OT_Robatic = 20,
OT_Xgroup = 21,
OT_Ygroup = 22,
OT_VAbv = 26,
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
//OT_VAbv = 26,
//OT_VBlw = 27,
//OT_VPre = 28,
//OT_VPst = 29,
};
static inline void
@ -100,10 +99,10 @@ set_khmer_properties (hb_glyph_info_t &info)
if (cat == (khmer_category_t) OT_M)
switch ((int) pos)
{
case POS_PRE_C: cat = OT_VPre; break;
case POS_BELOW_C: cat = OT_VBlw; break;
case POS_ABOVE_C: cat = OT_VAbv; break;
case POS_POST_C: cat = OT_VPst; break;
case POS_PRE_C: cat = (khmer_category_t) OT_VPre; break;
case POS_BELOW_C: cat = (khmer_category_t) OT_VBlw; break;
case POS_ABOVE_C: cat = (khmer_category_t) OT_VAbv; break;
case POS_POST_C: cat = (khmer_category_t) OT_VPst; break;
default: assert (0);
}

View File

@ -304,13 +304,13 @@ static const int myanmar_syllable_machine_en_main = 0;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_myanmar (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;

View File

@ -97,13 +97,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_myanmar (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-myanmar.hh"
@ -32,7 +36,7 @@
*/
static const hb_tag_t
basic_features[] =
myanmar_basic_features[] =
{
/*
* Basic features.
@ -44,7 +48,7 @@ basic_features[] =
HB_TAG('p','s','t','f'),
};
static const hb_tag_t
other_features[] =
myanmar_other_features[] =
{
/*
* Other features.
@ -56,7 +60,7 @@ other_features[] =
HB_TAG('p','s','t','s'),
};
static const hb_tag_t
positioning_features[] =
myanmar_positioning_features[] =
{
/*
* Positioning features.
@ -76,15 +80,11 @@ positioning_features[] =
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@ -94,7 +94,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_myanmar);
map->enable_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
@ -102,21 +102,21 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('c','c','m','p'));
map->add_gsub_pause (reorder);
map->add_gsub_pause (reorder_myanmar);
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
{
map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ);
map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
map->enable_feature (other_features[i], F_MANUAL_ZWJ);
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
map->enable_feature (positioning_features[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_positioning_features); i++)
map->enable_feature (myanmar_positioning_features[i]);
}
static void
@ -126,11 +126,11 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
}
enum syllable_type_t {
consonant_syllable,
punctuation_cluster,
broken_cluster,
non_myanmar_cluster,
enum myanmar_syllable_type_t {
myanmar_consonant_syllable,
myanmar_punctuation_cluster,
myanmar_broken_cluster,
myanmar_non_myanmar_cluster,
};
#include "hb-ot-shape-complex-myanmar-machine.hh"
@ -154,11 +154,11 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_myanmar (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -274,29 +274,29 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
}
static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) {
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case consonant_syllable:
case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case myanmar_consonant_syllable:
initial_reordering_consonant_syllable (buffer, start, end);
break;
case punctuation_cluster:
case non_myanmar_cluster:
case myanmar_punctuation_cluster:
case myanmar_non_myanmar_cluster:
break;
}
}
static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
@ -307,7 +307,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster)
{
has_broken_syllables = true;
break;
@ -332,8 +332,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster))
{
last_syllable = syllable;
@ -351,30 +351,19 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
insert_dotted_circles_myanmar (plan, font, buffer);
foreach_syllable (buffer, start, end)
initial_reordering_syllable (plan, font->face, buffer, start, end);
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
@ -415,3 +404,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
#endif

View File

@ -49,10 +49,10 @@ enum myanmar_category_t {
OT_MW = 23, /* Various consonant medial types */
OT_MY = 24, /* Various consonant medial types */
OT_PT = 25, /* Pwo and other tones */
OT_VAbv = 26,
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
//OT_VAbv = 26,
//OT_VBlw = 27,
//OT_VPre = 28,
//OT_VPst = 29,
OT_VS = 30, /* Variation selectors */
OT_P = 31, /* Punctuation */
OT_D = 32, /* Digits except zero */
@ -155,11 +155,11 @@ set_myanmar_properties (hb_glyph_info_t &info)
{
switch ((int) pos)
{
case POS_PRE_C: cat = OT_VPre;
case POS_PRE_C: cat = (myanmar_category_t) OT_VPre;
pos = POS_PRE_M; break;
case POS_ABOVE_C: cat = OT_VAbv; break;
case POS_BELOW_C: cat = OT_VBlw; break;
case POS_POST_C: cat = OT_VPst; break;
case POS_ABOVE_C: cat = (myanmar_category_t) OT_VAbv; break;
case POS_BELOW_C: cat = (myanmar_category_t) OT_VBlw; break;
case POS_POST_C: cat = (myanmar_category_t) OT_VPst; break;
}
}

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex.hh"
@ -385,3 +389,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
false,/* fallback_position */
};
#endif

View File

@ -380,13 +380,13 @@ static const int use_syllable_machine_en_main = 5;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_use (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;

View File

@ -165,13 +165,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_use (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;

View File

@ -15,6 +15,10 @@
* UnicodeData.txt does not have a header.
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-use.hh"
#pragma GCC diagnostic push
@ -851,4 +855,6 @@ hb_use_get_category (hb_codepoint_t u)
#undef VMPst
#undef VMAbv
#endif
/* == End of generated table == */

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-use.hh"
#include "hb-ot-shape-complex-arabic.hh"
#include "hb-ot-shape-complex-vowel-constraints.hh"
@ -40,7 +44,7 @@
*/
static const hb_tag_t
basic_features[] =
use_basic_features[] =
{
/*
* Basic features.
@ -55,28 +59,23 @@ basic_features[] =
HB_TAG('c','j','c','t'),
};
static const hb_tag_t
arabic_features[] =
use_topographical_features[] =
{
HB_TAG('i','s','o','l'),
HB_TAG('i','n','i','t'),
HB_TAG('m','e','d','i'),
HB_TAG('f','i','n','a'),
/* The spec doesn't specify these but we apply anyway, since our Arabic shaper
* does. These are only used in Syriac spec. */
HB_TAG('m','e','d','2'),
HB_TAG('f','i','n','2'),
HB_TAG('f','i','n','3'),
};
/* Same order as arabic_features. Don't need Syriac stuff.*/
/* Same order as use_topographical_features. */
enum joining_form_t {
ISOL,
INIT,
MEDI,
FINA,
_NONE
USE_ISOL,
USE_INIT,
USE_MEDI,
USE_FINA,
_USE_NONE
};
static const hb_tag_t
other_features[] =
use_other_features[] =
{
/*
* Other features.
@ -90,7 +89,7 @@ other_features[] =
HB_TAG('p','s','t','s'),
};
static const hb_tag_t
positioning_features[] =
use_positioning_features[] =
{
/*
* Positioning features.
@ -102,29 +101,21 @@ positioning_features[] =
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_substitution_flags (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_rphf (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_pref (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
record_pref_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_use (hb_ot_shape_planner_t *plan)
@ -132,7 +123,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_use);
/* "Default glyph pre-processing group" */
map->enable_feature (HB_TAG('l','o','c','l'));
@ -141,32 +132,32 @@ collect_features_use (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
/* "Reordering group" */
map->add_gsub_pause (clear_substitution_flags);
map->add_gsub_pause (_hb_clear_substitution_flags);
map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
map->add_gsub_pause (record_rphf);
map->add_gsub_pause (clear_substitution_flags);
map->add_gsub_pause (record_rphf_use);
map->add_gsub_pause (_hb_clear_substitution_flags);
map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
map->add_gsub_pause (record_pref);
map->add_gsub_pause (record_pref_use);
/* "Orthographic unit shaping group" */
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
for (unsigned int i = 0; i < ARRAY_LENGTH (use_basic_features); i++)
map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ);
map->add_gsub_pause (reorder);
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (reorder_use);
map->add_gsub_pause (_hb_clear_syllables);
/* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
map->add_feature (arabic_features[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
map->add_feature (use_topographical_features[i]);
map->add_gsub_pause (nullptr);
/* "Standard typographic presentation" */
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
map->enable_feature (other_features[i], F_MANUAL_ZWJ);
for (unsigned int i = 0; i < ARRAY_LENGTH (use_other_features); i++)
map->enable_feature (use_other_features[i], F_MANUAL_ZWJ);
/* "Positional feature application" */
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
map->enable_feature (positioning_features[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (use_positioning_features); i++)
map->enable_feature (use_positioning_features[i]);
}
struct use_shape_plan_t
@ -243,16 +234,16 @@ data_destroy_use (void *data)
free (data);
}
enum syllable_type_t {
independent_cluster,
virama_terminated_cluster,
sakot_terminated_cluster,
standard_cluster,
number_joiner_terminated_cluster,
numeral_cluster,
symbol_cluster,
broken_cluster,
non_cluster,
enum use_syllable_type_t {
use_independent_cluster,
use_virama_terminated_cluster,
use_sakot_terminated_cluster,
use_standard_cluster,
use_number_joiner_terminated_cluster,
use_numeral_cluster,
use_symbol_cluster,
use_broken_cluster,
use_non_cluster,
};
#include "hb-ot-shape-complex-use-machine.hh"
@ -309,11 +300,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
if (use_plan->arabic_plan)
return;
static_assert ((INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4), "");
static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), "");
hb_mask_t masks[4], all_masks = 0;
for (unsigned int i = 0; i < 4; i++)
{
masks[i] = plan->map.get_1_mask (arabic_features[i]);
masks[i] = plan->map.get_1_mask (use_topographical_features[i]);
if (masks[i] == plan->map.get_global_mask ())
masks[i] = 0;
all_masks |= masks[i];
@ -323,39 +314,39 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
hb_mask_t other_masks = ~all_masks;
unsigned int last_start = 0;
joining_form_t last_form = _NONE;
joining_form_t last_form = _USE_NONE;
hb_glyph_info_t *info = buffer->info;
foreach_syllable (buffer, start, end)
{
syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
switch (syllable_type)
{
case independent_cluster:
case symbol_cluster:
case non_cluster:
case use_independent_cluster:
case use_symbol_cluster:
case use_non_cluster:
/* These don't join. Nothing to do. */
last_form = _NONE;
last_form = _USE_NONE;
break;
case virama_terminated_cluster:
case sakot_terminated_cluster:
case standard_cluster:
case number_joiner_terminated_cluster:
case numeral_cluster:
case broken_cluster:
case use_virama_terminated_cluster:
case use_sakot_terminated_cluster:
case use_standard_cluster:
case use_number_joiner_terminated_cluster:
case use_numeral_cluster:
case use_broken_cluster:
bool join = last_form == FINA || last_form == ISOL;
bool join = last_form == USE_FINA || last_form == USE_ISOL;
if (join)
{
/* Fixup previous syllable's form. */
last_form = last_form == FINA ? MEDI : INIT;
last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT;
for (unsigned int i = last_start; i < start; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
}
/* Form for this syllable. */
last_form = join ? FINA : ISOL;
last_form = join ? USE_FINA : USE_ISOL;
for (unsigned int i = start; i < end; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
@ -367,11 +358,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_use (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
setup_rphf_mask (plan, buffer);
@ -379,20 +370,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
}
static void
clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_clear_substituted (&info[i]);
}
static void
record_rphf (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
@ -413,9 +393,9 @@ record_rphf (const hb_ot_shape_plan_t *plan,
}
static void
record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
@ -432,22 +412,22 @@ record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static inline bool
is_halant (const hb_glyph_info_t &info)
is_halant_use (const hb_glyph_info_t &info)
{
return (info.use_category() == USE_H || info.use_category() == USE_HVM) &&
!_hb_glyph_info_ligated (&info);
}
static void
reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
use_syllable_type_t syllable_type = (use_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
/* Only a few syllable types need reordering. */
if (unlikely (!(FLAG_UNSAFE (syllable_type) &
(FLAG (virama_terminated_cluster) |
FLAG (sakot_terminated_cluster) |
FLAG (standard_cluster) |
FLAG (broken_cluster) |
(FLAG (use_virama_terminated_cluster) |
FLAG (use_sakot_terminated_cluster) |
FLAG (use_standard_cluster) |
FLAG (use_broken_cluster) |
0))))
return;
@ -478,7 +458,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
for (unsigned int i = start + 1; i < end; i++)
{
bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) ||
is_halant (info[i]);
is_halant_use (info[i]);
if (is_post_base_glyph || i == end - 1)
{
/* If we hit a post-base glyph, move before it; otherwise move to the
@ -502,7 +482,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
for (unsigned int i = start; i < end; i++)
{
uint32_t flag = FLAG_UNSAFE (info[i].use_category());
if (is_halant (info[i]))
if (is_halant_use (info[i]))
{
/* If we hit a halant, move after it; otherwise move to the beginning, and
* shift things in between forward. */
@ -522,9 +502,9 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
}
static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
@ -535,7 +515,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == use_broken_cluster)
{
has_broken_syllables = true;
break;
@ -555,8 +535,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster))
{
last_syllable = syllable;
@ -580,29 +560,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
insert_dotted_circles_use (plan, font, buffer);
foreach_syllable (buffer, start, end)
reorder_syllable (buffer, start, end);
reorder_syllable_use (buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static void
preprocess_text_use (const hb_ot_shape_plan_t *plan,
@ -643,3 +612,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
false, /* fallback_position */
};
#endif

View File

@ -13,6 +13,10 @@
* # Date: 2019-01-28, 22:16:47 GMT
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-vowel-constraints.hh"
static void
@ -440,4 +444,6 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
}
#endif
/* == End of generated functions == */

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-fallback.hh"
#include "hb-kern.hh"
@ -587,3 +591,6 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
}
}
#endif

View File

@ -24,6 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-normalize.hh"
#include "hb-ot-shape-complex.hh"
#include "hb-ot-shape.hh"
@ -469,3 +473,6 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->swap_buffers ();
}
}
#endif

View File

@ -26,6 +26,14 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#ifdef HB_NO_OT_LAYOUT
#error "Cannot compile 'ot' shaper with HB_NO_OT_LAYOUT."
#endif
#include "hb-shaper-impl.hh"
#include "hb-ot-shape.hh"
@ -55,7 +63,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
const hb_feature_t *user_features,
unsigned int num_user_features);
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
static inline bool
_hb_apply_morx (hb_face_t *face)
{
@ -78,7 +86,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac
props (*props),
map (face, props),
aat_map (face, props)
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
, apply_morx (_hb_apply_morx (face))
#endif
{
@ -98,21 +106,30 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
plan.props = props;
plan.shaper = shaper;
map.compile (plan.map, key);
#ifndef HB_NO_AAT_SHAPE
if (apply_morx)
aat_map.compile (plan.aat_map);
#endif
#ifndef HB_NO_OT_SHAPE_FRACTIONS
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
#endif
plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
#ifndef HB_NO_OT_KERN
plan.kern_mask = plan.map.get_mask (kern_tag);
plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
plan.requested_kerning = !!plan.kern_mask;
#endif
#ifndef HB_NO_AAT_SHAPE
plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
plan.requested_tracking = !!plan.trak_mask;
#endif
bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
bool disable_gpos = plan.shaper->gpos_tag &&
plan.shaper->gpos_tag != plan.map.chosen_script[1];
@ -128,7 +145,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
* Decide who does substitutions. GSUB, morx, or fallback.
*/
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
plan.apply_morx = apply_morx;
#endif
@ -138,13 +155,13 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
if (0)
;
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
#endif
else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
plan.apply_gpos = true;
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
else if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
#endif
@ -152,29 +169,38 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
if (!plan.apply_kerx && !has_gpos_kern)
{
/* Apparently Apple applies kerx if GPOS kern was not applied. */
if (0)
;
#ifndef HB_NO_SHAPE_AAT
else if (hb_aat_layout_has_positioning (face))
#ifndef HB_NO_AAT_SHAPE
if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
else
#endif
else if (hb_ot_layout_has_kerning (face))
#ifndef HB_NO_OT_KERN
if (hb_ot_layout_has_kerning (face))
plan.apply_kern = true;
#endif
}
plan.zero_marks = script_zero_marks &&
!plan.apply_kerx &&
(!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face));
(!plan.apply_kern
#ifndef HB_NO_OT_KERN
|| !hb_ot_layout_has_machine_kerning (face)
#endif
);
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
!plan.apply_kerx &&
(!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face));
(!plan.apply_kern
#ifndef HB_NO_OT_KERN
|| !hb_ot_layout_has_cross_kerning (face)
#endif
);
plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
script_fallback_mark_positioning;
#ifndef HB_NO_SHAPE_AAT
#ifndef HB_NO_AAT_SHAPE
/* Currently we always apply trak. */
plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
#endif
@ -185,7 +211,9 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face,
const hb_shape_plan_key_t *key)
{
map.init ();
#ifndef HB_NO_AAT_SHAPE
aat_map.init ();
#endif
hb_ot_shape_planner_t planner (face,
&key->props);
@ -213,16 +241,20 @@ hb_ot_shape_plan_t::fini ()
shaper->data_destroy (const_cast<void *> (data));
map.fini ();
#ifndef HB_NO_AAT_SHAPE
aat_map.fini ();
#endif
}
void
hb_ot_shape_plan_t::substitute (hb_font_t *font,
hb_buffer_t *buffer) const
{
#ifndef HB_NO_AAT_SHAPE
if (unlikely (apply_morx))
hb_aat_layout_substitute (this, font, buffer);
else
#endif
map.substitute (this, font, buffer);
}
@ -232,15 +264,21 @@ hb_ot_shape_plan_t::position (hb_font_t *font,
{
if (this->apply_gpos)
map.position (this, font, buffer);
#ifndef HB_NO_AAT_SHAPE
else if (this->apply_kerx)
hb_aat_layout_position (this, font, buffer);
#endif
#ifndef HB_NO_OT_KERN
else if (this->apply_kern)
hb_ot_layout_kern (this, font, buffer);
#endif
else
_hb_ot_shape_fallback_kern (this, font, buffer);
#ifndef HB_NO_AAT_SHAPE
if (this->apply_trak)
hb_aat_layout_track (this, font, buffer);
#endif
}
@ -292,18 +330,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
}
#ifndef HB_NO_OT_SHAPE_FRACTIONS
/* Automatic fractions. */
map->add_feature (HB_TAG ('f','r','a','c'));
map->add_feature (HB_TAG ('n','u','m','r'));
map->add_feature (HB_TAG ('d','n','o','m'));
#endif
/* Random! */
map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
#ifndef HB_NO_AAT_SHAPE
/* Tracking. We enable dummy feature here just to allow disabling
* AAT 'trak' table using features.
* https://github.com/harfbuzz/harfbuzz/issues/1303 */
map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK);
#endif
map->enable_feature (HB_TAG ('H','A','R','F'));
@ -336,6 +378,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
feature->value);
}
#ifndef HB_NO_AAT_SHAPE
if (planner->apply_morx)
{
hb_aat_map_builder_t *aat_map = &planner->aat_map;
@ -345,6 +388,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
aat_map->add_feature (feature->tag, feature->value);
}
}
#endif
if (planner->shaper->override_features)
planner->shaper->override_features (planner);
@ -435,6 +479,7 @@ hb_set_unicode_props (hb_buffer_t *buffer)
{
_hb_glyph_info_set_continuation (&info[i]);
}
#ifndef HB_NO_EMOJI_SEQUENCES
else if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
{
_hb_glyph_info_set_continuation (&info[i]);
@ -446,6 +491,7 @@ hb_set_unicode_props (hb_buffer_t *buffer)
_hb_glyph_info_set_continuation (&info[i]);
}
}
#endif
/* Or part of the Other_Grapheme_Extend that is not marks.
* As of Unicode 11 that is just:
*
@ -569,6 +615,10 @@ hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
static inline void
hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
{
#ifdef HB_NO_OT_SHAPE_FRACTIONS
return;
#endif
if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
!c->plan->has_frac)
return;
@ -779,8 +829,10 @@ static inline void
hb_ot_substitute_post (const hb_ot_shape_context_t *c)
{
hb_ot_hide_default_ignorables (c->buffer, c->font);
#ifndef HB_NO_AAT_SHAPE
if (c->plan->apply_morx)
hb_aat_layout_remove_deleted_glyphs (c->buffer);
#endif
if (c->plan->shaper->postprocess_glyphs)
c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
@ -914,8 +966,10 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
/* Finish off. Has to follow a certain order. */
hb_ot_layout_position_finish_advances (c->font, c->buffer);
hb_ot_zero_width_default_ignorables (c->buffer);
#ifndef HB_NO_AAT_SHAPE
if (c->plan->apply_morx)
hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
#endif
hb_ot_layout_position_finish_offsets (c->font, c->buffer);
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
@ -1102,3 +1156,6 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_shape_plan_destroy (shape_plan);
}
#endif

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