Merge branch 'master' into subset-varstore
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2ce6a8e..6ad98d2 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -264,7 +264,7 @@
- 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:
@@ -272,7 +272,7 @@
- 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:
@@ -280,7 +280,7 @@
- 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:
@@ -288,7 +288,7 @@
- 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:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c9ba016..66e4a83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@
endif ()
if (WIN32)
option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
+ option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
endif ()
option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
@@ -77,6 +78,7 @@
set (HB_HAVE_GRAPHITE2 ON)
if (WIN32)
set (HB_HAVE_UNISCRIBE ON)
+ set (HB_HAVE_GDI ON)
set (HB_HAVE_DIRECTWRITE ON)
elseif (APPLE)
set (HB_HAVE_CORETEXT ON)
@@ -140,8 +142,8 @@
## Extract variables from Makefile files
function (extract_make_variable variable makefile_source)
- string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
- string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
+ string(REGEX MATCH "${variable} = ([^$]+)\\$" temp "${makefile_source}")
+ string(REGEX MATCHALL "[^ \n\t\\]+" listVar "${CMAKE_MATCH_1}")
set (${variable} ${listVar} PARENT_SCOPE)
endfunction ()
@@ -157,8 +159,6 @@
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/")
@@ -192,59 +192,12 @@
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}
-)
-
-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)
@@ -257,7 +210,6 @@
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
@@ -275,7 +227,6 @@
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})
@@ -296,7 +247,6 @@
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})
@@ -316,7 +266,6 @@
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})
@@ -328,7 +277,6 @@
# 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)
@@ -359,21 +307,21 @@
endif ()
endif ()
+if (WIN32 AND HB_HAVE_GDI)
+ add_definitions(-DHAVE_GDI)
+ list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
+ list(APPEND THIRD_PARTY_LIBS gdi32)
+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 ()
@@ -481,7 +429,6 @@
)
endif ()
-
## Atomic ops availability detection
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
" void memory_barrier (void) { __sync_synchronize (); }
@@ -590,7 +537,6 @@
endif ()
if (HB_HAVE_INTROSPECTION)
-
find_package(PkgConfig)
pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
@@ -824,7 +770,7 @@
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
@@ -833,7 +779,7 @@
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)
diff --git a/appveyor.yml b/appveyor.yml
index 236bb1b..6daf8d2 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -73,7 +73,7 @@
- 'if "%compiler%"=="msvc2" cmake --build build --config %configuration%'
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"'
- - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
+ - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --with-gdi --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
cache:
- c:\tools\vcpkg\installed\
diff --git a/configure.ac b/configure.ac
index 09ce4e6..cebb10a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -361,6 +361,28 @@
dnl ===========================================================================
+AC_ARG_WITH(gdi,
+ [AS_HELP_STRING([--with-gdi=@<:@yes/no/auto@:>@],
+ [Provide GDI integration helpers @<:@default=no@:>@])],,
+ [with_gdi=no])
+have_gdi=false
+if test "x$with_gdi" = "xyes" -o "x$with_gdi" = "xauto"; then
+ AC_CHECK_HEADERS(windows.h, have_gdi=true)
+fi
+if test "x$with_gdi" = "xyes" -a "x$have_gdi" != "xtrue"; then
+ AC_MSG_ERROR([gdi support requested but not found])
+fi
+if $have_gdi; then
+ GDI_CFLAGS=
+ GDI_LIBS="-lgdi32"
+ AC_SUBST(GDI_CFLAGS)
+ AC_SUBST(GDI_LIBS)
+ AC_DEFINE(HAVE_GDI, 1, [Have GDI library])
+fi
+AM_CONDITIONAL(HAVE_GDI, $have_gdi)
+
+dnl ===========================================================================
+
AC_ARG_WITH(directwrite,
[AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@],
[Use the DirectWrite library (experimental) @<:@default=no@:>@])],,
@@ -510,6 +532,7 @@
Platform shapers (not normally needed):
CoreText: ${have_coretext}
DirectWrite: ${have_directwrite}
+ GDI: ${have_gdi}
Uniscribe: ${have_uniscribe}
Other features:
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 4be248d..99916eb 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -1,6 +1,7 @@
<SUBSECTION Private>
HB_H_IN
HB_OT_H_IN
+HB_AAT_H_IN
</SECTION>
<SECTION>
@@ -179,6 +180,7 @@
HB_SCRIPT_CANADIAN_ABORIGINAL
hb_font_funcs_set_glyph_func
hb_font_get_glyph_func_t
+HB_MATH_GLYPH_PART_FLAG_EXTENDER
hb_ot_layout_table_choose_script
hb_ot_layout_table_find_script
hb_ot_tag_from_language
@@ -368,6 +370,11 @@
</SECTION>
<SECTION>
+<FILE>hb-gdi</FILE>
+hb_gdi_face_create
+</SECTION>
+
+<SECTION>
<FILE>hb-glib</FILE>
hb_glib_get_unicode_funcs
hb_glib_script_from_script
@@ -601,6 +608,22 @@
</SECTION>
<SECTION>
+<FILE>hb-ot-meta</FILE>
+hb_ot_meta_t
+hb_ot_meta_get_entries
+hb_ot_meta_reference_entry
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-metrics</FILE>
+hb_ot_metrics_t
+hb_ot_metrics_get_position
+hb_ot_metrics_get_variation
+hb_ot_metrics_get_x_variation
+hb_ot_metrics_get_y_variation
+</SECTION>
+
+<SECTION>
<FILE>hb-ot-shape</FILE>
hb_ot_shape_glyphs_closure
</SECTION>
diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml
index a7b1658..9147ff0 100644
--- a/docs/usermanual-clusters.xml
+++ b/docs/usermanual-clusters.xml
@@ -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
diff --git a/docs/usermanual-fonts-and-faces.xml b/docs/usermanual-fonts-and-faces.xml
index b87f0e5..1258bec 100644
--- a/docs/usermanual-fonts-and-faces.xml
+++ b/docs/usermanual-fonts-and-faces.xml
@@ -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>
diff --git a/src/Makefile.am b/src/Makefile.am
index d4ba39a..7173f4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,8 @@
TESTS =
check_PROGRAMS =
+EXTRA_DIST += harfbuzz.cc
+
# Convenience targets:
lib: $(BUILT_SOURCES) libharfbuzz.la
libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
@@ -80,6 +82,13 @@
HBHEADERS += $(HB_DIRECTWRITE_headers)
endif
+if HAVE_GDI
+HBCFLAGS += $(GDI_CXXFLAGS)
+HBNONPCLIBS += $(GDI_LIBS)
+HBSOURCES += $(HB_GDI_sources)
+HBHEADERS += $(HB_GDI_headers)
+endif
+
if HAVE_CORETEXT
HBCFLAGS += $(CORETEXT_CFLAGS)
HBNONPCLIBS += $(CORETEXT_LIBS)
@@ -253,31 +262,38 @@
$(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,10 +312,27 @@
$(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_GDI_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 \
test-buffer-serialize \
+ test-ot-meta \
test-ot-name \
test-gpos-size-params \
test-gsub-would-substitute \
@@ -318,6 +351,10 @@
test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
+test_ot_meta_SOURCES = test-ot-meta.cc
+test_ot_meta_CPPFLAGS = $(HBCFLAGS)
+test_ot_meta_LDADD = libharfbuzz.la $(HBLIBS)
+
test_ot_name_SOURCES = test-ot-name.cc
test_ot_name_CPPFLAGS = $(HBCFLAGS)
test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 6f42ba3..a8369bf 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -88,6 +88,10 @@
hb-ot-math-table.hh \
hb-ot-math.cc \
hb-ot-maxp-table.hh \
+ hb-ot-meta-table.hh \
+ hb-ot-meta.cc \
+ hb-ot-metrics.cc \
+ hb-ot-metrics.hh \
hb-ot-name-language-static.hh \
hb-ot-name-language.hh \
hb-ot-name-table.hh \
@@ -191,6 +195,8 @@
hb-ot-font.h \
hb-ot-layout.h \
hb-ot-math.h \
+ hb-ot-meta.h \
+ hb-ot-metrics.h \
hb-ot-name.h \
hb-ot-shape.h \
hb-ot-var.h \
@@ -222,6 +228,9 @@
HB_DIRECTWRITE_sources = hb-directwrite.cc
HB_DIRECTWRITE_headers = hb-directwrite.h
+HB_GDI_sources = hb-gdi.cc
+HB_GDI_headers = hb-gdi.h
+
HB_UNISCRIBE_sources = hb-uniscribe.cc
HB_UNISCRIBE_headers = hb-uniscribe.h
diff --git a/src/gen-ucd-table.py b/src/gen-ucd-table.py
index a152375..552c3c6 100755
--- a/src/gen-ucd-table.py
+++ b/src/gen-ucd-table.py
@@ -6,8 +6,8 @@
import logging
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
-if len (sys.argv) != 2:
- print("usage: ./gen-ucd-table ucd.nounihan.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
@@ -18,6 +18,8 @@
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]
@@ -68,7 +70,7 @@
sc_order = dict()
sc_array = []
sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
-for line in open('hb-common.h'):
+for line in open(hb_common_h):
m = sc_re.search (line)
if not m: continue
name = m.group(1)
diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc
new file mode 100644
index 0000000..d338d17
--- /dev/null
+++ b/src/harfbuzz.cc
@@ -0,0 +1,53 @@
+#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-meta.cc"
+#include "hb-ot-metrics.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-gdi.cc"
+#include "hb-directwrite.cc"
+#include "hb-coretext.cc"
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh
index a20ef86..2345f21 100644
--- a/src/hb-aat-layout-feat-table.hh
+++ b/src/hb-aat-layout-feat-table.hh
@@ -174,9 +174,7 @@
}
const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
- {
- return namesZ.bsearch (featureNameCount, feature_type);
- }
+ { return namesZ.bsearch (featureNameCount, feature_type); }
hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
{ return get_feature (feature).get_feature_name_id (); }
diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h
index 760aaae..b617e8b 100644
--- a/src/hb-aat-layout.h
+++ b/src/hb-aat-layout.h
@@ -85,7 +85,7 @@
HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
- _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+ _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_type_t;
/**
@@ -424,7 +424,7 @@
HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
- _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+ _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_selector_t;
HB_EXTERN unsigned int
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
index c8d83c8..7886894 100644
--- a/src/hb-algs.hh
+++ b/src/hb-algs.hh
@@ -50,31 +50,31 @@
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);
@@ -82,11 +82,11 @@
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: */
@@ -95,7 +95,7 @@
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);
@@ -328,14 +328,14 @@
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);
@@ -346,14 +346,14 @@
* 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))
}
@@ -917,7 +917,7 @@
{ 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);
@@ -925,7 +925,7 @@
{ 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);
@@ -933,7 +933,7 @@
{ 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);
@@ -941,56 +941,56 @@
{ 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> auto
+ 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);
diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh
index 948772b..fdc5c68 100644
--- a/src/hb-cff-interp-common.hh
+++ b/src/hb-cff-interp-common.hh
@@ -378,7 +378,7 @@
/* stack */
template <typename ELEM, int LIMIT>
-struct stack_t
+struct cff_stack_t
{
void init ()
{
@@ -469,7 +469,7 @@
/* 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)
{
@@ -523,7 +523,7 @@
{ 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 */
diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh
index cf9ce4d..d9ad4d0 100644
--- a/src/hb-cff-interp-cs-common.hh
+++ b/src/hb-cff-interp-cs-common.hh
@@ -57,7 +57,7 @@
/* 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
diff --git a/src/hb-config.hh b/src/hb-config.hh
index adf2b33..b6db206 100644
--- a/src/hb-config.hh
+++ b/src/hb-config.hh
@@ -66,6 +66,8 @@
#define HB_NO_LAYOUT_COLLECT_GLYPHS
#define HB_NO_LAYOUT_UNUSED
#define HB_NO_MATH
+#define HB_NO_META
+#define HB_NO_METRICS
#define HB_NO_MMAP
#define HB_NO_NAME
#define HB_NO_OPEN
diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc
index a57b970..e8a4fd5 100644
--- a/src/hb-coretext.cc
+++ b/src/hb-coretext.cc
@@ -75,7 +75,7 @@
}
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);
@@ -299,7 +299,7 @@
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);
}
/*
diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc
index a625763..c14e9d2 100644
--- a/src/hb-directwrite.cc
+++ b/src/hb-directwrite.cc
@@ -539,11 +539,6 @@
Run mRunHead;
};
-static inline uint16_t hb_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); }
-
/*
* shaper
*/
@@ -934,7 +929,7 @@
}
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;
@@ -979,7 +974,7 @@
{
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);
}
diff --git a/src/hb-font.cc b/src/hb-font.cc
index f450d88..9cd5011 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -1300,6 +1300,8 @@
1000, /* x_scale */
1000, /* y_scale */
+ 1<<16, /* x_mult */
+ 1<<16, /* y_mult */
0, /* x_ppem */
0, /* y_ppem */
@@ -1330,6 +1332,7 @@
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;
}
@@ -1601,7 +1604,9 @@
hb_face_t *old = font->face;
+ hb_face_make_immutable (face);
font->face = hb_face_reference (face);
+ font->mults_changed ();
hb_face_destroy (old);
}
@@ -1711,6 +1716,7 @@
font->x_scale = x_scale;
font->y_scale = y_scale;
+ font->mults_changed ();
}
/**
diff --git a/src/hb-font.hh b/src/hb-font.hh
index 3b917d1..4adf6ae 100644
--- a/src/hb-font.hh
+++ b/src/hb-font.hh
@@ -107,8 +107,10 @@
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 @@
/* 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 @@
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 ()); }
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index c01f029..2d7f2b9 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -564,7 +564,7 @@
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;
@@ -619,7 +619,7 @@
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);
diff --git a/src/hb-gdi.cc b/src/hb-gdi.cc
new file mode 100644
index 0000000..526f1cd
--- /dev/null
+++ b/src/hb-gdi.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_GDI
+
+#include "hb-gdi.h"
+
+static hb_blob_t *
+_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+ char *buffer = nullptr;
+ DWORD length = 0;
+
+ HDC hdc = GetDC (nullptr);
+ if (unlikely (!SelectObject (hdc, (HFONT) user_data))) goto fail;
+
+ length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+ if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc;
+
+ buffer = (char *) malloc (length);
+ if (unlikely (!buffer)) goto fail_with_releasedc;
+ length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+ if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free;
+ ReleaseDC (nullptr, hdc);
+
+ return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free);
+
+fail_with_releasedc_and_free:
+ free (buffer);
+fail_with_releasedc:
+ ReleaseDC (nullptr, hdc);
+fail:
+ return hb_blob_get_empty ();
+}
+
+/**
+ * hb_gdi_face_create:
+ * @hdc: a HFONT object.
+ *
+ * Return value: #hb_face_t object corresponding to the given input
+ *
+ * Since: REPLACEME
+ **/
+hb_face_t *
+hb_gdi_face_create (HFONT hfont)
+{
+ return hb_face_create_for_tables (_hb_gdi_reference_table, (void *) hfont, nullptr);
+}
+
+#endif
diff --git a/src/hb-gdi.h b/src/hb-gdi.h
new file mode 100644
index 0000000..68cc439
--- /dev/null
+++ b/src/hb-gdi.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#ifndef HB_GDI_H
+#define HB_GDI_H
+
+#include "hb.h"
+
+#include <windows.h>
+
+HB_BEGIN_DECLS
+
+HB_EXTERN hb_face_t *
+hb_gdi_face_create (HFONT hfont);
+
+HB_END_DECLS
+
+#endif /* HB_GDI_H */
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index 9588fa4..40ac906 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -106,32 +106,6 @@
return d;
}
-static void hb_graphite2_release_table(const void *data, const void *table_buffer)
-{
- hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
- hb_graphite2_tablelist_t *tlist = face_data->tlist;
-
- hb_graphite2_tablelist_t *prev = nullptr;
- hb_graphite2_tablelist_t *curr = tlist;
- while (curr)
- {
- if (hb_blob_get_data(curr->blob, nullptr) == table_buffer)
- {
- if (prev == nullptr)
- face_data->tlist.cmpexch(tlist, curr->next);
- else
- prev->next = curr->next;
- hb_blob_destroy(curr->blob);
- free(curr);
- break;
- }
- prev = curr;
- curr = curr->next;
- }
-}
-
-static gr_face_ops hb_graphite2_face_ops = { sizeof(gr_face_ops), hb_graphite2_get_table, hb_graphite2_release_table };
-
hb_graphite2_face_data_t *
_hb_graphite2_shaper_face_data_create (hb_face_t *face)
{
@@ -150,7 +124,7 @@
return nullptr;
data->face = face;
- data->grface = gr_make_face_with_ops (data, &hb_graphite2_face_ops, gr_face_preloadAll);
+ data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
if (unlikely (!data->grface)) {
free (data);
diff --git a/src/hb-iter.hh b/src/hb-iter.hh
index 5df4333..8d2ff80 100644
--- a/src/hb-iter.hh
+++ b/src/hb-iter.hh
@@ -480,7 +480,7 @@
template <typename Iter,
hb_requires (hb_is_iterator (Iter)),
- typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>
+ typename AccuT = hb_decay<decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>>
AccuT
operator () (Iter it)
{
diff --git a/src/hb-meta.hh b/src/hb-meta.hh
index df8ebd1..2dfaeb7 100644
--- a/src/hb-meta.hh
+++ b/src/hb-meta.hh
@@ -80,8 +80,8 @@
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 @@
/* 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);
diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh
index 5318c7f..f3f4dc0 100644
--- a/src/hb-open-file.hh
+++ b/src/hb-open-file.hh
@@ -141,14 +141,15 @@
TableRecord &rec = tables.arrayZ[i];
hb_blob_t *blob = items[i].blob;
rec.tag = items[i].tag;
- rec.length = hb_blob_get_length (blob);
+ rec.length = blob->length;
rec.offset.serialize (c, this);
/* Allocate room for the table and copy it. */
char *start = (char *) c->allocate_size<void> (rec.length);
- if (unlikely (!start)) {return false;}
+ if (unlikely (!start)) return false;
- memcpy (start, hb_blob_get_data (blob, nullptr), rec.length);
+ if (likely (rec.length))
+ memcpy (start, blob->data, rec.length);
/* 4-byte alignment. */
c->align (4);
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index e235a97..ad99575 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -576,13 +576,13 @@
operator writer_t () { return writer (); }
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
@@ -826,13 +826,13 @@
operator writer_t () { return writer (); }
hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc
index 3238ad7..3e4fc20 100644
--- a/src/hb-ot-cff1-table.cc
+++ b/src/hb-ot-cff1-table.cc
@@ -210,7 +210,7 @@
point_t max;
};
-struct extents_param_t
+struct cff1_extents_param_t
{
void init (const OT::cff1::accelerator_t *_cff)
{
@@ -229,15 +229,15 @@
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 ())
{
@@ -248,7 +248,7 @@
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 ())
{
@@ -265,9 +265,9 @@
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;
@@ -296,11 +296,11 @@
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;
diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc
index 9c9e37b..33b51fe 100644
--- a/src/hb-ot-cff2-table.cc
+++ b/src/hb-ot-cff2-table.cc
@@ -33,7 +33,7 @@
using namespace CFF;
-struct extents_param_t
+struct cff2_extents_param_t
{
void init ()
{
@@ -63,15 +63,15 @@
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 ())
{
@@ -82,7 +82,7 @@
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 ())
{
@@ -97,7 +97,7 @@
}
};
-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,
@@ -113,10 +113,10 @@
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;
diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index ac75bd9..d79b549 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -878,7 +878,7 @@
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;
@@ -979,6 +979,14 @@
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
return false;
}
+ else
+ {
+ // FIXME: Merge this with above or, remove and tweak #final_size
+ // and rebase all the tests expectations
+ HBUINT32 empty;
+ empty = 0;
+ for (unsigned int i = 0; i < 4; ++i) c.copy (empty);
+ }
c.end_serialize ();
diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
index 9b725c4..8a915a6 100644
--- a/src/hb-ot-color-sbix-table.hh
+++ b/src/hb-ot-color-sbix-table.hh
@@ -235,9 +235,9 @@
const PNGHeader &png = *blob->as<PNGHeader>();
extents->x_bearing = x_offset;
- extents->y_bearing = y_offset;
+ extents->y_bearing = png.IHDR.height + y_offset;
extents->width = png.IHDR.width;
- extents->height = png.IHDR.height;
+ extents->height = -png.IHDR.height;
/* Convert to font units. */
if (strike_ppem)
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
index ac70527..97fb765 100644
--- a/src/hb-ot-face-table-list.hh
+++ b/src/hb-ot-face-table-list.hh
@@ -50,9 +50,10 @@
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
HB_OT_ACCELERATOR (OT, cmap)
#endif
+HB_OT_TABLE (OT, hhea)
HB_OT_ACCELERATOR (OT, hmtx)
HB_OT_TABLE (OT, OS2)
-#ifndef HB_NO_OT_FONT_GLYPH_NAMES
+#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS)
HB_OT_ACCELERATOR (OT, post)
#endif
#ifndef HB_NO_NAME
@@ -61,8 +62,12 @@
#ifndef HB_NO_STAT
HB_OT_TABLE (OT, STAT)
#endif
+#ifndef HB_NO_META
+HB_OT_ACCELERATOR (OT, meta)
+#endif
/* Vertical layout. */
+HB_OT_TABLE (OT, vhea)
HB_OT_ACCELERATOR (OT, vmtx)
/* TrueType outlines. */
diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc
index f54d0b6..5ef8df4 100644
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@ -32,6 +32,7 @@
#include "hb-ot-cff2-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-kern-table.hh"
+#include "hb-ot-meta-table.hh"
#include "hb-ot-name-table.hh"
#include "hb-ot-post-table.hh"
#include "hb-ot-color-cbdt-table.hh"
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 999bfac..56e4685 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -230,32 +230,24 @@
static hb_bool_t
hb_ot_get_font_h_extents (hb_font_t *font,
- void *font_data,
+ void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
- const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
- metrics->ascender = font->em_scale_y (hmtx.ascender);
- metrics->descender = font->em_scale_y (hmtx.descender);
- metrics->line_gap = font->em_scale_y (hmtx.line_gap);
- // TODO Hook up variations.
- return hmtx.has_font_extents;
+ return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_ASCENDER, &metrics->ascender) &&
+ _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_DESCENDER, &metrics->descender) &&
+ _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_LINE_GAP, &metrics->line_gap);
}
static hb_bool_t
hb_ot_get_font_v_extents (hb_font_t *font,
- void *font_data,
+ void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
- const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
- const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
- metrics->ascender = font->em_scale_x (vmtx.ascender);
- metrics->descender = font->em_scale_x (vmtx.descender);
- metrics->line_gap = font->em_scale_x (vmtx.line_gap);
- // TODO Hook up variations.
- return vmtx.has_font_extents;
+ return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_ASCENDER, &metrics->ascender) &&
+ _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_DESCENDER, &metrics->descender) &&
+ _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_LINE_GAP, &metrics->line_gap);
}
#if HB_USE_ATEXIT
diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh
index c3155b7..778b6c5 100644
--- a/src/hb-ot-hhea-table.hh
+++ b/src/hb-ot-hhea-table.hh
@@ -45,6 +45,8 @@
template <typename T>
struct _hea
{
+ bool has_data () const { return version.major; }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh
index 754a376..11a588e 100644
--- a/src/hb-ot-hmtx-table.hh
+++ b/src/hb-ot-hmtx-table.hh
@@ -29,8 +29,8 @@
#include "hb-open-type.hh"
#include "hb-ot-hhea-table.hh"
-#include "hb-ot-os2-table.hh"
#include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-metrics.hh"
/*
* hmtx -- Horizontal Metrics
@@ -88,22 +88,22 @@
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
- void serialize (hb_serialize_context_t *c,
- Iterator it,
+ void serialize (hb_serialize_context_t *c,
+ Iterator it,
unsigned num_advances)
{
unsigned idx = 0;
+ it
| hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _)
{
- if (idx < num_advances)
+ if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed<LongMetric> (&lm))) return;
- }
- else
+ }
+ else
{
FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
if (unlikely (!sb)) return;
@@ -120,12 +120,12 @@
T *table_prime = c->serializer->start_embed <T> ();
if (unlikely (!table_prime)) return_trace (false);
-
+
accelerator_t _mtx;
_mtx.init (c->plan->source);
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
-
- auto it =
+
+ auto it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([c, &_mtx] (unsigned _)
{
@@ -162,28 +162,7 @@
{
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
- bool got_font_extents = false;
- if (T::os2Tag != HB_TAG_NONE && face->table.OS2->is_typo_metrics ())
- {
- ascender = abs (face->table.OS2->sTypoAscender);
- descender = -abs (face->table.OS2->sTypoDescender);
- line_gap = face->table.OS2->sTypoLineGap;
- got_font_extents = (ascender | descender) != 0;
- }
-
- hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
- const H *_hea_table = _hea_blob->as<H> ();
- num_advances = _hea_table->numberOfLongMetrics;
- if (!got_font_extents)
- {
- ascender = abs (_hea_table->ascender);
- descender = -abs (_hea_table->descender);
- line_gap = _hea_table->lineGap;
- got_font_extents = (ascender | descender) != 0;
- }
- hb_blob_destroy (_hea_blob);
-
- has_font_extents = got_font_extents;
+ num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
@@ -277,12 +256,6 @@
return get_advance (old_gid);
}
- public:
- bool has_font_extents;
- int ascender;
- int descender;
- int line_gap;
-
protected:
unsigned int num_metrics;
unsigned int num_advances;
@@ -322,12 +295,12 @@
struct hmtx : hmtxvmtx<hmtx, hhea> {
static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
- static constexpr hb_tag_t os2Tag = HB_OT_TAG_OS2;
+ static constexpr bool is_horizontal = true;
};
struct vmtx : hmtxvmtx<vmtx, vhea> {
static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
- static constexpr hb_tag_t os2Tag = HB_TAG_NONE;
+ static constexpr bool is_horizontal = false;
};
struct hmtx_accelerator_t : hmtx::accelerator_t {};
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 0912362..12cc163 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -1,7 +1,7 @@
/*
- * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
+ * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
* Copyright © 2018 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
+ * Copyright © 2018-2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -116,6 +116,8 @@
struct BaseCoord
{
+ bool has_data () const { return u.format; }
+
hb_position_t get_coord (hb_font_t *font,
const VariationStore &var_store,
hb_direction_t direction) const
@@ -142,10 +144,10 @@
protected:
union {
- HBUINT16 format;
- BaseCoordFormat1 format1;
- BaseCoordFormat2 format2;
- BaseCoordFormat3 format3;
+ HBUINT16 format;
+ BaseCoordFormat1 format1;
+ BaseCoordFormat2 format2;
+ BaseCoordFormat3 format3;
} u;
public:
DEFINE_SIZE_UNION (2, format);
@@ -153,14 +155,9 @@
struct FeatMinMaxRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
- return key < (unsigned int) entry.tag ? -1 :
- key > (unsigned int) entry.tag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return tag.cmp (key); }
+
+ bool has_data () const { return tag; }
void get_min_max (const BaseCoord **min, const BaseCoord **max) const
{
@@ -195,17 +192,12 @@
struct MinMax
{
void get_min_max (hb_tag_t feature_tag,
- const BaseCoord **min,
- const BaseCoord **max) const
+ const BaseCoord **min,
+ const BaseCoord **max) const
{
- /* TODO Replace hb_bsearch() with .bsearch(). */
- const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
- hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
- featMinMaxRecords.len,
- FeatMinMaxRecord::static_size,
- FeatMinMaxRecord::cmp);
- if (minMaxCoord)
- minMaxCoord->get_min_max (min, max);
+ const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
+ if (minMaxCoord.has_data ())
+ minMaxCoord.get_min_max (min, max);
else
{
if (likely (min)) *min = &(this+minCoord);
@@ -271,17 +263,11 @@
struct BaseLangSysRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
- return key < (unsigned int) entry.baseLangSysTag ? -1 :
- key > (unsigned int) entry.baseLangSysTag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
- const MinMax &get_min_max () const
- { return this+minMax; }
+ bool has_data () const { return baseLangSysTag; }
+
+ const MinMax &get_min_max () const { return this+minMax; }
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
@@ -303,19 +289,14 @@
{
const MinMax &get_min_max (hb_tag_t language_tag) const
{
- /* TODO Replace hb_bsearch() with .bsearch(). */
- const BaseLangSysRecord* record = (const BaseLangSysRecord *)
- hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
- baseLangSysRecords.len,
- BaseLangSysRecord::static_size,
- BaseLangSysRecord::cmp);
- return record ? record->get_min_max () : this+defaultMinMax;
+ const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
+ return record.has_data () ? record.get_min_max () : this+defaultMinMax;
}
const BaseCoord &get_base_coord (int baseline_tag_index) const
{ return (this+baseValues).get_base_coord (baseline_tag_index); }
- bool is_empty () const { return !baseValues; }
+ bool has_data () const { return baseValues; }
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -345,14 +326,9 @@
struct BaseScriptList;
struct BaseScriptRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
- return key < (unsigned int) entry.baseScriptTag ? -1 :
- key > (unsigned int) entry.baseScriptTag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
+
+ bool has_data () const { return baseScriptTag; }
const BaseScript &get_base_script (const BaseScriptList *list) const
{ return list+baseScript; }
@@ -376,22 +352,11 @@
struct BaseScriptList
{
- const BaseScriptRecord *find_record (hb_tag_t script) const
- {
- /* TODO Replace hb_bsearch() with .bsearch(). */
- return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
- baseScriptRecords.len,
- BaseScriptRecord::static_size,
- BaseScriptRecord::cmp);
- }
-
- /* TODO: Or client should handle fallback? */
const BaseScript &get_base_script (hb_tag_t script) const
{
- const BaseScriptRecord *record = find_record (script);
- if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T'));
-
- return record ? record->get_base_script (this) : Null (BaseScript);
+ const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
+ if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
+ return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -412,14 +377,19 @@
struct Axis
{
bool get_baseline (hb_ot_layout_baseline_t baseline,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- const BaseCoord **coord) const
+ hb_tag_t script_tag,
+ hb_tag_t language_tag,
+ const BaseCoord **coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (base_script.is_empty ()) return false;
+ if (!base_script.has_data ()) return false;
- if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline));
+ if (likely (coord))
+ {
+ unsigned int tag_index = 0;
+ (this+baseTagList).bfind (baseline, &tag_index);
+ *coord = &base_script.get_base_coord (tag_index);
+ }
return true;
}
@@ -431,7 +401,7 @@
const BaseCoord **max_coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (base_script.is_empty ()) return false;
+ if (!base_script.has_data ()) return false;
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
@@ -479,13 +449,14 @@
hb_tag_t language_tag,
hb_position_t *base) const
{
- const BaseCoord *base_coord;
- if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord))
+ const BaseCoord *base_coord = nullptr;
+ if (unlikely (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord) ||
+ !base_coord || !base_coord->has_data ()))
return false;
- if (likely (base && base_coord)) *base = base_coord->get_coord (font,
- get_var_store (),
- direction);
+ if (likely (base))
+ *base = base_coord->get_coord (font, get_var_store (), direction);
+
return true;
}
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index f4be42c..5c21980 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -733,7 +733,7 @@
+ hb_zip (this+coverage, pairSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
- | hb_map ([=] (const OffsetTo<PairSet> &_)
+ | hb_map ([glyphs, this] (const OffsetTo<PairSet> &_)
{ return (this+_).intersects (glyphs, valueFormat); })
| hb_any
;
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index a6cc1a2..84e1b15 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -248,7 +248,7 @@
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned format = 2;
unsigned delta = 0;
- if (glyphs.len ())
+ if (glyphs)
{
format = 1;
auto get_delta = [=] (hb_codepoint_pair_t _) {
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 98cd109..4cd65b4 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -43,7 +43,6 @@
#include "hb-map.hh"
#include "hb-ot-kern-table.hh"
-#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
@@ -109,7 +108,7 @@
*
* Tests whether a face has any cross-stream kerning (i.e., kerns
* that make adjustments perpendicular to the direction of the text
- * flow: Y adjustments in horizontal text or X adjustments in
+ * flow: Y adjustments in horizontal text or X adjustments in
* vertical text) in the 'kern' table.
*
* Does NOT examine the GPOS table.
@@ -286,7 +285,7 @@
*
* Fetches the GDEF class of the requested glyph in the specified face.
*
- * Return value: The #hb_ot_layout_glyph_class_t glyph class of the given code
+ * Return value: The #hb_ot_layout_glyph_class_t glyph class of the given code
* point in the GDEF table of the face.
*
* Since: 0.9.7
@@ -330,7 +329,7 @@
* @point_array: (out) (array length=point_count): The array of attachment points found for the query
*
* Fetches a list of all attachment points for the specified glyph in the GDEF
- * table of the face. The list returned will begin at the offset provided.
+ * table of the face. The list returned will begin at the offset provided.
*
* Useful if the client program wishes to cache the list.
*
@@ -980,7 +979,7 @@
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
*
- * Fetches the total number of lookups enumerated in the specified
+ * Fetches the total number of lookups enumerated in the specified
* face's GSUB table or GPOS table.
*
* Since: 0.9.22
@@ -1188,7 +1187,7 @@
* table or GPOS table, underneath the specified scripts, languages, and
* features. If no list of scripts is provided, all scripts will be queried.
* If no list of languages is provided, all languages will be queried. If no
- * list of features is provided, all features will be queried.
+ * list of features is provided, all features will be queried.
*
* Since: 0.9.8
**/
@@ -1582,7 +1581,7 @@
* as used here are defined as pertaining only to fonts within a font family that differ
* specifically in their respective size ranges; other ways to differentiate fonts within
* a subfamily are not covered by the `size` feature.
- *
+ *
* For more information on this distinction, see the `size` documentation at
* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-39size39
*
@@ -1724,7 +1723,7 @@
* returned. This function can be called with incrementally larger start_offset
* until the char_count output value is lower than its input value, or the size
* of the characters array can be increased.</note>
- *
+ *
* Return value: Number of total sample characters in the cvXX feature.
*
* Since: 2.0.0
@@ -1980,7 +1979,9 @@
HB_OT_LAYOUT_BASELINE_IDEO = HB_TAG('i','d','e','o'),
HB_OT_LAYOUT_BASELINE_IDTB = HB_TAG('i','d','t','b'),
HB_OT_LAYOUT_BASELINE_MATH = HB_TAG('m','a','t','h'),
- HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n')
+ HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n'),
+
+ _HB_OT_LAYOUT_BASELINE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_layout_baseline_t;
diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index be7ef02..f3bb155 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -168,6 +168,17 @@
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 @@
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. */
diff --git a/src/hb-ot-map.hh b/src/hb-ot-map.hh
index dd67786..0a4827d 100644
--- a/src/hb-ot-map.hh
+++ b/src/hb-ot-map.hh
@@ -154,8 +154,8 @@
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;
diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh
index 0b16e0b..b4592cc 100644
--- a/src/hb-ot-math-table.hh
+++ b/src/hb-ot-math-table.hh
@@ -453,14 +453,14 @@
}
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 @@
{
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 @@
{
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;
diff --git a/src/hb-ot-math.h b/src/hb-ot-math.h
index 7b2befb..ad864a7 100644
--- a/src/hb-ot-math.h
+++ b/src/hb-ot-math.h
@@ -158,7 +158,7 @@
* hb_ot_math_glyph_part_t:
* @glyph: The glyph index of the variant part
* @start_connector_length: The length of the connector on the starting side of the variant part
- * @end_connection_length: The length of the connector on the ending side of the variant part
+ * @end_connector_length: The length of the connector on the ending side of the variant part
* @full_advance: The total advance of the part
* @flags: #hb_ot_math_glyph_part_flags_t flags for the part
*
diff --git a/src/hb-ot-meta-table.hh b/src/hb-ot-meta-table.hh
new file mode 100644
index 0000000..f0842e4
--- /dev/null
+++ b/src/hb-ot-meta-table.hh
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#ifndef HB_OT_META_TABLE_HH
+#define HB_OT_META_TABLE_HH
+
+#include "hb-open-type.hh"
+
+/*
+ * meta -- Metadata Table
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/meta
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
+ */
+#define HB_OT_TAG_meta HB_TAG ('m','e','t','a')
+
+
+namespace OT {
+
+
+struct DataMap
+{
+ int cmp (hb_tag_t a) const { return tag.cmp (a); }
+
+ hb_tag_t get_tag () const { return tag; }
+
+ hb_blob_t *reference_entry (hb_blob_t *meta_blob) const
+ { return hb_blob_create_sub_blob (meta_blob, dataZ, dataLength); }
+
+ bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this) &&
+ dataZ.sanitize (c, base, dataLength)));
+ }
+
+ protected:
+ Tag tag; /* A tag indicating the type of metadata. */
+ LOffsetTo<UnsizedArrayOf<HBUINT8>>
+ dataZ; /* Offset in bytes from the beginning of the
+ * metadata table to the data for this tag. */
+ HBUINT32 dataLength; /* Length of the data. The data is not required to
+ * be padded to any byte boundary. */
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct meta
+{
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_meta;
+
+ struct accelerator_t
+ {
+ void init (hb_face_t *face)
+ { table = hb_sanitize_context_t ().reference_table<meta> (face); }
+ void fini () { table.destroy (); }
+
+ hb_blob_t *reference_entry (hb_tag_t tag) const
+ { return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
+
+ unsigned int get_entries (unsigned int start_offset,
+ unsigned int *count,
+ hb_ot_meta_tag_t *entries) const
+ {
+ if (count)
+ {
+ hb_array_t<const DataMap> arr = table->dataMaps.sub_array (start_offset, count);
+ for (unsigned int i = 0; i < arr.length; i++)
+ entries[i] = (hb_ot_meta_tag_t) arr[i].get_tag ();
+ }
+ return table->dataMaps.len;
+ }
+
+ private:
+ hb_blob_ptr_t<meta> table;
+ };
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (likely (c->check_struct (this) &&
+ version == 1 &&
+ dataMaps.sanitize (c, this)));
+ }
+
+ protected:
+ HBUINT32 version; /* Version number of the metadata table — set to 1. */
+ HBUINT32 flags; /* Flags — currently unused; set to 0. */
+ HBUINT32 dataOffset; /* Per Apple specification:
+ * Offset from the beginning of the table to the data.
+ * Per OT specification:
+ * Reserved. Not used; should be set to 0. */
+ LArrayOf<DataMap>
+ dataMaps; /* Array of data map records. */
+ public:
+ DEFINE_SIZE_ARRAY (16, dataMaps);
+};
+
+struct meta_accelerator_t : meta::accelerator_t {};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_META_TABLE_HH */
diff --git a/src/hb-ot-meta.cc b/src/hb-ot-meta.cc
new file mode 100644
index 0000000..a5ce148
--- /dev/null
+++ b/src/hb-ot-meta.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb.hh"
+
+#ifndef HB_NO_META
+
+#include "hb-ot-meta-table.hh"
+
+/**
+ * SECTION:hb-ot-meta
+ * @title: hb-ot-meta
+ * @short_description: OpenType Metadata
+ * @include: hb-ot.h
+ *
+ * Functions for fetching metadata from fonts.
+ **/
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a face object
+ * @start_offset: iteration's start offset
+ * @entries_count:(inout) (allow-none): buffer size as input, filled size as output
+ * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
+ *
+ * Return value: Number of all available feature types.
+ *
+ * Since: REPLACEME
+ **/
+unsigned int
+hb_ot_meta_get_entries (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *entries_count, /* IN/OUT. May be NULL. */
+ hb_ot_meta_tag_t *entries /* OUT. May be NULL. */)
+{
+ return face->table.meta->get_entries (start_offset, entries_count, entries);
+}
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a #hb_face_t object.
+ * @meta_tag: tag of metadata you like to have.
+ *
+ * It fetches metadata entry of a given tag from a font.
+ *
+ * Returns: (transfer full): A blob containing the blob.
+ *
+ * Since: REPLACEME
+ **/
+hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag)
+{
+ return face->table.meta->reference_entry (meta_tag);
+}
+
+#endif
diff --git a/src/hb-ot-meta.h b/src/hb-ot-meta.h
new file mode 100644
index 0000000..5267728
--- /dev/null
+++ b/src/hb-ot-meta.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_META_H
+#define HB_OT_META_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+/**
+ * hb_ot_meta_tag_t:
+ *
+ * From https://docs.microsoft.com/en-us/typography/opentype/spec/meta
+ *
+ * Since: REPLACEME
+ **/
+typedef enum {
+/*
+ HB_OT_META_APPL = HB_TAG ('a','p','p','l'),
+ HB_OT_META_BILD = HB_TAG ('b','i','l','d'),
+*/
+ HB_OT_META_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'),
+ HB_OT_META_SUPPORTED_LANGUAGES= HB_TAG ('s','l','n','g'),
+
+ _HB_OT_META_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_meta_tag_t;
+
+HB_EXTERN unsigned int
+hb_ot_meta_get_entries (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *entries_count, /* IN/OUT. May be NULL. */
+ hb_ot_meta_tag_t *entries /* OUT. May be NULL. */);
+
+HB_EXTERN hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_META_H */
diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc
new file mode 100644
index 0000000..d211d7e
--- /dev/null
+++ b/src/hb-ot-metrics.cc
@@ -0,0 +1,231 @@
+/*
+ * Copyright © 2018-2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb.hh"
+
+#include "hb-ot-var-mvar-table.hh"
+#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-post-table.hh"
+#include "hb-ot-hhea-table.hh"
+#include "hb-ot-metrics.hh"
+#include "hb-ot-face.hh"
+
+
+static float
+_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
+{
+ if (metrics_tag == HB_OT_METRICS_HORIZONTAL_ASCENDER ||
+ metrics_tag == HB_OT_METRICS_VERTICAL_ASCENDER)
+ return fabs ((double) value);
+ if (metrics_tag == HB_OT_METRICS_HORIZONTAL_DESCENDER ||
+ metrics_tag == HB_OT_METRICS_VERTICAL_DESCENDER)
+ return -fabs ((double) value);
+ return value;
+}
+
+/* The common part of _get_position logic needed on hb-ot-font and here
+ to be able to have slim builds without the not always needed parts */
+bool
+_hb_ot_metrics_get_position_common (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */)
+{
+ hb_face_t *face = font->face;
+ switch ((unsigned) metrics_tag)
+ {
+#ifndef HB_NO_VAR
+#define GET_VAR face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords)
+#else
+#define GET_VAR .0f
+#endif
+#define GET_METRIC_X(TABLE, ATTR) \
+ (face->table.TABLE->has_data () && \
+ (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \
+ face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
+#define GET_METRIC_Y(TABLE, ATTR) \
+ (face->table.TABLE->has_data () && \
+ (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
+ face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
+ case HB_OT_METRICS_HORIZONTAL_ASCENDER:
+ return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
+ GET_METRIC_Y (hhea, ascender);
+ case HB_OT_METRICS_HORIZONTAL_DESCENDER:
+ return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoDescender)) ||
+ GET_METRIC_Y (hhea, descender);
+ case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
+ return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
+ GET_METRIC_Y (hhea, lineGap);
+ case HB_OT_METRICS_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender);
+ case HB_OT_METRICS_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
+ case HB_OT_METRICS_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap);
+#undef GET_METRIC_Y
+#undef GET_METRIC_X
+#undef GET_VAR
+ default: assert (0); return false;
+ }
+}
+
+#ifndef HB_NO_METRICS
+
+#if 0
+static bool
+_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag)
+{
+ const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
+ if (&range == &Null (OT::GaspRange)) return false;
+ if (result) *result = range.rangeMaxPPEM + font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
+ return true;
+}
+#endif
+
+/* Private tags for https://github.com/harfbuzz/harfbuzz/issues/1866 */
+#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2 HB_TAG ('O','a','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA HB_TAG ('H','a','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2 HB_TAG ('O','d','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA HB_TAG ('H','d','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2 HB_TAG ('O','l','g','p')
+#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA HB_TAG ('H','l','g','p')
+
+/**
+ * hb_ot_metrics_get_position:
+ * @font: a #hb_font_t object.
+ * @metrics_tag: tag of metrics value you like to fetch.
+ * @position: (out) (optional): result of metrics value from the font.
+ *
+ * It fetches metrics value corresponding to a given tag from a font.
+ *
+ * Returns: Whether found the requested metrics in the font.
+ * Since: REPLACEME
+ **/
+hb_bool_t
+hb_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */)
+{
+ hb_face_t *face = font->face;
+ switch ((unsigned) metrics_tag)
+ {
+ case HB_OT_METRICS_HORIZONTAL_ASCENDER:
+ case HB_OT_METRICS_HORIZONTAL_DESCENDER:
+ case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
+ case HB_OT_METRICS_VERTICAL_ASCENDER:
+ case HB_OT_METRICS_VERTICAL_DESCENDER:
+ case HB_OT_METRICS_VERTICAL_LINE_GAP: return _hb_ot_metrics_get_position_common (font, metrics_tag, position);
+#ifndef HB_NO_VAR
+#define GET_VAR hb_ot_metrics_get_variation (font, metrics_tag)
+#else
+#define GET_VAR 0
+#endif
+#define GET_METRIC_X(TABLE, ATTR) \
+ (face->table.TABLE->has_data () && \
+ (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true))
+#define GET_METRIC_Y(TABLE, ATTR) \
+ (face->table.TABLE->has_data () && \
+ (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
+ case HB_OT_METRICS_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
+ case HB_OT_METRICS_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
+ case HB_OT_METRICS_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
+ case HB_OT_METRICS_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
+ case HB_OT_METRICS_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
+ case HB_OT_METRICS_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset);
+ case HB_OT_METRICS_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight);
+ case HB_OT_METRICS_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight);
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize);
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySubscriptYSize);
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySubscriptXOffset);
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySubscriptYOffset);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySuperscriptXSize);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySuperscriptYSize);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySuperscriptXOffset);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySuperscriptYOffset);
+ case HB_OT_METRICS_STRIKEOUT_SIZE: return GET_METRIC_Y (OS2, yStrikeoutSize);
+ case HB_OT_METRICS_STRIKEOUT_OFFSET: return GET_METRIC_Y (OS2, yStrikeoutPosition);
+ case HB_OT_METRICS_UNDERLINE_SIZE: return GET_METRIC_Y (post->table, underlineThickness);
+ case HB_OT_METRICS_UNDERLINE_OFFSET: return GET_METRIC_Y (post->table, underlinePosition);
+
+ /* Private tags */
+ case _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2: return GET_METRIC_Y (OS2, sTypoAscender);
+ case _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA: return GET_METRIC_Y (hhea, ascender);
+ case _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2: return GET_METRIC_Y (OS2, sTypoDescender);
+ case _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA: return GET_METRIC_Y (hhea, descender);
+ case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2: return GET_METRIC_Y (OS2, sTypoLineGap);
+ case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA: return GET_METRIC_Y (hhea, lineGap);
+#undef GET_METRIC_Y
+#undef GET_METRIC_X
+#undef GET_VAR
+ default: return false;
+ }
+}
+
+#ifndef HB_NO_VAR
+/**
+ * hb_ot_metrics_get_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+float
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+ return font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
+}
+
+/**
+ * hb_ot_metrics_get_x_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+ return font->em_scalef_x (hb_ot_metrics_get_variation (font, metrics_tag));
+}
+
+/**
+ * hb_ot_metrics_get_y_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+ return font->em_scalef_y (hb_ot_metrics_get_variation (font, metrics_tag));
+}
+#endif
+
+#endif
diff --git a/src/hb-ot-metrics.h b/src/hb-ot-metrics.h
new file mode 100644
index 0000000..6b2747b
--- /dev/null
+++ b/src/hb-ot-metrics.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_METRICS_H
+#define HB_OT_METRICS_H
+
+#include "hb.h"
+#include "hb-ot-name.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_ot_metrics_tag_t:
+ *
+ * From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
+ *
+ * Since: REPLACEME
+ **/
+typedef enum {
+ HB_OT_METRICS_HORIZONTAL_ASCENDER = HB_TAG ('h','a','s','c'),
+ HB_OT_METRICS_HORIZONTAL_DESCENDER = HB_TAG ('h','d','s','c'),
+ HB_OT_METRICS_HORIZONTAL_LINE_GAP = HB_TAG ('h','l','g','p'),
+ HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT = HB_TAG ('h','c','l','a'),
+ HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT = HB_TAG ('h','c','l','d'),
+ HB_OT_METRICS_VERTICAL_ASCENDER = HB_TAG ('v','a','s','c'),
+ HB_OT_METRICS_VERTICAL_DESCENDER = HB_TAG ('v','d','s','c'),
+ HB_OT_METRICS_VERTICAL_LINE_GAP = HB_TAG ('v','l','g','p'),
+ HB_OT_METRICS_HORIZONTAL_CARET_RISE = HB_TAG ('h','c','r','s'),
+ HB_OT_METRICS_HORIZONTAL_CARET_RUN = HB_TAG ('h','c','r','n'),
+ HB_OT_METRICS_HORIZONTAL_CARET_OFFSET = HB_TAG ('h','c','o','f'),
+ HB_OT_METRICS_VERTICAL_CARET_RISE = HB_TAG ('v','c','r','s'),
+ HB_OT_METRICS_VERTICAL_CARET_RUN = HB_TAG ('v','c','r','n'),
+ HB_OT_METRICS_VERTICAL_CARET_OFFSET = HB_TAG ('v','c','o','f'),
+ HB_OT_METRICS_X_HEIGHT = HB_TAG ('x','h','g','t'),
+ HB_OT_METRICS_CAP_HEIGHT = HB_TAG ('c','p','h','t'),
+ HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE = HB_TAG ('s','b','x','s'),
+ HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE = HB_TAG ('s','b','y','s'),
+ HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET = HB_TAG ('s','b','x','o'),
+ HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET = HB_TAG ('s','b','y','o'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE = HB_TAG ('s','p','x','s'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE = HB_TAG ('s','p','y','s'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET = HB_TAG ('s','p','x','o'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET = HB_TAG ('s','p','y','o'),
+ HB_OT_METRICS_STRIKEOUT_SIZE = HB_TAG ('s','t','r','s'),
+ HB_OT_METRICS_STRIKEOUT_OFFSET = HB_TAG ('s','t','r','o'),
+ HB_OT_METRICS_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'),
+ HB_OT_METRICS_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'),
+
+ _HB_OT_METRICS_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_metrics_tag_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */);
+
+HB_EXTERN float
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_METRICS_H */
diff --git a/src/hb-ot-metrics.hh b/src/hb-ot-metrics.hh
new file mode 100644
index 0000000..19a5e9e
--- /dev/null
+++ b/src/hb-ot-metrics.hh
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#ifndef HB_OT_METRICS_HH
+#define HB_OT_METRICS_HH
+
+#include "hb.hh"
+
+HB_INTERNAL bool
+_hb_ot_metrics_get_position_common (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */);
+
+#endif /* HB_OT_METRICS_HH */
diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh
index 16e29ca..67f21eb 100644
--- a/src/hb-ot-os2-table.hh
+++ b/src/hb-ot-os2-table.hh
@@ -59,6 +59,10 @@
struct OS2V2Tail
{
+ bool has_data () const { return this != &Null (OS2V2Tail); }
+
+ const OS2V2Tail * operator -> () const { return this; }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -113,9 +117,9 @@
OBLIQUE = 1u<<9
};
- bool is_italic () const { return fsSelection & ITALIC; }
- bool is_oblique () const { return fsSelection & OBLIQUE; }
- bool is_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
+ bool is_italic () const { return fsSelection & ITALIC; }
+ bool is_oblique () const { return fsSelection & OBLIQUE; }
+ bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
enum width_class_t {
FWIDTH_ULTRA_CONDENSED = 1, /* 50% */
@@ -192,13 +196,14 @@
}
static void find_min_and_max_codepoint (const hb_set_t *codepoints,
- uint16_t *min_cp, /* OUT */
- uint16_t *max_cp /* OUT */)
+ uint16_t *min_cp, /* OUT */
+ uint16_t *max_cp /* OUT */)
{
*min_cp = codepoints->get_min ();
*max_cp = codepoints->get_max ();
}
+ /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */
enum font_page_t {
HEBREW_FONT_PAGE = 0xB100, // Hebrew Windows 3.1 font page
SIMP_ARABIC_FONT_PAGE = 0xB200, // Simplified Arabic Windows 3.1 font page
@@ -208,8 +213,6 @@
TRAD_FARSI_FONT_PAGE = 0xBB00, // Traditional Farsi Windows 3.1 font page
THAI_FONT_PAGE = 0xDE00 // Thai Windows 3.1 font page
};
-
- // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
font_page_t get_font_page () const
{ return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 720e03b..fb826cd 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -178,6 +178,8 @@
return false;
}
+ hb_blob_ptr_t<post> table;
+
protected:
unsigned int get_glyph_count () const
@@ -237,7 +239,6 @@
}
private:
- hb_blob_ptr_t<post> table;
uint32_t version;
const ArrayOf<HBUINT16> *glyphNameIndex;
hb_vector_t<uint32_t> index_to_offset;
@@ -245,6 +246,8 @@
hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
};
+ bool has_data () const { return version.to_int (); }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-ot-shape-complex-indic-machine.hh b/src/hb-ot-shape-complex-indic-machine.hh
index ca26ecb..670b6bf 100644
--- a/src/hb-ot-shape-complex-indic-machine.hh
+++ b/src/hb-ot-shape-complex-indic-machine.hh
@@ -395,13 +395,13 @@
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 @@
}
+#undef found_syllable
+
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index a2a88af..5f819bd 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -96,13 +96,13 @@
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 @@
}%%
}
+#undef found_syllable
+
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 6405d9c..fd099ca 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -144,49 +144,45 @@
* 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)
@@ -194,7 +190,7 @@
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
@@ -203,14 +199,14 @@
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]);
@@ -218,7 +214,7 @@
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
@@ -228,32 +224,6 @@
}
-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
@@ -285,10 +255,10 @@
#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];
};
@@ -371,13 +341,13 @@
}
-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"
@@ -401,11 +371,11 @@
}
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);
}
@@ -422,9 +392,9 @@
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;
@@ -497,7 +467,7 @@
* 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])) ||
@@ -833,13 +803,13 @@
/* 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 */
@@ -847,7 +817,9 @@
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;
}
@@ -879,13 +851,13 @@
(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++) {
@@ -895,7 +867,7 @@
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;
}
}
@@ -916,7 +888,7 @@
/* 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]));
}
@@ -945,34 +917,34 @@
}
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;
@@ -983,7 +955,7 @@
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;
@@ -1008,8 +980,8 @@
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;
@@ -1033,21 +1005,21 @@
}
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;
@@ -1083,7 +1055,7 @@
* syllable.
*/
- bool try_pref = !!indic_plan->mask_array[PREF];
+ bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
/* Find base again */
unsigned int base;
@@ -1093,7 +1065,7 @@
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])))
@@ -1415,7 +1387,7 @@
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
@@ -1478,7 +1450,7 @@
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);
}
@@ -1508,15 +1480,15 @@
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);
@@ -1524,18 +1496,6 @@
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,
hb_font_t *font)
diff --git a/src/hb-ot-shape-complex-indic.hh b/src/hb-ot-shape-complex-indic.hh
index d207728..1eeed68 100644
--- a/src/hb-ot-shape-complex-indic.hh
+++ b/src/hb-ot-shape-complex-indic.hh
@@ -64,7 +64,14 @@
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))
@@ -398,5 +405,31 @@
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 */
diff --git a/src/hb-ot-shape-complex-khmer-machine.hh b/src/hb-ot-shape-complex-khmer-machine.hh
index 65e0ffc..a040318 100644
--- a/src/hb-ot-shape-complex-khmer-machine.hh
+++ b/src/hb-ot-shape-complex-khmer-machine.hh
@@ -226,13 +226,13 @@
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 @@
}
+#undef found_syllable
+
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
diff --git a/src/hb-ot-shape-complex-khmer-machine.rl b/src/hb-ot-shape-complex-khmer-machine.rl
index 1076a08..e7f1453 100644
--- a/src/hb-ot-shape-complex-khmer-machine.rl
+++ b/src/hb-ot-shape-complex-khmer-machine.rl
@@ -83,13 +83,13 @@
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 @@
}%%
}
+#undef found_syllable
+
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc
index eba7d86..b1fa015 100644
--- a/src/hb-ot-shape-complex-khmer.cc
+++ b/src/hb-ot-shape-complex-khmer.cc
@@ -69,37 +69,33 @@
* 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)
@@ -107,8 +103,8 @@
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
@@ -127,7 +123,7 @@
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]);
@@ -153,32 +149,6 @@
}
-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
@@ -202,7 +172,7 @@
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];
};
@@ -232,10 +202,10 @@
}
-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"
@@ -257,11 +227,11 @@
}
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);
}
@@ -282,7 +252,9 @@
/* 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;
}
@@ -309,7 +281,7 @@
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);
@@ -325,9 +297,9 @@
* 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. */
}
@@ -346,28 +318,28 @@
}
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;
@@ -378,7 +350,7 @@
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;
@@ -403,8 +375,8 @@
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;
@@ -428,29 +400,18 @@
}
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,
diff --git a/src/hb-ot-shape-complex-khmer.hh b/src/hb-ot-shape-complex-khmer.hh
index 21015c7..11a77bf 100644
--- a/src/hb-ot-shape-complex-khmer.hh
+++ b/src/hb-ot-shape-complex-khmer.hh
@@ -43,11 +43,10 @@
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 @@
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);
}
diff --git a/src/hb-ot-shape-complex-myanmar-machine.hh b/src/hb-ot-shape-complex-myanmar-machine.hh
index b7b04cb..c2f4c00 100644
--- a/src/hb-ot-shape-complex-myanmar-machine.hh
+++ b/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -304,13 +304,13 @@
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;
diff --git a/src/hb-ot-shape-complex-myanmar-machine.rl b/src/hb-ot-shape-complex-myanmar-machine.rl
index 6659989..67133cd 100644
--- a/src/hb-ot-shape-complex-myanmar-machine.rl
+++ b/src/hb-ot-shape-complex-myanmar-machine.rl
@@ -97,13 +97,13 @@
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;
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 5b819cf..14d215e 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -36,7 +36,7 @@
*/
static const hb_tag_t
-basic_features[] =
+myanmar_basic_features[] =
{
/*
* Basic features.
@@ -48,7 +48,7 @@
HB_TAG('p','s','t','f'),
};
static const hb_tag_t
-other_features[] =
+myanmar_other_features[] =
{
/*
* Other features.
@@ -60,7 +60,7 @@
HB_TAG('p','s','t','s'),
};
static const hb_tag_t
-positioning_features[] =
+myanmar_positioning_features[] =
{
/*
* Positioning features.
@@ -80,15 +80,11 @@
};
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);
@@ -98,7 +94,7 @@
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
@@ -106,21 +102,21 @@
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
@@ -130,11 +126,11 @@
}
-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"
@@ -158,11 +154,11 @@
}
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);
}
@@ -278,29 +274,29 @@
}
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;
@@ -311,7 +307,7 @@
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;
@@ -336,8 +332,8 @@
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;
@@ -355,30 +351,19 @@
}
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 =
{
diff --git a/src/hb-ot-shape-complex-myanmar.hh b/src/hb-ot-shape-complex-myanmar.hh
index 9ec78ef..7b9821e 100644
--- a/src/hb-ot-shape-complex-myanmar.hh
+++ b/src/hb-ot-shape-complex-myanmar.hh
@@ -49,10 +49,10 @@
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 @@
{
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;
}
}
diff --git a/src/hb-ot-shape-complex-use-machine.hh b/src/hb-ot-shape-complex-use-machine.hh
index 01fe3d7..462342c 100644
--- a/src/hb-ot-shape-complex-use-machine.hh
+++ b/src/hb-ot-shape-complex-use-machine.hh
@@ -380,13 +380,13 @@
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;
diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl
index aca7ea6..9b75b5c 100644
--- a/src/hb-ot-shape-complex-use-machine.rl
+++ b/src/hb-ot-shape-complex-use-machine.rl
@@ -165,13 +165,13 @@
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;
diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc
index 91c0b8c..1ea2957 100644
--- a/src/hb-ot-shape-complex-use.cc
+++ b/src/hb-ot-shape-complex-use.cc
@@ -44,7 +44,7 @@
*/
static const hb_tag_t
-basic_features[] =
+use_basic_features[] =
{
/*
* Basic features.
@@ -59,28 +59,23 @@
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.
@@ -94,7 +89,7 @@
HB_TAG('p','s','t','s'),
};
static const hb_tag_t
-positioning_features[] =
+use_positioning_features[] =
{
/*
* Positioning features.
@@ -106,29 +101,21 @@
};
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)
@@ -136,7 +123,7 @@
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'));
@@ -145,32 +132,32 @@
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
@@ -247,16 +234,16 @@
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"
@@ -313,11 +300,11 @@
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];
@@ -327,39 +314,39 @@
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];
@@ -371,11 +358,11 @@
}
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);
@@ -383,20 +370,9 @@
}
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;
@@ -417,9 +393,9 @@
}
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;
@@ -436,22 +412,22 @@
}
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;
@@ -482,7 +458,7 @@
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
@@ -506,7 +482,7 @@
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. */
@@ -526,9 +502,9 @@
}
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;
@@ -539,7 +515,7 @@
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;
@@ -559,8 +535,8 @@
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;
@@ -584,29 +560,18 @@
}
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,
diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h
index cf6f0c9..df89bc5 100644
--- a/src/hb-ot-var.h
+++ b/src/hb-ot-var.h
@@ -68,7 +68,7 @@
typedef enum { /*< flags >*/
HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u,
- _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu /*< skip >*/
+ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_var_axis_flags_t;
/**
diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh
index 19e08eb..d9002f3 100644
--- a/src/hb-ot-vorg-table.hh
+++ b/src/hb-ot-vorg-table.hh
@@ -85,7 +85,7 @@
this->vertYOrigins.len = it.len ();
+ it
- | hb_apply ([c] (const VertOriginMetric& _) { c->copy (_);})
+ | hb_apply ([c] (const VertOriginMetric& _) { c->copy (_); })
;
}
diff --git a/src/hb-ot.h b/src/hb-ot.h
index db78469..f2dbaa1 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -35,6 +35,8 @@
#include "hb-ot-font.h"
#include "hb-ot-layout.h"
#include "hb-ot-math.h"
+#include "hb-ot-meta.h"
+#include "hb-ot-metrics.h"
#include "hb-ot-name.h"
#include "hb-ot-shape.h"
#include "hb-ot-var.h"
diff --git a/src/hb-set.cc b/src/hb-set.cc
index fa98688..10638a7 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -479,7 +479,7 @@
* @set: a set.
* @codepoint: (inout):
*
- * Gets the previous number in @set that is slower than current value of @codepoint.
+ * Gets the previous number in @set that is lower than current value of @codepoint.
*
* Set @codepoint to %HB_SET_VALUE_INVALID to get started.
*
@@ -524,7 +524,7 @@
* @last: (out): output last codepoint in the range.
*
* Gets the previous consecutive range of numbers in @set that
- * are greater than current value of @last.
+ * are less than current value of @first.
*
* Set @first to %HB_SET_VALUE_INVALID to get started.
*
diff --git a/src/hb-shape-plan.hh b/src/hb-shape-plan.hh
index 8e8d763..6da7edb 100644
--- a/src/hb-shape-plan.hh
+++ b/src/hb-shape-plan.hh
@@ -46,16 +46,16 @@
hb_shape_func_t *shaper_func;
const char *shaper_name;
- HB_INTERNAL inline bool init (bool copy,
- hb_face_t *face,
- const hb_segment_properties_t *props,
- const hb_feature_t *user_features,
- unsigned int num_user_features,
- const int *coords,
- unsigned int num_coords,
- const char * const *shaper_list);
+ HB_INTERNAL bool init (bool copy,
+ hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const int *coords,
+ unsigned int num_coords,
+ const char * const *shaper_list);
- HB_INTERNAL inline void free () { ::free ((void *) user_features); }
+ HB_INTERNAL void free () { ::free ((void *) user_features); }
HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other);
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 6b33c17..e244da1 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -179,7 +179,7 @@
unsigned max_glyph =
+ hb_iter (all_gids_to_retain)
- | hb_reduce (hb_max, 0)
+ | hb_reduce (hb_max, 0u)
;
*num_glyphs = max_glyph + 1;
}
diff --git a/src/hb-ucd.cc b/src/hb-ucd.cc
index 69949a2..b29f2a9 100644
--- a/src/hb-ucd.cc
+++ b/src/hb-ucd.cc
@@ -15,6 +15,7 @@
*/
#include "hb.hh"
+#include "hb-unicode.hh"
#include "hb-machinery.hh"
#include "hb-ucd-table.hh"
@@ -235,10 +236,6 @@
}
#endif
-extern "C" HB_INTERNAL
-hb_unicode_funcs_t *
-hb_ucd_get_unicode_funcs ();
-
hb_unicode_funcs_t *
hb_ucd_get_unicode_funcs ()
{
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index ed4fb77..9a81840 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -126,10 +126,12 @@
}
#endif
-
-extern "C" hb_unicode_funcs_t *hb_ucd_get_unicode_funcs ();
-extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs ();
-extern "C" hb_unicode_funcs_t *hb_icu_get_unicode_funcs ();
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
+#include "hb-glib.h"
+#endif
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
+#include "hb-icu.h"
+#endif
hb_unicode_funcs_t *
hb_unicode_funcs_get_default ()
diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh
index 021fa46..0c355f1 100644
--- a/src/hb-unicode.hh
+++ b/src/hb-unicode.hh
@@ -105,9 +105,6 @@
unsigned int
modified_combining_class (hb_codepoint_t u)
{
- /* XXX This hack belongs to the Myanmar shaper. */
- if (unlikely (u == 0x1037u)) u = 0x103Au;
-
/* XXX This hack belongs to the USE shaper (for Tai Tham):
* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (u == 0x1A60u)) return 254;
@@ -395,4 +392,7 @@
_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp);
+extern "C" HB_INTERNAL hb_unicode_funcs_t *hb_ucd_get_unicode_funcs ();
+
+
#endif /* HB_UNICODE_HH */
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 5c7ff87..289a347 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -58,13 +58,6 @@
* Functions for using HarfBuzz with the Windows fonts.
**/
-
-static inline uint16_t hb_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); }
-
-
typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
const WCHAR *pwcInChars,
int cInChars,
@@ -245,8 +238,9 @@
}
};
-
+#if HB_USE_ATEXIT
static void free_static_uniscribe_shaper_funcs ();
+#endif
static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_uniscribe_shaper_funcs_t,
hb_uniscribe_shaper_funcs_lazy_loader_t>
diff --git a/src/hb-vector.hh b/src/hb-vector.hh
index de16c97..035c6d0 100644
--- a/src/hb-vector.hh
+++ b/src/hb-vector.hh
@@ -143,13 +143,13 @@
operator writer_t () { return writer (); }
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t<Type> as_sorted_array ()
{ return hb_sorted_array (arrayZ, length); }
diff --git a/src/hb.hh b/src/hb.hh
index bee39cd..8dcd5aa 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -98,6 +98,7 @@
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
#pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
#pragma GCC diagnostic warning "-Wdeprecated"
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
#pragma GCC diagnostic warning "-Wdisabled-optimization"
#pragma GCC diagnostic warning "-Wdouble-promotion"
#pragma GCC diagnostic warning "-Wformat=2"
@@ -317,7 +318,8 @@
# define HB_FALLTHROUGH /* FALLTHROUGH */
#endif
-#ifdef __clang__
+/* https://github.com/harfbuzz/harfbuzz/issues/1852 */
+#if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
/* Disable certain sanitizer errors. */
/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
@@ -475,6 +477,11 @@
/* Size signifying variable-sized array */
#define VAR 1
+/* Endian swap, used in Windows related backends */
+static inline uint16_t hb_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); }
/*
* Big-endian integers. Here because fundamental.
diff --git a/src/test-ot-meta.cc b/src/test-ot-meta.cc
new file mode 100644
index 0000000..512df5a
--- /dev/null
+++ b/src/test-ot-meta.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb.hh"
+#include "hb-ot.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x) hb_blob_get_empty ()
+#endif
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s font-file\n", argv[0]);
+ exit (1);
+ }
+
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+ hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+ hb_blob_destroy (blob);
+ blob = nullptr;
+
+ unsigned int count = 0;
+
+#ifndef HB_NO_META
+ count = hb_ot_meta_get_entries (face, 0, nullptr, nullptr);
+
+ hb_ot_meta_tag_t *tags = (hb_ot_meta_tag_t *)
+ malloc (sizeof (hb_ot_meta_tag_t) * count);
+ hb_ot_meta_get_entries (face, 0, &count, tags);
+ for (unsigned i = 0; i < count; ++i)
+ {
+ hb_blob_t *entry = hb_ot_meta_reference_entry (face, tags[i]);
+ printf ("%c%c%c%c, size: %d: %.*s\n",
+ HB_UNTAG (tags[i]), hb_blob_get_length (entry),
+ hb_blob_get_length (entry), hb_blob_get_data (entry, nullptr));
+ hb_blob_destroy (entry);
+ }
+ free (tags);
+#endif
+
+ hb_face_destroy (face);
+
+ return !count;
+}
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index b9d4d79..2386e53 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -84,6 +84,8 @@
test-ot-color \
test-ot-ligature-carets \
test-ot-name \
+ test-ot-meta \
+ test-ot-metrics \
test-ot-tag \
test-ot-extents-cff \
$(NULL)
diff --git a/test/api/fonts/TestCFF2VF.otf b/test/api/fonts/TestCFF2VF.otf
new file mode 100644
index 0000000..a9e48e3
--- /dev/null
+++ b/test/api/fonts/TestCFF2VF.otf
Binary files differ
diff --git a/test/api/fonts/meta.ttf b/test/api/fonts/meta.ttf
new file mode 100644
index 0000000..414d7e6
--- /dev/null
+++ b/test/api/fonts/meta.ttf
Binary files differ
diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c
index c0cbd77..d646f73 100644
--- a/test/api/test-ot-color.c
+++ b/test/api/test-ot-color.c
@@ -426,9 +426,9 @@
g_assert (strncmp (data + 1, "PNG", 3) == 0);
hb_font_get_glyph_extents (sbix_font, 1, &extents);
g_assert_cmpint (extents.x_bearing, ==, 0);
- g_assert_cmpint (extents.y_bearing, ==, 0);
+ g_assert_cmpint (extents.y_bearing, ==, 800);
g_assert_cmpint (extents.width, ==, 800);
- g_assert_cmpint (extents.height, ==, 800);
+ g_assert_cmpint (extents.height, ==, -800);
hb_blob_destroy (blob);
hb_font_destroy (sbix_font);
diff --git a/test/api/test-ot-meta.c b/test/api/test-ot-meta.c
new file mode 100644
index 0000000..b8be5a3
--- /dev/null
+++ b/test/api/test-ot-meta.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2019 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb-test.h"
+
+#include <hb-ot.h>
+
+/* Unit tests for hb-ot-meta.h */
+
+static void
+test_ot_meta_get_entries (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+ hb_ot_meta_tag_t entries[2];
+
+ unsigned int entries_count = 2;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 0, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 2);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('a','p','p','l'));
+ g_assert_cmpint (entries[1], ==, HB_TAG ('b','i','l','d'));
+
+ entries_count = 1;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 2, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 1);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('d','l','n','g'));
+
+ entries_count = 2;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 4, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 1);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('s','l','n','g'));
+
+ hb_face_destroy (face);
+}
+
+static void
+test_ot_meta_reference_entry (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+ hb_blob_t *dlng = hb_ot_meta_reference_entry (face, HB_OT_META_DESIGN_LANGUAGES);
+ g_assert_cmpint (hb_blob_get_length (dlng), ==, 8);
+ g_assert_cmpmem (hb_blob_get_data (dlng, NULL), 8, "ar,de,fa", 8);
+ hb_blob_destroy (dlng);
+ hb_blob_t *fslf = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('f','s','l','f'));
+ g_assert_cmpint (hb_blob_get_length (fslf), ==, 12);
+ hb_blob_destroy (fslf);
+ hb_blob_t *nacl = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('n','a','c','l'));
+ g_assert_cmpint (hb_blob_get_length (nacl), ==, 0);
+ hb_blob_destroy (nacl);
+ hb_blob_t *slng = hb_ot_meta_reference_entry (face, HB_OT_META_SUPPORTED_LANGUAGES);
+ g_assert_cmpint (hb_blob_get_length (slng), ==, 11);
+ g_assert_cmpmem (hb_blob_get_data (slng, NULL), 11, "ar,de,en,fa", 11);
+ hb_blob_destroy (slng);
+ hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+ hb_test_init (&argc, &argv);
+ hb_test_add (test_ot_meta_get_entries);
+ hb_test_add (test_ot_meta_reference_entry);
+ return hb_test_run ();
+}
diff --git a/test/api/test-ot-metrics.c b/test/api/test-ot-metrics.c
new file mode 100644
index 0000000..9712c93
--- /dev/null
+++ b/test/api/test-ot-metrics.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * 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.
+ */
+
+#include "hb-test.h"
+
+#include <hb-ot.h>
+
+#include <math.h>
+
+/* Unit tests for hb-ot-metrics.h */
+
+static void
+test_ot_metrics_get_no_var (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf");
+ hb_font_t *font = hb_font_create (face);
+ hb_position_t value;
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_HORIZONTAL_ASCENDER, &value));
+ g_assert_cmpint (value, ==, 1000);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
+ // g_assert_cmpint ((int) hb_ot_metrics_get_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+static void
+test_ot_metrics_get_var (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/TestCFF2VF.otf");
+ hb_font_t *font = hb_font_create (face);
+ hb_position_t value;
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
+ g_assert_cmpint (value, ==, 486);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
+ float coords[] = {100.f};
+ hb_font_set_var_coords_design (font, coords, 1);
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
+ g_assert_cmpint (value, ==, 478);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, -8);
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+ hb_test_init (&argc, &argv);
+ hb_test_add (test_ot_metrics_get_no_var);
+ hb_test_add (test_ot_metrics_get_var);
+ return hb_test_run ();
+}
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960
new file mode 100644
index 0000000..0264a15
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960
Binary files differ
diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc
index 73c95b2..428765e 100644
--- a/test/fuzzing/hb-subset-fuzzer.cc
+++ b/test/fuzzing/hb-subset-fuzzer.cc
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <assert.h>
#include "hb-subset.h"
@@ -32,6 +33,19 @@
}
hb_face_t *result = hb_subset (face, input);
+ {
+ hb_blob_t *blob = hb_face_reference_blob (result);
+ unsigned int length;
+ const char *data = hb_blob_get_data (blob, &length);
+
+ // Something not optimizable just to access all the blob data
+ unsigned int bytes_count = 0;
+ for (unsigned int i = 0; i < length; ++i)
+ if (data[i]) ++bytes_count;
+ assert (bytes_count || !length);
+
+ hb_blob_destroy (blob);
+ }
hb_face_destroy (result);
hb_subset_input_destroy (input);
diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py
index ba480dd..6d36c2c 100755
--- a/test/fuzzing/run-shape-fuzzer-tests.py
+++ b/test/fuzzing/run-shape-fuzzer-tests.py
@@ -5,41 +5,41 @@
import sys, os, subprocess, tempfile, threading
-def which(program):
+def which (program):
# https://stackoverflow.com/a/377028
- def is_exe(fpath):
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+ def is_exe (fpath):
+ return os.path.isfile (fpath) and os.access (fpath, os.X_OK)
- fpath, _ = os.path.split(program)
+ fpath, _ = os.path.split (program)
if fpath:
- if is_exe(program):
+ if is_exe (program):
return program
else:
- for path in os.environ["PATH"].split(os.pathsep):
- exe_file = os.path.join(path, program)
- if is_exe(exe_file):
+ for path in os.environ["PATH"].split (os.pathsep):
+ exe_file = os.path.join (path, program)
+ if is_exe (exe_file):
return exe_file
return None
-def cmd(command):
+def cmd (command):
# https://stackoverflow.com/a/4408409
# https://stackoverflow.com/a/10012262
- with tempfile.TemporaryFile() as tempf:
+ with tempfile.TemporaryFile () as tempf:
p = subprocess.Popen (command, stderr=tempf)
is_killed = {'value': False}
- def timeout(p, is_killed):
+ def timeout (p, is_killed):
is_killed['value'] = True
- p.kill()
+ p.kill ()
timer = threading.Timer (2, timeout, [p, is_killed])
try:
timer.start()
p.wait ()
tempf.seek (0)
- text = tempf.read().decode ("utf-8").strip ()
+ text = tempf.read ().decode ("utf-8").strip ()
returncode = p.returncode
finally:
timer.cancel()
@@ -67,9 +67,9 @@
print ('hb_shape_fuzzer:', hb_shape_fuzzer)
fails = 0
-libtool = os.environ.get('LIBTOOL')
+libtool = os.environ.get ('LIBTOOL')
valgrind = None
-if os.environ.get('RUN_VALGRIND', ''):
+if os.environ.get ('RUN_VALGRIND', ''):
valgrind = which ('valgrind')
if valgrind is None:
print ("""Valgrind requested but not found.""")
@@ -80,7 +80,7 @@
parent_path = os.path.join (srcdir, "fonts")
for file in os.listdir (parent_path):
- path = os.path.join(parent_path, file)
+ path = os.path.join (parent_path, file)
if valgrind:
text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --error-exitcode=1', '--', hb_shape_fuzzer, path])
@@ -89,7 +89,7 @@
if 'error' in text:
returncode = 1
- if not valgrind and text.strip ():
+ if (not valgrind or returncode) and text.strip ():
print (text)
if returncode != 0:
diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py
index 3ac2288..f94c13f 100755
--- a/test/fuzzing/run-subset-fuzzer-tests.py
+++ b/test/fuzzing/run-subset-fuzzer-tests.py
@@ -33,7 +33,7 @@
def timeout(p, is_killed):
is_killed['value'] = True
p.kill()
- timer = threading.Timer (2, timeout, [p, is_killed])
+ timer = threading.Timer (8, timeout, [p, is_killed])
try:
timer.start()
@@ -82,6 +82,8 @@
global fails
for file in os.listdir (parent_path):
path = os.path.join(parent_path, file)
+ # TODO: Run on all the fonts not just subset related ones
+ if "subset" not in path: continue
print ("running subset fuzzer against %s" % path)
if valgrind:
@@ -91,7 +93,7 @@
if 'error' in text:
returncode = 1
- if not valgrind and text.strip ():
+ if (not valgrind or returncode) and text.strip ():
print (text)
if returncode != 0:
@@ -100,8 +102,7 @@
run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts"))
-# TODO running these tests very slow tests. Fix and re-enable
-#run_dir (os.path.join (srcdir, "fonts"))
+run_dir (os.path.join (srcdir, "fonts"))
if fails:
print ("%i subset fuzzer related tests failed." % fails)
diff --git a/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf b/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf
new file mode 100644
index 0000000..b1a8a33
--- /dev/null
+++ b/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf
Binary files differ
diff --git a/test/shaping/data/in-house/tests/color-fonts.tests b/test/shaping/data/in-house/tests/color-fonts.tests
index b325d78..bf0005c 100644
--- a/test/shaping/data/in-house/tests/color-fonts.tests
+++ b/test/shaping/data/in-house/tests/color-fonts.tests
@@ -1 +1,2 @@
../fonts/ee39587d13b2afa5499cc79e45780aa79293bbd4.ttf:--font-funcs=ot --show-extents:U+1F42F:[gid1=0+2963<0,2179,2963,-2789>]
+../fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf:--font-funcs=ot --show-extents:U+1F600:[gid4=0+2550<0,1898,2555,-2405>]
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf
new file mode 100644
index 0000000..5de8d89
--- /dev/null
+++ b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..e3c0727
--- /dev/null
+++ b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf
new file mode 100644
index 0000000..6425ecf
--- /dev/null
+++ b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..fbb8c33
--- /dev/null
+++ b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..cc2805a
--- /dev/null
+++ b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf
new file mode 100644
index 0000000..12d9208
--- /dev/null
+++ b/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..52dc474
--- /dev/null
+++ b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf
new file mode 100644
index 0000000..52dc474
--- /dev/null
+++ b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..12d9208
--- /dev/null
+++ b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf
new file mode 100644
index 0000000..12d9208
--- /dev/null
+++ b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf
Binary files differ
diff --git a/test/subset/data/tests/basics.tests b/test/subset/data/tests/basics.tests
index c310722..772f33c 100644
--- a/test/subset/data/tests/basics.tests
+++ b/test/subset/data/tests/basics.tests
@@ -15,3 +15,4 @@
c
ac
a
+*
diff --git a/test/subset/subset_test_suite.py b/test/subset/subset_test_suite.py
index ad438ee..47664d0 100644
--- a/test/subset/subset_test_suite.py
+++ b/test/subset/subset_test_suite.py
@@ -12,7 +12,10 @@
self.subset = subset
def unicodes(self):
- return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
+ if self.subset == '*':
+ return self.subset[0]
+ else:
+ return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
def get_profile_flags(self):
with io.open(self.profile_path, mode="r", encoding="utf-8") as f:
@@ -23,7 +26,12 @@
font_base_name_parts = os.path.splitext(font_base_name)
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
- return "%s.%s.%s%s" % (font_base_name_parts[0],
+ if self.unicodes() == "*":
+ return "%s.%s.retain-all-codepoint%s" % (font_base_name_parts[0],
+ profile_name,
+ font_base_name_parts[1])
+ else:
+ return "%s.%s.%s%s" % (font_base_name_parts[0],
profile_name,
self.unicodes(),
font_base_name_parts[1])
@@ -39,9 +47,9 @@
def __init__(self, test_path, definition):
self.test_path = test_path
- self.fonts = set()
- self.profiles = set()
- self.subsets = set()
+ self.fonts = []
+ self.profiles = []
+ self.subsets = []
self._parse(definition)
def get_output_directory(self):
@@ -87,6 +95,6 @@
if line in destinations:
current_destination = destinations[line]
elif current_destination is not None:
- current_destination.add(line)
+ current_destination.append(line)
else:
raise Exception("Failed to parse test suite file.")
diff --git a/util/hb-subset.cc b/util/hb-subset.cc
index 4b7af8e..6d87c56 100644
--- a/util/hb-subset.cc
+++ b/util/hb-subset.cc
@@ -53,6 +53,13 @@
{
// TODO(Q1) does this only get called with at least 1 codepoint?
hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+ if (0 == strcmp (text, "*"))
+ {
+ hb_face_t *face = hb_font_get_face (font);
+ hb_face_collect_unicodes (face, codepoints);
+ return;
+ }
+
gchar *c = (gchar *)text;
do {
gunichar cp = g_utf8_get_char(c);
diff --git a/util/options.cc b/util/options.cc
index 4e6ca57..f71a5a3 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -349,28 +349,37 @@
}
GString *gs = g_string_new (nullptr);
- char *s = (char *) arg;
- char *p;
-
- while (s && *s)
+ if (0 == strcmp (arg, "*"))
{
- while (*s && strchr (DELIMITERS, *s))
- s++;
- if (!*s)
- break;
+ g_string_append_c (gs, '*');
+ }
+ else
+ {
- errno = 0;
- hb_codepoint_t u = strtoul (s, &p, 16);
- if (errno || s == p)
+ char *s = (char *) arg;
+ char *p;
+
+ while (s && *s)
{
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed parsing Unicode values at: '%s'", s);
- return false;
+ while (*s && strchr (DELIMITERS, *s))
+ s++;
+ if (!*s)
+ break;
+
+ errno = 0;
+ hb_codepoint_t u = strtoul (s, &p, 16);
+ if (errno || s == p)
+ {
+ g_string_free (gs, TRUE);
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Failed parsing Unicode values at: '%s'", s);
+ return false;
+ }
+
+ g_string_append_unichar (gs, u);
+
+ s = p;
}
-
- g_string_append_unichar (gs, u);
-
- s = p;
}
text_opts->text_len = gs->len;