Merge branch 'master' into subset-varstore
This commit is contained in:
commit
f0dd724c1e
|
@ -264,7 +264,7 @@ jobs:
|
|||
- image: dockcross/android-arm
|
||||
steps:
|
||||
- checkout
|
||||
- run: cmake -Bbuild -H. -GNinja
|
||||
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
|
||||
- run: ninja -Cbuild
|
||||
|
||||
crosscompile-cmake-notest-browser-asmjs-hb_tiny:
|
||||
|
@ -272,7 +272,7 @@ jobs:
|
|||
- image: dockcross/browser-asmjs
|
||||
steps:
|
||||
- checkout
|
||||
- run: cmake -Bbuild -H. -GNinja -DCMAKE_CXX_FLAGS="-DHB_TINY"
|
||||
- run: cmake -Bbuild -H. -GNinja -DCMAKE_CXX_FLAGS="-DHB_TINY" -DHB_BUILD_TESTS=OFF
|
||||
- run: ninja -Cbuild
|
||||
|
||||
crosscompile-cmake-notest-linux-arm64:
|
||||
|
@ -280,7 +280,7 @@ jobs:
|
|||
- image: dockcross/linux-arm64
|
||||
steps:
|
||||
- checkout
|
||||
- run: cmake -Bbuild -H. -GNinja
|
||||
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
|
||||
- run: ninja -Cbuild
|
||||
|
||||
crosscompile-cmake-notest-linux-mips:
|
||||
|
@ -288,7 +288,7 @@ jobs:
|
|||
- image: dockcross/linux-mips
|
||||
steps:
|
||||
- checkout
|
||||
- run: cmake -Bbuild -H. -GNinja
|
||||
- run: cmake -Bbuild -H. -GNinja -DHB_BUILD_TESTS=OFF
|
||||
- run: ninja -Cbuild
|
||||
|
||||
#crosscompile-cmake-notest-windows-x64:
|
||||
|
|
|
@ -43,6 +43,7 @@ if (APPLE)
|
|||
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 @@ if (HB_CHECK)
|
|||
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 @@ endif ()
|
|||
|
||||
## 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 @@ endfunction ()
|
|||
file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
|
||||
file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
|
||||
|
||||
extract_make_variable(HB_BASE_sources ${SRCSOURCES})
|
||||
add_prefix_to_list(HB_BASE_sources "${PROJECT_SOURCE_DIR}/src/")
|
||||
extract_make_variable(HB_BASE_headers ${SRCSOURCES})
|
||||
add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
|
||||
|
||||
|
@ -192,59 +192,12 @@ set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
|
|||
set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
|
||||
set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
|
||||
|
||||
|
||||
## Define ragel tasks
|
||||
# if (NOT IN_HB_DIST)
|
||||
# foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources})
|
||||
# string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
|
||||
# set (target_name ${CMAKE_MATCH_1})
|
||||
# add_custom_command(OUTPUT ${ragel_output}
|
||||
# COMMAND ${RAGEL} -G2 -o ${ragel_output} ${PROJECT_SOURCE_DIR}/src/${target_name}.rl -I ${PROJECT_SOURCE_DIR} ${ARGN}
|
||||
# DEPENDS ${PROJECT_SOURCE_DIR}/src/${target_name}.rl
|
||||
# )
|
||||
# add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
|
||||
# endforeach ()
|
||||
|
||||
# mark_as_advanced(RAGEL)
|
||||
# endif ()
|
||||
|
||||
|
||||
## Generate hb-version.h
|
||||
# if (NOT IN_HB_DIST)
|
||||
# set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
|
||||
# set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
|
||||
# set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
|
||||
# configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
|
||||
# execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
# "${HB_VERSION_H}.tmp"
|
||||
# "${HB_VERSION_H}"
|
||||
# )
|
||||
# file(REMOVE "${HB_VERSION_H}.tmp")
|
||||
# endif ()
|
||||
|
||||
|
||||
## Define sources and headers of the project
|
||||
set (project_sources
|
||||
${HB_BASE_sources}
|
||||
${HB_BASE_RAGEL_GENERATED_sources}
|
||||
)
|
||||
|
||||
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 @@ if (HB_HAVE_FREETYPE)
|
|||
include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
|
||||
add_definitions(-DHAVE_FREETYPE=1)
|
||||
|
||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
|
||||
|
||||
# So check_funcs can find its headers
|
||||
|
@ -275,7 +227,6 @@ if (HB_HAVE_GRAPHITE2)
|
|||
|
||||
include_directories(${GRAPHITE2_INCLUDE_DIR})
|
||||
|
||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-graphite2.cc)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
|
||||
|
||||
list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
|
||||
|
@ -296,7 +247,6 @@ if (HB_HAVE_GLIB)
|
|||
|
||||
include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
|
||||
|
||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-glib.cc)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
|
||||
|
||||
list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
|
||||
|
@ -316,7 +266,6 @@ if (HB_HAVE_ICU)
|
|||
|
||||
include_directories(${ICU_INCLUDE_DIR})
|
||||
|
||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-icu.cc)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
|
||||
|
||||
list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
|
||||
|
@ -328,7 +277,6 @@ if (APPLE AND HB_HAVE_CORETEXT)
|
|||
# Apple Advanced Typography
|
||||
add_definitions(-DHAVE_CORETEXT)
|
||||
|
||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
|
||||
|
||||
if (HB_IOS)
|
||||
|
@ -359,21 +307,21 @@ if (APPLE AND HB_HAVE_CORETEXT)
|
|||
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 @@ if (HB_HAVE_GOBJECT)
|
|||
)
|
||||
endif ()
|
||||
|
||||
|
||||
## Atomic ops availability detection
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
|
||||
" void memory_barrier (void) { __sync_synchronize (); }
|
||||
|
@ -590,7 +537,6 @@ if (WIN32)
|
|||
endif ()
|
||||
|
||||
if (HB_HAVE_INTROSPECTION)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
|
||||
|
||||
|
@ -824,7 +770,7 @@ endif ()
|
|||
|
||||
if (HB_BUILD_TESTS)
|
||||
## src/ executables
|
||||
foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
|
||||
foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize test-unicode-ranges) # hb-ot-tag
|
||||
set (prog_name ${prog})
|
||||
if (${prog_name} STREQUAL "test")
|
||||
# test can not be used as a valid executable name on cmake, lets special case it
|
||||
|
@ -833,7 +779,7 @@ if (HB_BUILD_TESTS)
|
|||
add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
|
||||
target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
|
||||
endforeach ()
|
||||
set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
|
||||
# set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
|
||||
|
||||
## Tests
|
||||
if (UNIX OR MINGW)
|
||||
|
|
|
@ -73,7 +73,7 @@ build_script:
|
|||
- '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\
|
||||
|
|
23
configure.ac
23
configure.ac
|
@ -361,6 +361,28 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
|
|||
|
||||
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 @@ Additional shapers (the more the merrier):
|
|||
Platform shapers (not normally needed):
|
||||
CoreText: ${have_coretext}
|
||||
DirectWrite: ${have_directwrite}
|
||||
GDI: ${have_gdi}
|
||||
Uniscribe: ${have_uniscribe}
|
||||
|
||||
Other features:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<SUBSECTION Private>
|
||||
HB_H_IN
|
||||
HB_OT_H_IN
|
||||
HB_AAT_H_IN
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -179,6 +180,7 @@ HB_BUFFER_SERIALIZE_FLAGS_DEFAULT
|
|||
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
|
||||
|
@ -367,6 +369,11 @@ hb_ft_font_get_load_flags
|
|||
hb_ft_font_set_funcs
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-gdi</FILE>
|
||||
hb_gdi_face_create
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-glib</FILE>
|
||||
hb_glib_get_unicode_funcs
|
||||
|
@ -600,6 +607,22 @@ hb_ot_math_get_min_connector_overlap
|
|||
hb_ot_math_get_glyph_assembly
|
||||
</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
|
||||
|
|
|
@ -156,14 +156,16 @@
|
|||
order.
|
||||
</para>
|
||||
<para>
|
||||
For left-to-right scripts (LTR) and top-to-bottom scripts (TTB),
|
||||
For buffers in the left-to-right (LTR)
|
||||
or top-to-bottom (TTB) text flow direction,
|
||||
HarfBuzz will preserve the monotonic property: client programs
|
||||
are guaranteed that monotonically increasing initial cluster
|
||||
values will be returned as monotonically increasing final
|
||||
cluster values.
|
||||
</para>
|
||||
<para>
|
||||
For right-to-left scripts (RTL) and bottom-to-top scripts (BTT),
|
||||
For buffers in the right-to-left (RTL)
|
||||
or bottom-to-top (BTT) text flow direction,
|
||||
the directionality of the buffer itself is reversed for final
|
||||
output as a matter of design. Therefore, HarfBuzz inverts the
|
||||
monotonic property: client programs are guaranteed that
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
objects. <function>hb_font_set_ppem(font, x_ppem,
|
||||
y_ppem)</function> sets the pixels-per-EM value of the font. You
|
||||
can also set the point size of the font with
|
||||
<function>hb_font_set_ppem(font, ptem)</function>. HarfBuzz uses the
|
||||
<function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
|
||||
industry standard 72 points per inch.
|
||||
</para>
|
||||
<para>
|
||||
|
|
|
@ -12,6 +12,8 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
|
|||
TESTS =
|
||||
check_PROGRAMS =
|
||||
|
||||
EXTRA_DIST += harfbuzz.cc
|
||||
|
||||
# Convenience targets:
|
||||
lib: $(BUILT_SOURCES) libharfbuzz.la
|
||||
libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
|
||||
|
@ -80,6 +82,13 @@ HBSOURCES += $(HB_DIRECTWRITE_sources)
|
|||
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 @@ GENERATORS = \
|
|||
$(NULL)
|
||||
EXTRA_DIST += $(GENERATORS)
|
||||
|
||||
unicode-tables: arabic-table indic-table tag-table use-table emoji-table
|
||||
unicode-tables: \
|
||||
arabic-table \
|
||||
emoji-table \
|
||||
indic-table \
|
||||
tag-table \
|
||||
ucd-table \
|
||||
use-table \
|
||||
emoji-table \
|
||||
$(NULL)
|
||||
|
||||
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
|
||||
|
||||
emoji-table: gen-emoji-table.py emoji-data.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
|
||||
indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
|
||||
|
||||
tag-table: gen-tag-table.py languagetags language-subtag-registry
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
|
||||
|
||||
ucd-table: gen-ucd-table.py ucd.nounihan.grouped.zip hb-common.h
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ucd-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-ucd-table.hh; false)
|
||||
use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
|
||||
|
||||
vowel-constraints: gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc; false)
|
||||
|
||||
emoji-table: gen-emoji-table.py emoji-data.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
|
||||
|
||||
built-sources: $(BUILT_SOURCES)
|
||||
|
||||
|
@ -296,10 +312,27 @@ $(srcdir)/%.hh: $(srcdir)/%.rl
|
|||
$(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \
|
||||
|| ($(RM) "$@"; false)
|
||||
|
||||
harfbuzz.cc: Makefile.sources
|
||||
$(AM_V_GEN) \
|
||||
for f in \
|
||||
$(HB_BASE_sources) \
|
||||
$(HB_GLIB_sources) \
|
||||
$(HB_FT_sources) \
|
||||
$(HB_GRAPHITE2_sources) \
|
||||
$(HB_UNISCRIBE_sources) \
|
||||
$(HB_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_SOURCES = test-buffer-serialize.cc
|
|||
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)
|
||||
|
|
|
@ -88,6 +88,10 @@ HB_BASE_sources = \
|
|||
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_BASE_headers = \
|
|||
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_CORETEXT_headers = hb-coretext.h
|
|||
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
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import io, os.path, sys, re
|
|||
import logging
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
|
||||
|
||||
if len (sys.argv) != 2:
|
||||
print("usage: ./gen-ucd-table ucd.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 @@ logging.info('Loading UCDXML...')
|
|||
ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
|
||||
ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)
|
||||
|
||||
hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2]
|
||||
|
||||
logging.info('Preparing data tables...')
|
||||
|
||||
gc = [u['gc'] for u in ucd]
|
||||
|
@ -68,7 +70,7 @@ for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu'
|
|||
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)
|
||||
|
|
|
@ -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"
|
|
@ -174,9 +174,7 @@ struct feat
|
|||
}
|
||||
|
||||
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 (); }
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef enum
|
|||
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 @@ typedef enum
|
|||
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
|
||||
|
|
|
@ -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 @@ HB_FUNCOBJ (hb_bool);
|
|||
struct
|
||||
{
|
||||
private:
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||
|
||||
template <typename T,
|
||||
hb_enable_if (hb_is_integral (T))> auto
|
||||
hb_enable_if (hb_is_integral (T))> constexpr auto
|
||||
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(
|
||||
/* Knuth's multiplicative method: */
|
||||
|
@ -95,7 +95,7 @@ struct
|
|||
|
||||
public:
|
||||
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
|
||||
}
|
||||
HB_FUNCOBJ (hb_hash);
|
||||
|
@ -328,14 +328,14 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
|
|||
|
||||
struct
|
||||
{
|
||||
template <typename Pair> typename Pair::first_t
|
||||
template <typename Pair> constexpr typename Pair::first_t
|
||||
operator () (const Pair& pair) const { return pair.first; }
|
||||
}
|
||||
HB_FUNCOBJ (hb_first);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename Pair> typename Pair::second_t
|
||||
template <typename Pair> constexpr typename Pair::second_t
|
||||
operator () (const Pair& pair) const { return pair.second; }
|
||||
}
|
||||
HB_FUNCOBJ (hb_second);
|
||||
|
@ -346,14 +346,14 @@ HB_FUNCOBJ (hb_second);
|
|||
* comparing integers of different signedness. */
|
||||
struct
|
||||
{
|
||||
template <typename T, typename T2> auto
|
||||
template <typename T, typename T2> constexpr auto
|
||||
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
|
||||
(hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
|
||||
}
|
||||
HB_FUNCOBJ (hb_min);
|
||||
struct
|
||||
{
|
||||
template <typename T, typename T2> auto
|
||||
template <typename T, typename T2> constexpr auto
|
||||
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
|
||||
(hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ struct hb_bitwise_and
|
|||
{ HB_PARTIALIZE(2);
|
||||
static constexpr bool passthru_left = false;
|
||||
static constexpr bool passthru_right = false;
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
|
||||
}
|
||||
HB_FUNCOBJ (hb_bitwise_and);
|
||||
|
@ -925,7 +925,7 @@ struct hb_bitwise_or
|
|||
{ HB_PARTIALIZE(2);
|
||||
static constexpr bool passthru_left = true;
|
||||
static constexpr bool passthru_right = true;
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
|
||||
}
|
||||
HB_FUNCOBJ (hb_bitwise_or);
|
||||
|
@ -933,7 +933,7 @@ struct hb_bitwise_xor
|
|||
{ HB_PARTIALIZE(2);
|
||||
static constexpr bool passthru_left = true;
|
||||
static constexpr bool passthru_right = true;
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
|
||||
}
|
||||
HB_FUNCOBJ (hb_bitwise_xor);
|
||||
|
@ -941,56 +941,56 @@ struct hb_bitwise_sub
|
|||
{ HB_PARTIALIZE(2);
|
||||
static constexpr bool passthru_left = true;
|
||||
static constexpr bool passthru_right = false;
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
|
||||
}
|
||||
HB_FUNCOBJ (hb_bitwise_sub);
|
||||
struct
|
||||
{
|
||||
template <typename T> 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);
|
||||
|
|
|
@ -378,7 +378,7 @@ typedef hb_vector_t<byte_str_t> byte_str_array_t;
|
|||
|
||||
/* stack */
|
||||
template <typename ELEM, int LIMIT>
|
||||
struct stack_t
|
||||
struct cff_stack_t
|
||||
{
|
||||
void init ()
|
||||
{
|
||||
|
@ -469,7 +469,7 @@ struct stack_t
|
|||
|
||||
/* argument stack */
|
||||
template <typename ARG=number_t>
|
||||
struct arg_stack_t : stack_t<ARG, 513>
|
||||
struct arg_stack_t : cff_stack_t<ARG, 513>
|
||||
{
|
||||
void push_int (int v)
|
||||
{
|
||||
|
@ -523,7 +523,7 @@ struct arg_stack_t : stack_t<ARG, 513>
|
|||
{ 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 */
|
||||
|
|
|
@ -57,7 +57,7 @@ struct call_context_t
|
|||
|
||||
/* call stack */
|
||||
const unsigned int kMaxCallLimit = 10;
|
||||
struct call_stack_t : stack_t<call_context_t, kMaxCallLimit> {};
|
||||
struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
|
||||
|
||||
template <typename SUBRS>
|
||||
struct biased_subrs_t
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -75,7 +75,7 @@ release_table_data (void *user_data)
|
|||
}
|
||||
|
||||
static hb_blob_t *
|
||||
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
|
||||
CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
|
||||
|
@ -299,7 +299,7 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
|
|||
hb_face_t *
|
||||
hb_coretext_face_create (CGFontRef cg_font)
|
||||
{
|
||||
return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
|
||||
return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -539,11 +539,6 @@ protected:
|
|||
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 @@ _hb_directwrite_table_data_release (void *data)
|
|||
}
|
||||
|
||||
static hb_blob_t *
|
||||
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
_hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
IDWriteFontFace *dw_face = ((IDWriteFontFace *) user_data);
|
||||
const void *data;
|
||||
|
@ -979,7 +974,7 @@ hb_directwrite_face_create (IDWriteFontFace *font_face)
|
|||
{
|
||||
if (font_face)
|
||||
font_face->AddRef ();
|
||||
return hb_face_create_for_tables (reference_table, font_face,
|
||||
return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face,
|
||||
_hb_directwrite_font_release);
|
||||
}
|
||||
|
||||
|
|
|
@ -1300,6 +1300,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
|
|||
|
||||
1000, /* x_scale */
|
||||
1000, /* y_scale */
|
||||
1<<16, /* x_mult */
|
||||
1<<16, /* y_mult */
|
||||
|
||||
0, /* x_ppem */
|
||||
0, /* y_ppem */
|
||||
|
@ -1330,6 +1332,7 @@ _hb_font_create (hb_face_t *face)
|
|||
font->klass = hb_font_funcs_get_empty ();
|
||||
font->data.init0 (font);
|
||||
font->x_scale = font->y_scale = hb_face_get_upem (face);
|
||||
font->x_mult = font->y_mult = 1 << 16;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
@ -1601,7 +1604,9 @@ hb_font_set_face (hb_font_t *font,
|
|||
|
||||
hb_face_t *old = font->face;
|
||||
|
||||
hb_face_make_immutable (face);
|
||||
font->face = hb_face_reference (face);
|
||||
font->mults_changed ();
|
||||
|
||||
hb_face_destroy (old);
|
||||
}
|
||||
|
@ -1711,6 +1716,7 @@ hb_font_set_scale (hb_font_t *font,
|
|||
|
||||
font->x_scale = x_scale;
|
||||
font->y_scale = y_scale;
|
||||
font->mults_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -107,8 +107,10 @@ struct hb_font_t
|
|||
hb_font_t *parent;
|
||||
hb_face_t *face;
|
||||
|
||||
int x_scale;
|
||||
int y_scale;
|
||||
int32_t x_scale;
|
||||
int32_t y_scale;
|
||||
int64_t x_mult;
|
||||
int64_t y_mult;
|
||||
|
||||
unsigned int x_ppem;
|
||||
unsigned int y_ppem;
|
||||
|
@ -127,16 +129,16 @@ struct hb_font_t
|
|||
|
||||
|
||||
/* Convert from font-space to user-space */
|
||||
int dir_scale (hb_direction_t direction)
|
||||
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
|
||||
hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
|
||||
hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
|
||||
hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
|
||||
hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
|
||||
int64_t dir_mult (hb_direction_t direction)
|
||||
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
|
||||
hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
|
||||
hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
|
||||
hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); }
|
||||
hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
|
||||
float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
|
||||
float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
|
||||
hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
|
||||
{ return em_scale (v, dir_scale (direction)); }
|
||||
{ return em_mult (v, dir_mult (direction)); }
|
||||
|
||||
/* Convert from parent-font user-space to our user-space */
|
||||
hb_position_t parent_scale_x_distance (hb_position_t v)
|
||||
|
@ -607,12 +609,16 @@ struct hb_font_t
|
|||
return false;
|
||||
}
|
||||
|
||||
hb_position_t em_scale (int16_t v, int scale)
|
||||
void mults_changed ()
|
||||
{
|
||||
int upem = face->get_upem ();
|
||||
int64_t scaled = v * (int64_t) scale;
|
||||
scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
|
||||
return (hb_position_t) (scaled / upem);
|
||||
signed upem = face->get_upem ();
|
||||
x_mult = ((int64_t) x_scale << 16) / upem;
|
||||
y_mult = ((int64_t) y_scale << 16) / upem;
|
||||
}
|
||||
|
||||
hb_position_t em_mult (int16_t v, int64_t mult)
|
||||
{
|
||||
return (hb_position_t) ((v * mult) >> 16);
|
||||
}
|
||||
hb_position_t em_scalef (float v, int scale)
|
||||
{ return (hb_position_t) roundf (v * scale / face->get_upem ()); }
|
||||
|
|
|
@ -564,7 +564,7 @@ _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
|
|||
|
||||
|
||||
static hb_blob_t *
|
||||
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
_hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
FT_Face ft_face = (FT_Face) user_data;
|
||||
FT_Byte *buffer;
|
||||
|
@ -619,7 +619,7 @@ hb_ft_face_create (FT_Face ft_face,
|
|||
face = hb_face_create (blob, ft_face->face_index);
|
||||
hb_blob_destroy (blob);
|
||||
} else {
|
||||
face = hb_face_create_for_tables (reference_table, ft_face, destroy);
|
||||
face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy);
|
||||
}
|
||||
|
||||
hb_face_set_index (face, ft_face->face_index);
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -106,32 +106,6 @@ retry:
|
|||
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 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
|||
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);
|
||||
|
|
|
@ -480,7 +480,7 @@ struct hb_reduce_t
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -80,8 +80,8 @@ template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::t
|
|||
|
||||
struct
|
||||
{
|
||||
template <typename T>
|
||||
T* operator () (T& arg) const
|
||||
template <typename T> constexpr T*
|
||||
operator () (T& arg) const
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
@ -171,29 +171,29 @@ using hb_is_cr_convertible = hb_bool_constant<
|
|||
/* std::move and std::forward */
|
||||
|
||||
template <typename T>
|
||||
static hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
|
||||
static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
|
||||
|
||||
template <typename T>
|
||||
static T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
|
||||
static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
|
||||
template <typename T>
|
||||
static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
|
||||
static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
|
||||
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (T *v) const HB_AUTO_RETURN (*v)
|
||||
}
|
||||
HB_FUNCOBJ (hb_deref);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
|
||||
|
||||
template <typename T> auto
|
||||
template <typename T> constexpr auto
|
||||
operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
|
||||
}
|
||||
HB_FUNCOBJ (hb_ref);
|
||||
|
|
|
@ -141,14 +141,15 @@ typedef struct OffsetTable
|
|||
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);
|
||||
|
|
|
@ -576,13 +576,13 @@ struct ArrayOf
|
|||
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 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -210,7 +210,7 @@ struct bounds_t
|
|||
point_t max;
|
||||
};
|
||||
|
||||
struct extents_param_t
|
||||
struct cff1_extents_param_t
|
||||
{
|
||||
void init (const OT::cff1::accelerator_t *_cff)
|
||||
{
|
||||
|
@ -229,15 +229,15 @@ struct extents_param_t
|
|||
const OT::cff1::accelerator_t *cff;
|
||||
};
|
||||
|
||||
struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, extents_param_t>
|
||||
struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, cff1_extents_param_t>
|
||||
{
|
||||
static void moveto (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
|
||||
static void moveto (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt)
|
||||
{
|
||||
param.end_path ();
|
||||
env.moveto (pt);
|
||||
}
|
||||
|
||||
static void line (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
|
||||
static void line (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1)
|
||||
{
|
||||
if (!param.is_path_open ())
|
||||
{
|
||||
|
@ -248,7 +248,7 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
|
|||
param.bounds.update (env.get_pt ());
|
||||
}
|
||||
|
||||
static void curve (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
|
||||
static void curve (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
|
||||
{
|
||||
if (!param.is_path_open ())
|
||||
{
|
||||
|
@ -265,9 +265,9 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
|
|||
|
||||
static bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
|
||||
|
||||
struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, extents_param_t, cff1_path_procs_extents_t>
|
||||
struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, cff1_extents_param_t, cff1_path_procs_extents_t>
|
||||
{
|
||||
static void process_seac (cff1_cs_interp_env_t &env, extents_param_t& param)
|
||||
static void process_seac (cff1_cs_interp_env_t &env, cff1_extents_param_t& param)
|
||||
{
|
||||
unsigned int n = env.argStack.get_count ();
|
||||
point_t delta;
|
||||
|
@ -296,11 +296,11 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
|
|||
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
|
||||
|
||||
unsigned int fd = cff->fdSelect->get_fd (glyph);
|
||||
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, extents_param_t> interp;
|
||||
cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp;
|
||||
const byte_str_t str = (*cff->charStrings)[glyph];
|
||||
interp.env.init (str, *cff, fd);
|
||||
interp.env.set_in_seac (in_seac);
|
||||
extents_param_t param;
|
||||
cff1_extents_param_t param;
|
||||
param.init (cff);
|
||||
if (unlikely (!interp.interpret (param))) return false;
|
||||
bounds = param.bounds;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
using namespace CFF;
|
||||
|
||||
struct extents_param_t
|
||||
struct cff2_extents_param_t
|
||||
{
|
||||
void init ()
|
||||
{
|
||||
|
@ -63,15 +63,15 @@ struct extents_param_t
|
|||
number_t max_y;
|
||||
};
|
||||
|
||||
struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, extents_param_t>
|
||||
struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, cff2_extents_param_t>
|
||||
{
|
||||
static void moveto (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
|
||||
static void moveto (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt)
|
||||
{
|
||||
param.end_path ();
|
||||
env.moveto (pt);
|
||||
}
|
||||
|
||||
static void line (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
|
||||
static void line (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1)
|
||||
{
|
||||
if (!param.is_path_open ())
|
||||
{
|
||||
|
@ -82,7 +82,7 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
|
|||
param.update_bounds (env.get_pt ());
|
||||
}
|
||||
|
||||
static void curve (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
|
||||
static void curve (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
|
||||
{
|
||||
if (!param.is_path_open ())
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
|
|||
}
|
||||
};
|
||||
|
||||
struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, extents_param_t, cff2_path_procs_extents_t> {};
|
||||
struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_extents_param_t, cff2_path_procs_extents_t> {};
|
||||
|
||||
bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
|
@ -113,10 +113,10 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
|
|||
unsigned int num_coords;
|
||||
const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
|
||||
unsigned int fd = fdSelect->get_fd (glyph);
|
||||
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, extents_param_t> interp;
|
||||
cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t> interp;
|
||||
const byte_str_t str = (*charStrings)[glyph];
|
||||
interp.env.init (str, *this, fd, coords, num_coords);
|
||||
extents_param_t param;
|
||||
cff2_extents_param_t param;
|
||||
param.init ();
|
||||
if (unlikely (!interp.interpret (param))) return false;
|
||||
|
||||
|
|
|
@ -878,7 +878,7 @@ struct cmap
|
|||
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 @@ struct cmap
|
|||
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 ();
|
||||
|
||||
|
|
|
@ -235,9 +235,9 @@ struct sbix
|
|||
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)
|
||||
|
|
|
@ -50,9 +50,10 @@ HB_OT_TABLE (OT, head)
|
|||
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
|
||||
HB_OT_ACCELERATOR (OT, cmap)
|
||||
#endif
|
||||
HB_OT_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 @@ HB_OT_ACCELERATOR (OT, name)
|
|||
#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. */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -230,32 +230,24 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
|||
|
||||
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
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace OT {
|
|||
template <typename T>
|
||||
struct _hea
|
||||
{
|
||||
bool has_data () const { return version.major; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
|
|
@ -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 @@ struct hmtxvmtx
|
|||
|
||||
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 @@ struct hmtxvmtx
|
|||
|
||||
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 @@ struct hmtxvmtx
|
|||
{
|
||||
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 @@ struct hmtxvmtx
|
|||
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 hmtxvmtx
|
|||
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 {};
|
||||
|
|
|
@ -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 BaseCoordFormat3
|
|||
|
||||
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 @@ struct BaseCoord
|
|||
|
||||
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 BaseCoord
|
|||
|
||||
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 FeatMinMaxRecord
|
|||
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 BaseValues
|
|||
|
||||
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 @@ struct BaseScript
|
|||
{
|
||||
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 BaseScript
|
|||
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 BaseScriptRecord
|
|||
|
||||
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 BaseScriptList
|
|||
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 @@ struct Axis
|
|||
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 @@ struct BASE
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -733,7 +733,7 @@ struct PairPosFormat1
|
|||
+ 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
|
||||
;
|
||||
|
|
|
@ -248,7 +248,7 @@ struct SingleSubst
|
|||
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 _) {
|
||||
|
|
|
@ -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 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
|
|||
*
|
||||
* 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 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
|
|||
*
|
||||
* 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 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
|
|||
* @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 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
|
|||
* @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 @@ hb_ot_layout_collect_features (hb_face_t *face,
|
|||
* 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 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
|
|||
* 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 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face,
|
|||
* 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 @@ typedef enum {
|
|||
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;
|
||||
|
||||
|
||||
|
|
|
@ -168,6 +168,17 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
|
|||
return start;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
}
|
||||
|
||||
|
||||
/* unicode_props */
|
||||
|
||||
|
@ -551,6 +562,17 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
|
|||
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
_hb_glyph_info_clear_substituted (&info[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Allocation / deallocation. */
|
||||
|
||||
|
|
|
@ -154,8 +154,8 @@ struct hb_ot_map_t
|
|||
|
||||
HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
|
||||
template <typename Proxy>
|
||||
HB_INTERNAL inline void apply (const Proxy &proxy,
|
||||
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void apply (const Proxy &proxy,
|
||||
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
|
||||
|
|
|
@ -453,14 +453,14 @@ struct MathGlyphPartRecord
|
|||
}
|
||||
|
||||
void extract (hb_ot_math_glyph_part_t &out,
|
||||
int scale,
|
||||
int64_t mult,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
out.glyph = glyph;
|
||||
|
||||
out.start_connector_length = font->em_scale (startConnectorLength, scale);
|
||||
out.end_connector_length = font->em_scale (endConnectorLength, scale);
|
||||
out.full_advance = font->em_scale (fullAdvance, scale);
|
||||
out.start_connector_length = font->em_mult (startConnectorLength, mult);
|
||||
out.end_connector_length = font->em_mult (endConnectorLength, mult);
|
||||
out.full_advance = font->em_mult (fullAdvance, mult);
|
||||
|
||||
static_assert ((unsigned int) HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER ==
|
||||
(unsigned int) PartFlags::Extender, "");
|
||||
|
@ -508,11 +508,11 @@ struct MathGlyphAssembly
|
|||
{
|
||||
if (parts_count)
|
||||
{
|
||||
int scale = font->dir_scale (direction);
|
||||
int64_t mult = font->dir_mult (direction);
|
||||
hb_array_t<const MathGlyphPartRecord> arr = partRecords.sub_array (start_offset, parts_count);
|
||||
unsigned int count = arr.length;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
arr[i].extract (parts[i], scale, font);
|
||||
arr[i].extract (parts[i], mult, font);
|
||||
}
|
||||
|
||||
if (italics_correction)
|
||||
|
@ -553,13 +553,13 @@ struct MathGlyphConstruction
|
|||
{
|
||||
if (variants_count)
|
||||
{
|
||||
int scale = font->dir_scale (direction);
|
||||
int64_t mult = font->dir_mult (direction);
|
||||
hb_array_t<const MathGlyphVariantRecord> arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count);
|
||||
unsigned int count = arr.length;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
variants[i].glyph = arr[i].variantGlyph;
|
||||
variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
|
||||
variants[i].advance = font->em_mult (arr[i].advanceMeasurement, mult);
|
||||
}
|
||||
}
|
||||
return mathGlyphVariantRecord.len;
|
||||
|
|
|
@ -158,7 +158,7 @@ typedef enum { /*< flags >*/
|
|||
* 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
|
||||
*
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -59,6 +59,10 @@ struct OS2V1Tail
|
|||
|
||||
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 @@ struct OS2
|
|||
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 @@ struct OS2
|
|||
}
|
||||
|
||||
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 @@ struct OS2
|
|||
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); }
|
||||
|
||||
|
|
|
@ -178,6 +178,8 @@ struct post
|
|||
return false;
|
||||
}
|
||||
|
||||
hb_blob_ptr_t<post> table;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int get_glyph_count () const
|
||||
|
@ -237,7 +239,6 @@ struct post
|
|||
}
|
||||
|
||||
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 @@ struct post
|
|||
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);
|
||||
|
|
|
@ -395,13 +395,13 @@ static const int indic_syllable_machine_en_main = 39;
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_indic (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act;
|
||||
int cs;
|
||||
|
@ -569,4 +569,6 @@ _again:
|
|||
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
|
||||
|
|
|
@ -96,13 +96,13 @@ main := |*
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_indic (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act;
|
||||
int cs;
|
||||
|
@ -121,4 +121,6 @@ find_syllables (hb_buffer_t *buffer)
|
|||
}%%
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
|
||||
|
|
|
@ -144,49 +144,45 @@ indic_features[] =
|
|||
* Must be in the same order as the indic_features array.
|
||||
*/
|
||||
enum {
|
||||
_NUKT,
|
||||
_AKHN,
|
||||
RPHF,
|
||||
_RKRF,
|
||||
PREF,
|
||||
BLWF,
|
||||
ABVF,
|
||||
HALF,
|
||||
PSTF,
|
||||
_VATU,
|
||||
_CJCT,
|
||||
_INDIC_NUKT,
|
||||
_INDIC_AKHN,
|
||||
INDIC_RPHF,
|
||||
_INDIC_RKRF,
|
||||
INDIC_PREF,
|
||||
INDIC_BLWF,
|
||||
INDIC_ABVF,
|
||||
INDIC_HALF,
|
||||
INDIC_PSTF,
|
||||
_INDIC_VATU,
|
||||
_INDIC_CJCT,
|
||||
|
||||
INIT,
|
||||
_PRES,
|
||||
_ABVS,
|
||||
_BLWS,
|
||||
_PSTS,
|
||||
_HALN,
|
||||
INDIC_INIT,
|
||||
_INDIC_PRES,
|
||||
_INDIC_ABVS,
|
||||
_INDIC_BLWS,
|
||||
_INDIC_PSTS,
|
||||
_INDIC_HALN,
|
||||
|
||||
_DIST,
|
||||
_ABVM,
|
||||
_BLWM,
|
||||
_INDIC_DIST,
|
||||
_INDIC_ABVM,
|
||||
_INDIC_BLWM,
|
||||
|
||||
INDIC_NUM_FEATURES,
|
||||
INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
|
||||
INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
|
||||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
setup_syllables_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
final_reordering_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_indic (hb_ot_shape_planner_t *plan)
|
||||
|
@ -194,7 +190,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
|||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
map->add_gsub_pause (setup_syllables_indic);
|
||||
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
|
@ -203,14 +199,14 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
|||
|
||||
|
||||
unsigned int i = 0;
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
map->add_gsub_pause (initial_reordering_indic);
|
||||
|
||||
for (; i < INDIC_BASIC_FEATURES; i++) {
|
||||
map->add_feature (indic_features[i]);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
|
||||
map->add_gsub_pause (final_reordering);
|
||||
map->add_gsub_pause (final_reordering_indic);
|
||||
|
||||
for (; i < INDIC_NUM_FEATURES; i++)
|
||||
map->add_feature (indic_features[i]);
|
||||
|
@ -218,7 +214,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
|||
map->enable_feature (HB_TAG('c','a','l','t'));
|
||||
map->enable_feature (HB_TAG('c','l','i','g'));
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -228,32 +224,6 @@ override_features_indic (hb_ot_shape_planner_t *plan)
|
|||
}
|
||||
|
||||
|
||||
struct would_substitute_feature_t
|
||||
{
|
||||
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
|
||||
{
|
||||
zero_context = zero_context_;
|
||||
map->get_stage_lookups (0/*GSUB*/,
|
||||
map->get_feature_stage (0/*GSUB*/, feature_tag),
|
||||
&lookups, &count);
|
||||
}
|
||||
|
||||
bool would_substitute (const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_count,
|
||||
hb_face_t *face) const
|
||||
{
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const hb_ot_map_t::lookup_map_t *lookups;
|
||||
unsigned int count;
|
||||
bool zero_context;
|
||||
};
|
||||
|
||||
struct indic_shape_plan_t
|
||||
{
|
||||
bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
|
||||
|
@ -285,10 +255,10 @@ struct indic_shape_plan_t
|
|||
#endif
|
||||
mutable hb_atomic_int_t virama_glyph;
|
||||
|
||||
would_substitute_feature_t rphf;
|
||||
would_substitute_feature_t pref;
|
||||
would_substitute_feature_t blwf;
|
||||
would_substitute_feature_t pstf;
|
||||
hb_indic_would_substitute_feature_t rphf;
|
||||
hb_indic_would_substitute_feature_t pref;
|
||||
hb_indic_would_substitute_feature_t blwf;
|
||||
hb_indic_would_substitute_feature_t pstf;
|
||||
|
||||
hb_mask_t mask_array[INDIC_NUM_FEATURES];
|
||||
};
|
||||
|
@ -371,13 +341,13 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
|
|||
}
|
||||
|
||||
|
||||
enum syllable_type_t {
|
||||
consonant_syllable,
|
||||
vowel_syllable,
|
||||
standalone_cluster,
|
||||
symbol_cluster,
|
||||
broken_cluster,
|
||||
non_indic_cluster,
|
||||
enum indic_syllable_type_t {
|
||||
indic_consonant_syllable,
|
||||
indic_vowel_syllable,
|
||||
indic_standalone_cluster,
|
||||
indic_symbol_cluster,
|
||||
indic_broken_cluster,
|
||||
indic_non_indic_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-indic-machine.hh"
|
||||
|
@ -401,11 +371,11 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
find_syllables_indic (buffer);
|
||||
foreach_syllable (buffer, start, end)
|
||||
buffer->unsafe_to_break (start, end);
|
||||
}
|
||||
|
@ -422,9 +392,9 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
|||
|
||||
|
||||
static void
|
||||
update_consonant_positions (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
||||
|
||||
|
@ -497,7 +467,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* and has more than one consonant, Ra is excluded from candidates for
|
||||
* base consonants. */
|
||||
unsigned int limit = start;
|
||||
if (indic_plan->mask_array[RPHF] &&
|
||||
if (indic_plan->mask_array[INDIC_RPHF] &&
|
||||
start + 3 <= end &&
|
||||
(
|
||||
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
|
||||
|
@ -833,13 +803,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
/* Reph */
|
||||
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
|
||||
info[i].mask |= indic_plan->mask_array[RPHF];
|
||||
info[i].mask |= indic_plan->mask_array[INDIC_RPHF];
|
||||
|
||||
/* Pre-base */
|
||||
mask = indic_plan->mask_array[HALF];
|
||||
mask = indic_plan->mask_array[INDIC_HALF];
|
||||
if (!indic_plan->is_old_spec &&
|
||||
indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
|
||||
mask |= indic_plan->mask_array[BLWF];
|
||||
mask |= indic_plan->mask_array[INDIC_BLWF];
|
||||
for (unsigned int i = start; i < base; i++)
|
||||
info[i].mask |= mask;
|
||||
/* Base */
|
||||
|
@ -847,7 +817,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (base < end)
|
||||
info[base].mask |= mask;
|
||||
/* Post-base */
|
||||
mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
|
||||
mask = indic_plan->mask_array[INDIC_BLWF] |
|
||||
indic_plan->mask_array[INDIC_ABVF] |
|
||||
indic_plan->mask_array[INDIC_PSTF];
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
}
|
||||
|
@ -879,13 +851,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
(i + 2 == base ||
|
||||
info[i+2].indic_category() != OT_ZWJ))
|
||||
{
|
||||
info[i ].mask |= indic_plan->mask_array[BLWF];
|
||||
info[i+1].mask |= indic_plan->mask_array[BLWF];
|
||||
info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
|
||||
info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int pref_len = 2;
|
||||
if (indic_plan->mask_array[PREF] && base + pref_len < end)
|
||||
if (indic_plan->mask_array[INDIC_PREF] && base + pref_len < end)
|
||||
{
|
||||
/* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
|
||||
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
|
||||
|
@ -895,7 +867,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
|
||||
{
|
||||
for (unsigned int j = 0; j < pref_len; j++)
|
||||
info[i++].mask |= indic_plan->mask_array[PREF];
|
||||
info[i++].mask |= indic_plan->mask_array[INDIC_PREF];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -916,7 +888,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
/* A ZWNJ disables HALF. */
|
||||
if (non_joiner)
|
||||
info[j].mask &= ~indic_plan->mask_array[HALF];
|
||||
info[j].mask &= ~indic_plan->mask_array[INDIC_HALF];
|
||||
|
||||
} while (j > start && !is_consonant (info[j]));
|
||||
}
|
||||
|
@ -945,34 +917,34 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
static void
|
||||
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
switch (syllable_type)
|
||||
{
|
||||
case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
|
||||
case consonant_syllable:
|
||||
case indic_vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
|
||||
case indic_consonant_syllable:
|
||||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
break;
|
||||
|
||||
case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
|
||||
case standalone_cluster:
|
||||
case indic_broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
|
||||
case indic_standalone_cluster:
|
||||
initial_reordering_standalone_cluster (plan, face, buffer, start, end);
|
||||
break;
|
||||
|
||||
case symbol_cluster:
|
||||
case non_indic_cluster:
|
||||
case indic_symbol_cluster:
|
||||
case indic_non_indic_cluster:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
|
||||
return;
|
||||
|
@ -983,7 +955,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||
if ((info[i].syllable() & 0x0F) == indic_broken_cluster)
|
||||
{
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
|
@ -1008,8 +980,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
while (buffer->idx < buffer->len && buffer->successful)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
|
@ -1033,21 +1005,21 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
update_consonant_positions (plan, font, buffer);
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
update_consonant_positions_indic (plan, font, buffer);
|
||||
insert_dotted_circles_indic (plan, font, buffer);
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
initial_reordering_syllable (plan, font->face, buffer, start, end);
|
||||
initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
|
||||
}
|
||||
|
||||
static void
|
||||
final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
@ -1083,7 +1055,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* syllable.
|
||||
*/
|
||||
|
||||
bool try_pref = !!indic_plan->mask_array[PREF];
|
||||
bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
|
||||
|
||||
/* Find base again */
|
||||
unsigned int base;
|
||||
|
@ -1093,7 +1065,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (try_pref && base + 1 < end)
|
||||
{
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
|
||||
if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
|
||||
{
|
||||
if (!(_hb_glyph_info_substituted (&info[i]) &&
|
||||
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
|
||||
|
@ -1415,7 +1387,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
|
||||
{
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
|
||||
if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
|
||||
{
|
||||
/* 1. Only reorder a glyph produced by substitution during application
|
||||
* of the <pref> feature. (Note that a font may shape a Ra consonant with
|
||||
|
@ -1478,7 +1450,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (!start ||
|
||||
!(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
|
||||
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
|
||||
info[start].mask |= indic_plan->mask_array[INIT];
|
||||
info[start].mask |= indic_plan->mask_array[INDIC_INIT];
|
||||
else
|
||||
buffer->unsafe_to_break (start - 1, start + 1);
|
||||
}
|
||||
|
@ -1508,33 +1480,21 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
final_reordering_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
if (unlikely (!count)) return;
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
final_reordering_syllable (plan, buffer, start, end);
|
||||
final_reordering_syllable_indic (plan, buffer, start, end);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
preprocess_text_indic (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
|
|
|
@ -64,7 +64,14 @@ enum indic_category_t {
|
|||
OT_Ra = 16,
|
||||
OT_CM = 17, /* Consonant-Medial. */
|
||||
OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
|
||||
OT_CS = 19
|
||||
OT_CS = 19,
|
||||
|
||||
/* The following are used by Khmer & Myanmar shapers. Defined
|
||||
* here for them to share. */
|
||||
OT_VAbv = 26,
|
||||
OT_VBlw = 27,
|
||||
OT_VPre = 28,
|
||||
OT_VPst = 29,
|
||||
};
|
||||
|
||||
#define MEDIAL_FLAGS (FLAG (OT_CM))
|
||||
|
@ -398,5 +405,31 @@ set_indic_properties (hb_glyph_info_t &info)
|
|||
info.indic_position() = pos;
|
||||
}
|
||||
|
||||
struct hb_indic_would_substitute_feature_t
|
||||
{
|
||||
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
|
||||
{
|
||||
zero_context = zero_context_;
|
||||
map->get_stage_lookups (0/*GSUB*/,
|
||||
map->get_feature_stage (0/*GSUB*/, feature_tag),
|
||||
&lookups, &count);
|
||||
}
|
||||
|
||||
bool would_substitute (const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_count,
|
||||
hb_face_t *face) const
|
||||
{
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const hb_ot_map_t::lookup_map_t *lookups;
|
||||
unsigned int count;
|
||||
bool zero_context;
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */
|
||||
|
|
|
@ -226,13 +226,13 @@ static const int khmer_syllable_machine_en_main = 20;
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_khmer (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
|
||||
int cs;
|
||||
|
@ -367,4 +367,6 @@ _again:
|
|||
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
|
||||
|
|
|
@ -83,13 +83,13 @@ main := |*
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_khmer (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
|
||||
int cs;
|
||||
|
@ -108,4 +108,6 @@ find_syllables (hb_buffer_t *buffer)
|
|||
}%%
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
|
||||
|
|
|
@ -69,37 +69,33 @@ khmer_features[] =
|
|||
* Must be in the same order as the khmer_features array.
|
||||
*/
|
||||
enum {
|
||||
PREF,
|
||||
BLWF,
|
||||
ABVF,
|
||||
PSTF,
|
||||
CFAR,
|
||||
KHMER_PREF,
|
||||
KHMER_BLWF,
|
||||
KHMER_ABVF,
|
||||
KHMER_PSTF,
|
||||
KHMER_CFAR,
|
||||
|
||||
_PRES,
|
||||
_ABVS,
|
||||
_BLWS,
|
||||
_PSTS,
|
||||
_KHMER_PRES,
|
||||
_KHMER_ABVS,
|
||||
_KHMER_BLWS,
|
||||
_KHMER_PSTS,
|
||||
|
||||
_DIST,
|
||||
_ABVM,
|
||||
_BLWM,
|
||||
_KHMER_DIST,
|
||||
_KHMER_ABVM,
|
||||
_KHMER_BLWM,
|
||||
|
||||
KHMER_NUM_FEATURES,
|
||||
KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
|
||||
KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
|
||||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
reorder_khmer (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_khmer (hb_ot_shape_planner_t *plan)
|
||||
|
@ -107,8 +103,8 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
|
|||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
map->add_gsub_pause (reorder);
|
||||
map->add_gsub_pause (setup_syllables_khmer);
|
||||
map->add_gsub_pause (reorder_khmer);
|
||||
|
||||
/* Testing suggests that Uniscribe does NOT pause between basic
|
||||
* features. Test with KhmerUI.ttf and the following three
|
||||
|
@ -127,7 +123,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
|
|||
for (; i < KHMER_BASIC_FEATURES; i++)
|
||||
map->add_feature (khmer_features[i]);
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
|
||||
for (; i < KHMER_NUM_FEATURES; i++)
|
||||
map->add_feature (khmer_features[i]);
|
||||
|
@ -153,32 +149,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
|
|||
}
|
||||
|
||||
|
||||
struct would_substitute_feature_t
|
||||
{
|
||||
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
|
||||
{
|
||||
zero_context = zero_context_;
|
||||
map->get_stage_lookups (0/*GSUB*/,
|
||||
map->get_feature_stage (0/*GSUB*/, feature_tag),
|
||||
&lookups, &count);
|
||||
}
|
||||
|
||||
bool would_substitute (const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_count,
|
||||
hb_face_t *face) const
|
||||
{
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const hb_ot_map_t::lookup_map_t *lookups;
|
||||
unsigned int count;
|
||||
bool zero_context;
|
||||
};
|
||||
|
||||
struct khmer_shape_plan_t
|
||||
{
|
||||
bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
|
||||
|
@ -202,7 +172,7 @@ struct khmer_shape_plan_t
|
|||
|
||||
mutable hb_codepoint_t virama_glyph;
|
||||
|
||||
would_substitute_feature_t pref;
|
||||
hb_indic_would_substitute_feature_t pref;
|
||||
|
||||
hb_mask_t mask_array[KHMER_NUM_FEATURES];
|
||||
};
|
||||
|
@ -232,10 +202,10 @@ data_destroy_khmer (void *data)
|
|||
}
|
||||
|
||||
|
||||
enum syllable_type_t {
|
||||
consonant_syllable,
|
||||
broken_cluster,
|
||||
non_khmer_cluster,
|
||||
enum khmer_syllable_type_t {
|
||||
khmer_consonant_syllable,
|
||||
khmer_broken_cluster,
|
||||
khmer_non_khmer_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-khmer-machine.hh"
|
||||
|
@ -257,11 +227,11 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
find_syllables_khmer (buffer);
|
||||
foreach_syllable (buffer, start, end)
|
||||
buffer->unsafe_to_break (start, end);
|
||||
}
|
||||
|
@ -282,7 +252,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
/* Setup masks. */
|
||||
{
|
||||
/* Post-base */
|
||||
hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
|
||||
hb_mask_t mask = khmer_plan->mask_array[KHMER_BLWF] |
|
||||
khmer_plan->mask_array[KHMER_ABVF] |
|
||||
khmer_plan->mask_array[KHMER_PSTF];
|
||||
for (unsigned int i = start + 1; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
}
|
||||
|
@ -309,7 +281,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (info[i + 1].khmer_category() == OT_Ra)
|
||||
{
|
||||
for (unsigned int j = 0; j < 2; j++)
|
||||
info[i + j].mask |= khmer_plan->mask_array[PREF];
|
||||
info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
|
||||
|
||||
/* Move the Coeng,Ro sequence to the start. */
|
||||
buffer->merge_clusters (start, i + 2);
|
||||
|
@ -325,9 +297,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* U+1784,U+17D2,U+179A,U+17D2,U+1782
|
||||
* U+1784,U+17D2,U+1782,U+17D2,U+179A
|
||||
*/
|
||||
if (khmer_plan->mask_array[CFAR])
|
||||
if (khmer_plan->mask_array[KHMER_CFAR])
|
||||
for (unsigned int j = i + 2; j < end; j++)
|
||||
info[j].mask |= khmer_plan->mask_array[CFAR];
|
||||
info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
|
||||
|
||||
num_coengs = 2; /* Done. */
|
||||
}
|
||||
|
@ -346,28 +318,28 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
static void
|
||||
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
switch (syllable_type)
|
||||
{
|
||||
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
case consonant_syllable:
|
||||
case khmer_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
case khmer_consonant_syllable:
|
||||
reorder_consonant_syllable (plan, face, buffer, start, end);
|
||||
break;
|
||||
|
||||
case non_khmer_cluster:
|
||||
case khmer_non_khmer_cluster:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
|
||||
return;
|
||||
|
@ -378,7 +350,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||
if ((info[i].syllable() & 0x0F) == khmer_broken_cluster)
|
||||
{
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
|
@ -403,8 +375,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
while (buffer->idx < buffer->len && buffer->successful)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
|
@ -428,29 +400,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
reorder_khmer (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
insert_dotted_circles_khmer (plan, font, buffer);
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
initial_reordering_syllable (plan, font->face, buffer, start, end);
|
||||
reorder_syllable_khmer (plan, font->face, buffer, start, end);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
decompose_khmer (const hb_ot_shape_normalize_context_t *c,
|
||||
|
|
|
@ -43,11 +43,10 @@ enum khmer_category_t
|
|||
OT_Robatic = 20,
|
||||
OT_Xgroup = 21,
|
||||
OT_Ygroup = 22,
|
||||
|
||||
OT_VAbv = 26,
|
||||
OT_VBlw = 27,
|
||||
OT_VPre = 28,
|
||||
OT_VPst = 29,
|
||||
//OT_VAbv = 26,
|
||||
//OT_VBlw = 27,
|
||||
//OT_VPre = 28,
|
||||
//OT_VPst = 29,
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
@ -100,10 +99,10 @@ set_khmer_properties (hb_glyph_info_t &info)
|
|||
if (cat == (khmer_category_t) OT_M)
|
||||
switch ((int) pos)
|
||||
{
|
||||
case POS_PRE_C: cat = OT_VPre; break;
|
||||
case POS_BELOW_C: cat = OT_VBlw; break;
|
||||
case POS_ABOVE_C: cat = OT_VAbv; break;
|
||||
case POS_POST_C: cat = OT_VPst; break;
|
||||
case POS_PRE_C: cat = (khmer_category_t) OT_VPre; break;
|
||||
case POS_BELOW_C: cat = (khmer_category_t) OT_VBlw; break;
|
||||
case POS_ABOVE_C: cat = (khmer_category_t) OT_VAbv; break;
|
||||
case POS_POST_C: cat = (khmer_category_t) OT_VPst; break;
|
||||
default: assert (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -304,13 +304,13 @@ static const int myanmar_syllable_machine_en_main = 0;
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_myanmar (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
|
||||
int cs;
|
||||
|
|
|
@ -97,13 +97,13 @@ main := |*
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_myanmar (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
|
||||
int cs;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
static const hb_tag_t
|
||||
basic_features[] =
|
||||
myanmar_basic_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
|
@ -48,7 +48,7 @@ basic_features[] =
|
|||
HB_TAG('p','s','t','f'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
other_features[] =
|
||||
myanmar_other_features[] =
|
||||
{
|
||||
/*
|
||||
* Other features.
|
||||
|
@ -60,7 +60,7 @@ other_features[] =
|
|||
HB_TAG('p','s','t','s'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
positioning_features[] =
|
||||
myanmar_positioning_features[] =
|
||||
{
|
||||
/*
|
||||
* Positioning features.
|
||||
|
@ -80,15 +80,11 @@ positioning_features[] =
|
|||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan,
|
||||
reorder_myanmar (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
@ -98,7 +94,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
|
|||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
map->add_gsub_pause (setup_syllables_myanmar);
|
||||
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
|
@ -106,21 +102,21 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
|
|||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
|
||||
map->add_gsub_pause (reorder);
|
||||
map->add_gsub_pause (reorder_myanmar);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
|
||||
{
|
||||
map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
|
||||
map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->enable_feature (other_features[i], F_MANUAL_ZWJ);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
|
||||
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
|
||||
map->enable_feature (positioning_features[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_positioning_features); i++)
|
||||
map->enable_feature (myanmar_positioning_features[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -130,11 +126,11 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
|
|||
}
|
||||
|
||||
|
||||
enum syllable_type_t {
|
||||
consonant_syllable,
|
||||
punctuation_cluster,
|
||||
broken_cluster,
|
||||
non_myanmar_cluster,
|
||||
enum myanmar_syllable_type_t {
|
||||
myanmar_consonant_syllable,
|
||||
myanmar_punctuation_cluster,
|
||||
myanmar_broken_cluster,
|
||||
myanmar_non_myanmar_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
|
@ -158,11 +154,11 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
find_syllables_myanmar (buffer);
|
||||
foreach_syllable (buffer, start, end)
|
||||
buffer->unsafe_to_break (start, end);
|
||||
}
|
||||
|
@ -278,29 +274,29 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
|
|||
}
|
||||
|
||||
static void
|
||||
initial_reordering_syllable (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_face_t *face HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_face_t *face HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
switch (syllable_type) {
|
||||
|
||||
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
case consonant_syllable:
|
||||
case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
case myanmar_consonant_syllable:
|
||||
initial_reordering_consonant_syllable (buffer, start, end);
|
||||
break;
|
||||
|
||||
case punctuation_cluster:
|
||||
case non_myanmar_cluster:
|
||||
case myanmar_punctuation_cluster:
|
||||
case myanmar_non_myanmar_cluster:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
|
||||
return;
|
||||
|
@ -311,7 +307,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||
if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster)
|
||||
{
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
|
@ -336,8 +332,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
while (buffer->idx < buffer->len && buffer->successful)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
|
@ -355,30 +351,19 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
reorder_myanmar (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
insert_dotted_circles_myanmar (plan, font, buffer);
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
initial_reordering_syllable (plan, font->face, buffer, start, end);
|
||||
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||
{
|
||||
|
|
|
@ -49,10 +49,10 @@ enum myanmar_category_t {
|
|||
OT_MW = 23, /* Various consonant medial types */
|
||||
OT_MY = 24, /* Various consonant medial types */
|
||||
OT_PT = 25, /* Pwo and other tones */
|
||||
OT_VAbv = 26,
|
||||
OT_VBlw = 27,
|
||||
OT_VPre = 28,
|
||||
OT_VPst = 29,
|
||||
//OT_VAbv = 26,
|
||||
//OT_VBlw = 27,
|
||||
//OT_VPre = 28,
|
||||
//OT_VPst = 29,
|
||||
OT_VS = 30, /* Variation selectors */
|
||||
OT_P = 31, /* Punctuation */
|
||||
OT_D = 32, /* Digits except zero */
|
||||
|
@ -155,11 +155,11 @@ set_myanmar_properties (hb_glyph_info_t &info)
|
|||
{
|
||||
switch ((int) pos)
|
||||
{
|
||||
case POS_PRE_C: cat = OT_VPre;
|
||||
case POS_PRE_C: cat = (myanmar_category_t) OT_VPre;
|
||||
pos = POS_PRE_M; break;
|
||||
case POS_ABOVE_C: cat = OT_VAbv; break;
|
||||
case POS_BELOW_C: cat = OT_VBlw; break;
|
||||
case POS_POST_C: cat = OT_VPst; break;
|
||||
case POS_ABOVE_C: cat = (myanmar_category_t) OT_VAbv; break;
|
||||
case POS_BELOW_C: cat = (myanmar_category_t) OT_VBlw; break;
|
||||
case POS_POST_C: cat = (myanmar_category_t) OT_VPst; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -380,13 +380,13 @@ static const int use_syllable_machine_en_main = 5;
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_use (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act;
|
||||
int cs;
|
||||
|
|
|
@ -165,13 +165,13 @@ main := |*
|
|||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
|
||||
for (unsigned int i = ts; i < te; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
find_syllables_use (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts, te, act;
|
||||
int cs;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
*/
|
||||
|
||||
static const hb_tag_t
|
||||
basic_features[] =
|
||||
use_basic_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
|
@ -59,28 +59,23 @@ basic_features[] =
|
|||
HB_TAG('c','j','c','t'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
arabic_features[] =
|
||||
use_topographical_features[] =
|
||||
{
|
||||
HB_TAG('i','s','o','l'),
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
/* The spec doesn't specify these but we apply anyway, since our Arabic shaper
|
||||
* does. These are only used in Syriac spec. */
|
||||
HB_TAG('m','e','d','2'),
|
||||
HB_TAG('f','i','n','2'),
|
||||
HB_TAG('f','i','n','3'),
|
||||
};
|
||||
/* Same order as arabic_features. Don't need Syriac stuff.*/
|
||||
/* Same order as use_topographical_features. */
|
||||
enum joining_form_t {
|
||||
ISOL,
|
||||
INIT,
|
||||
MEDI,
|
||||
FINA,
|
||||
_NONE
|
||||
USE_ISOL,
|
||||
USE_INIT,
|
||||
USE_MEDI,
|
||||
USE_FINA,
|
||||
_USE_NONE
|
||||
};
|
||||
static const hb_tag_t
|
||||
other_features[] =
|
||||
use_other_features[] =
|
||||
{
|
||||
/*
|
||||
* Other features.
|
||||
|
@ -94,7 +89,7 @@ other_features[] =
|
|||
HB_TAG('p','s','t','s'),
|
||||
};
|
||||
static const hb_tag_t
|
||||
positioning_features[] =
|
||||
use_positioning_features[] =
|
||||
{
|
||||
/*
|
||||
* Positioning features.
|
||||
|
@ -106,29 +101,21 @@ positioning_features[] =
|
|||
};
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
setup_syllables_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
record_rphf_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_substitution_flags (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
record_rphf (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
record_pref (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan,
|
||||
record_pref_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
reorder_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_use (hb_ot_shape_planner_t *plan)
|
||||
|
@ -136,7 +123,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
|
|||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
map->add_gsub_pause (setup_syllables_use);
|
||||
|
||||
/* "Default glyph pre-processing group" */
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
|
@ -145,32 +132,32 @@ collect_features_use (hb_ot_shape_planner_t *plan)
|
|||
map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
|
||||
|
||||
/* "Reordering group" */
|
||||
map->add_gsub_pause (clear_substitution_flags);
|
||||
map->add_gsub_pause (_hb_clear_substitution_flags);
|
||||
map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (record_rphf);
|
||||
map->add_gsub_pause (clear_substitution_flags);
|
||||
map->add_gsub_pause (record_rphf_use);
|
||||
map->add_gsub_pause (_hb_clear_substitution_flags);
|
||||
map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (record_pref);
|
||||
map->add_gsub_pause (record_pref_use);
|
||||
|
||||
/* "Orthographic unit shaping group" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (use_basic_features); i++)
|
||||
map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ);
|
||||
|
||||
map->add_gsub_pause (reorder);
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
map->add_gsub_pause (reorder_use);
|
||||
map->add_gsub_pause (_hb_clear_syllables);
|
||||
|
||||
/* "Topographical features" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
|
||||
map->add_feature (arabic_features[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
|
||||
map->add_feature (use_topographical_features[i]);
|
||||
map->add_gsub_pause (nullptr);
|
||||
|
||||
/* "Standard typographic presentation" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->enable_feature (other_features[i], F_MANUAL_ZWJ);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (use_other_features); i++)
|
||||
map->enable_feature (use_other_features[i], F_MANUAL_ZWJ);
|
||||
|
||||
/* "Positional feature application" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
|
||||
map->enable_feature (positioning_features[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (use_positioning_features); i++)
|
||||
map->enable_feature (use_positioning_features[i]);
|
||||
}
|
||||
|
||||
struct use_shape_plan_t
|
||||
|
@ -247,16 +234,16 @@ data_destroy_use (void *data)
|
|||
free (data);
|
||||
}
|
||||
|
||||
enum syllable_type_t {
|
||||
independent_cluster,
|
||||
virama_terminated_cluster,
|
||||
sakot_terminated_cluster,
|
||||
standard_cluster,
|
||||
number_joiner_terminated_cluster,
|
||||
numeral_cluster,
|
||||
symbol_cluster,
|
||||
broken_cluster,
|
||||
non_cluster,
|
||||
enum use_syllable_type_t {
|
||||
use_independent_cluster,
|
||||
use_virama_terminated_cluster,
|
||||
use_sakot_terminated_cluster,
|
||||
use_standard_cluster,
|
||||
use_number_joiner_terminated_cluster,
|
||||
use_numeral_cluster,
|
||||
use_symbol_cluster,
|
||||
use_broken_cluster,
|
||||
use_non_cluster,
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-use-machine.hh"
|
||||
|
@ -313,11 +300,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
|
|||
if (use_plan->arabic_plan)
|
||||
return;
|
||||
|
||||
static_assert ((INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4), "");
|
||||
static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), "");
|
||||
hb_mask_t masks[4], all_masks = 0;
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
masks[i] = plan->map.get_1_mask (arabic_features[i]);
|
||||
masks[i] = plan->map.get_1_mask (use_topographical_features[i]);
|
||||
if (masks[i] == plan->map.get_global_mask ())
|
||||
masks[i] = 0;
|
||||
all_masks |= masks[i];
|
||||
|
@ -327,39 +314,39 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
|
|||
hb_mask_t other_masks = ~all_masks;
|
||||
|
||||
unsigned int last_start = 0;
|
||||
joining_form_t last_form = _NONE;
|
||||
joining_form_t last_form = _USE_NONE;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
foreach_syllable (buffer, start, end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
|
||||
use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
|
||||
switch (syllable_type)
|
||||
{
|
||||
case independent_cluster:
|
||||
case symbol_cluster:
|
||||
case non_cluster:
|
||||
case use_independent_cluster:
|
||||
case use_symbol_cluster:
|
||||
case use_non_cluster:
|
||||
/* These don't join. Nothing to do. */
|
||||
last_form = _NONE;
|
||||
last_form = _USE_NONE;
|
||||
break;
|
||||
|
||||
case virama_terminated_cluster:
|
||||
case sakot_terminated_cluster:
|
||||
case standard_cluster:
|
||||
case number_joiner_terminated_cluster:
|
||||
case numeral_cluster:
|
||||
case broken_cluster:
|
||||
case use_virama_terminated_cluster:
|
||||
case use_sakot_terminated_cluster:
|
||||
case use_standard_cluster:
|
||||
case use_number_joiner_terminated_cluster:
|
||||
case use_numeral_cluster:
|
||||
case use_broken_cluster:
|
||||
|
||||
bool join = last_form == FINA || last_form == ISOL;
|
||||
bool join = last_form == USE_FINA || last_form == USE_ISOL;
|
||||
|
||||
if (join)
|
||||
{
|
||||
/* Fixup previous syllable's form. */
|
||||
last_form = last_form == FINA ? MEDI : INIT;
|
||||
last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT;
|
||||
for (unsigned int i = last_start; i < start; i++)
|
||||
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
|
||||
}
|
||||
|
||||
/* Form for this syllable. */
|
||||
last_form = join ? FINA : ISOL;
|
||||
last_form = join ? USE_FINA : USE_ISOL;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
|
||||
|
||||
|
@ -371,11 +358,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
static void
|
||||
setup_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
setup_syllables_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
find_syllables (buffer);
|
||||
find_syllables_use (buffer);
|
||||
foreach_syllable (buffer, start, end)
|
||||
buffer->unsafe_to_break (start, end);
|
||||
setup_rphf_mask (plan, buffer);
|
||||
|
@ -383,20 +370,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
static void
|
||||
clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
_hb_glyph_info_clear_substituted (&info[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
record_rphf (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
record_rphf_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
|
||||
|
||||
|
@ -417,9 +393,9 @@ record_rphf (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
static void
|
||||
record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
|
@ -436,22 +412,22 @@ record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static inline bool
|
||||
is_halant (const hb_glyph_info_t &info)
|
||||
is_halant_use (const hb_glyph_info_t &info)
|
||||
{
|
||||
return (info.use_category() == USE_H || info.use_category() == USE_HVM) &&
|
||||
!_hb_glyph_info_ligated (&info);
|
||||
}
|
||||
|
||||
static void
|
||||
reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
||||
reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
||||
{
|
||||
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
use_syllable_type_t syllable_type = (use_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
|
||||
/* Only a few syllable types need reordering. */
|
||||
if (unlikely (!(FLAG_UNSAFE (syllable_type) &
|
||||
(FLAG (virama_terminated_cluster) |
|
||||
FLAG (sakot_terminated_cluster) |
|
||||
FLAG (standard_cluster) |
|
||||
FLAG (broken_cluster) |
|
||||
(FLAG (use_virama_terminated_cluster) |
|
||||
FLAG (use_sakot_terminated_cluster) |
|
||||
FLAG (use_standard_cluster) |
|
||||
FLAG (use_broken_cluster) |
|
||||
0))))
|
||||
return;
|
||||
|
||||
|
@ -482,7 +458,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
|||
for (unsigned int i = start + 1; i < end; i++)
|
||||
{
|
||||
bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) ||
|
||||
is_halant (info[i]);
|
||||
is_halant_use (info[i]);
|
||||
if (is_post_base_glyph || i == end - 1)
|
||||
{
|
||||
/* If we hit a post-base glyph, move before it; otherwise move to the
|
||||
|
@ -506,7 +482,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
|||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
uint32_t flag = FLAG_UNSAFE (info[i].use_category());
|
||||
if (is_halant (info[i]))
|
||||
if (is_halant_use (info[i]))
|
||||
{
|
||||
/* If we hit a halant, move after it; otherwise move to the beginning, and
|
||||
* shift things in between forward. */
|
||||
|
@ -526,9 +502,9 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
|
|||
}
|
||||
|
||||
static inline void
|
||||
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
|
||||
return;
|
||||
|
@ -539,7 +515,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||
if ((info[i].syllable() & 0x0F) == use_broken_cluster)
|
||||
{
|
||||
has_broken_syllables = true;
|
||||
break;
|
||||
|
@ -559,8 +535,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
while (buffer->idx < buffer->len && buffer->successful)
|
||||
{
|
||||
unsigned int syllable = buffer->cur().syllable();
|
||||
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
|
||||
use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F);
|
||||
if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster))
|
||||
{
|
||||
last_syllable = syllable;
|
||||
|
||||
|
@ -584,29 +560,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
reorder_use (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
insert_dotted_circles_use (plan, font, buffer);
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
reorder_syllable (buffer, start, end);
|
||||
reorder_syllable_use (buffer, start, end);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].syllable() = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
preprocess_text_use (const hb_ot_shape_plan_t *plan,
|
||||
|
|
|
@ -68,7 +68,7 @@ hb_ot_var_get_axis_count (hb_face_t *face);
|
|||
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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -85,7 +85,7 @@ struct VORG
|
|||
this->vertYOrigins.len = it.len ();
|
||||
|
||||
+ it
|
||||
| hb_apply ([c] (const VertOriginMetric& _) { c->copy (_);})
|
||||
| hb_apply ([c] (const VertOriginMetric& _) { c->copy (_); })
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -479,7 +479,7 @@ hb_set_next (const hb_set_t *set,
|
|||
* @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 @@ hb_set_next_range (const hb_set_t *set,
|
|||
* @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.
|
||||
*
|
||||
|
|
|
@ -46,16 +46,16 @@ struct hb_shape_plan_key_t
|
|||
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);
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
|
|||
|
||||
unsigned max_glyph =
|
||||
+ hb_iter (all_gids_to_retain)
|
||||
| hb_reduce (hb_max, 0)
|
||||
| hb_reduce (hb_max, 0u)
|
||||
;
|
||||
*num_glyphs = max_glyph + 1;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-unicode.hh"
|
||||
#include "hb-machinery.hh"
|
||||
|
||||
#include "hb-ucd-table.hh"
|
||||
|
@ -235,10 +236,6 @@ void free_static_ucd_funcs ()
|
|||
}
|
||||
#endif
|
||||
|
||||
extern "C" HB_INTERNAL
|
||||
hb_unicode_funcs_t *
|
||||
hb_ucd_get_unicode_funcs ();
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_ucd_get_unicode_funcs ()
|
||||
{
|
||||
|
|
|
@ -126,10 +126,12 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
|
|||
}
|
||||
#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 ()
|
||||
|
|
|
@ -105,9 +105,6 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||
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_INTERNAL bool
|
|||
_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 */
|
||||
|
|
|
@ -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 @@ struct hb_uniscribe_shaper_funcs_t
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#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>
|
||||
|
|
|
@ -143,13 +143,13 @@ struct hb_vector_t
|
|||
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); }
|
||||
|
|
|
@ -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 @@ extern "C" void hb_free_impl(void *ptr);
|
|||
# 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 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
|
|||
/* 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.
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -84,6 +84,8 @@ TEST_PROGS += \
|
|||
test-ot-color \
|
||||
test-ot-ligature-carets \
|
||||
test-ot-name \
|
||||
test-ot-meta \
|
||||
test-ot-metrics \
|
||||
test-ot-tag \
|
||||
test-ot-extents-cff \
|
||||
$(NULL)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -426,9 +426,9 @@ test_hb_ot_color_png (void)
|
|||
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);
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
|
@ -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 ();
|
||||
}
|
Binary file not shown.
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hb-subset.h"
|
||||
|
||||
|
@ -32,6 +33,19 @@ trySubset (hb_face_t *face,
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -5,41 +5,41 @@ from __future__ import print_function, division, absolute_import
|
|||
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 @@ please provide it as the first argument to the tool""")
|
|||
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 @@ if os.environ.get('RUN_VALGRIND', ''):
|
|||
|
||||
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 @@ for file in os.listdir (parent_path):
|
|||
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:
|
||||
|
|
|
@ -33,7 +33,7 @@ def cmd(command):
|
|||
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 @@ def run_dir (parent_path):
|
|||
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 @@ def run_dir (parent_path):
|
|||
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 @@ def run_dir (parent_path):
|
|||
|
||||
|
||||
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)
|
||||
|
|
Binary file not shown.
|
@ -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>]
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue