update from master
This commit is contained in:
commit
8bf989ea70
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
|
@ -13,6 +13,7 @@ EXTRA_DIST = \
|
|||
README.mingw.md \
|
||||
README.python.md \
|
||||
BUILD.md \
|
||||
CONFIG.md \
|
||||
RELEASING.md \
|
||||
TESTING.md \
|
||||
CMakeLists.txt \
|
||||
|
|
19
NEWS
19
NEWS
|
@ -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
|
||||
====================================
|
||||
|
|
|
@ -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
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 = \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */")
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.')
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 == */')
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
104
src/hb-algs.hh
104
src/hb-algs.hh
|
@ -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)];
|
||||
};
|
||||
|
||||
|
||||
|
|
130
src/hb-bimap.hh
130
src/hb-bimap.hh
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
@ -308,7 +301,7 @@ struct byte_str_t : hb_ubytes_t
|
|||
: hb_ubytes_t (s, l) {}
|
||||
byte_str_t (const hb_ubytes_t &ub) /* conversion from hb_ubytes_t */
|
||||
: hb_ubytes_t (ub) {}
|
||||
|
||||
|
||||
/* sub-string */
|
||||
byte_str_t sub_str (unsigned int offset, unsigned int len_) const
|
||||
{ return byte_str_t (hb_ubytes_t::sub_array (offset, len_)); }
|
||||
|
@ -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 (); }
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ()); }
|
||||
|
|
32
src/hb-ft.cc
32
src/hb-ft.cc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ®ion_map, const hb_bimap_t &inner_map) const
|
||||
void collect_region_refs (hb_inc_bimap_t ®ion_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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 == */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 == */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 == */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue