Merge branch 'master' into cff-subset
This commit is contained in:
commit
b5aa5dbb11
|
@ -27,6 +27,17 @@ jobs:
|
||||||
# Ignoring assembler complains, https://stackoverflow.com/a/39867021
|
# Ignoring assembler complains, https://stackoverflow.com/a/39867021
|
||||||
- run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*'
|
- run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*'
|
||||||
|
|
||||||
|
macos-notest-ios:
|
||||||
|
macos:
|
||||||
|
xcode: "10.0.0"
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run: brew update-reset
|
||||||
|
- run: brew install cmake
|
||||||
|
# not needed to be a framework but we like to test that also
|
||||||
|
- run: cmake -DBUILD_FRAMEWORK=ON -H. -Bbuild -GXcode -DHB_IOS=ON
|
||||||
|
- run: cd build && xcodebuild -sdk iphoneos12.0 -configuration Release build -arch arm64
|
||||||
|
|
||||||
distcheck:
|
distcheck:
|
||||||
docker:
|
docker:
|
||||||
- image: ubuntu:17.10
|
- image: ubuntu:17.10
|
||||||
|
@ -274,6 +285,7 @@ workflows:
|
||||||
# macOS
|
# macOS
|
||||||
- macos-llvm-gcc-4.2
|
- macos-llvm-gcc-4.2
|
||||||
- macos-notest-apple-gcc-i686-4.2
|
- macos-notest-apple-gcc-i686-4.2
|
||||||
|
- macos-notest-ios
|
||||||
|
|
||||||
# both autotools and cmake
|
# both autotools and cmake
|
||||||
- distcheck
|
- distcheck
|
||||||
|
|
137
CMakeLists.txt
137
CMakeLists.txt
|
@ -82,12 +82,21 @@ if (HB_CHECK)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
set (HB_DISABLE_SUBSET OFF)
|
||||||
|
set (HB_DISABLE_TESTS OFF)
|
||||||
|
option(HB_IOS "Apply iOS specific build flags" OFF)
|
||||||
|
if (HB_IOS)
|
||||||
|
# We should fix their issue and enable them
|
||||||
|
set (HB_DISABLE_SUBSET ON)
|
||||||
|
set (HB_DISABLE_TESTS ON)
|
||||||
|
set (HB_HAVE_CORETEXT OFF)
|
||||||
|
endif ()
|
||||||
|
|
||||||
include_directories(AFTER
|
include_directories(AFTER
|
||||||
${PROJECT_SOURCE_DIR}/src
|
${PROJECT_SOURCE_DIR}/src
|
||||||
${PROJECT_BINARY_DIR}/src
|
${PROJECT_BINARY_DIR}/src
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(-DHAVE_OT)
|
|
||||||
add_definitions(-DHAVE_FALLBACK)
|
add_definitions(-DHAVE_FALLBACK)
|
||||||
|
|
||||||
# We need PYTHON_EXECUTABLE to be set for running the tests...
|
# We need PYTHON_EXECUTABLE to be set for running the tests...
|
||||||
|
@ -359,12 +368,32 @@ if (APPLE AND HB_HAVE_CORETEXT)
|
||||||
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
|
list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
|
||||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
|
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
|
||||||
|
|
||||||
find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
|
if (HB_IOS)
|
||||||
if (APPLICATION_SERVICES_FRAMEWORK)
|
find_library(COREFOUNDATION CoreFoundation)
|
||||||
list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
|
if (COREFOUNDATION)
|
||||||
endif (APPLICATION_SERVICES_FRAMEWORK)
|
list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
|
||||||
|
endif ()
|
||||||
|
mark_as_advanced(COREFOUNDATION)
|
||||||
|
|
||||||
mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
|
find_library(CORETEXT CoreText)
|
||||||
|
if (CORETEXT)
|
||||||
|
list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
|
||||||
|
endif ()
|
||||||
|
mark_as_advanced(CORETEXT)
|
||||||
|
|
||||||
|
find_library(COREGRAPHICS CoreGraphics)
|
||||||
|
if (COREGRAPHICS)
|
||||||
|
list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
|
||||||
|
endif ()
|
||||||
|
mark_as_advanced(COREGRAPHICS)
|
||||||
|
else ()
|
||||||
|
find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
|
||||||
|
if (APPLICATION_SERVICES_FRAMEWORK)
|
||||||
|
list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (WIN32 AND HB_HAVE_UNISCRIBE)
|
if (WIN32 AND HB_HAVE_UNISCRIBE)
|
||||||
|
@ -527,12 +556,14 @@ add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_heade
|
||||||
target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
|
target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
|
||||||
|
|
||||||
## Define harfbuzz-subset library
|
## Define harfbuzz-subset library
|
||||||
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
|
if (NOT HB_DISABLE_SUBSET)
|
||||||
add_dependencies(harfbuzz-subset harfbuzz)
|
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
|
||||||
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
|
add_dependencies(harfbuzz-subset harfbuzz)
|
||||||
|
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
|
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (UNIX OR MINGW)
|
if (UNIX OR MINGW)
|
||||||
|
@ -549,7 +580,9 @@ if (UNIX OR MINGW)
|
||||||
set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
|
set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
|
||||||
set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||||
set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
|
set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
|
||||||
set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
|
if (NOT HB_DISABLE_SUBSET)
|
||||||
|
set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
|
||||||
|
endif ()
|
||||||
|
|
||||||
# No threadsafe statics as we do it ourselves
|
# No threadsafe statics as we do it ourselves
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
|
||||||
|
@ -828,51 +861,53 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
## src/ executables
|
if (NOT HB_DISABLE_TESTS)
|
||||||
foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
|
## src/ executables
|
||||||
set (prog_name ${prog})
|
foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
|
||||||
if (${prog_name} STREQUAL "test")
|
set (prog_name ${prog})
|
||||||
# test can not be used as a valid executable name on cmake, lets special case it
|
if (${prog_name} STREQUAL "test")
|
||||||
set (prog_name test-test)
|
# test can not be used as a valid executable name on cmake, lets special case it
|
||||||
endif ()
|
set (prog_name test-test)
|
||||||
add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
|
endif ()
|
||||||
target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
|
add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
|
||||||
endforeach ()
|
target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
|
||||||
set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
|
endforeach ()
|
||||||
|
set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
if (UNIX OR MINGW)
|
if (UNIX OR MINGW)
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
# generate harfbuzz.def after build completion
|
# generate harfbuzz.def after build completion
|
||||||
add_custom_command(TARGET harfbuzz POST_BUILD
|
add_custom_command(TARGET harfbuzz POST_BUILD
|
||||||
COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
|
COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
add_test(NAME check-static-inits.sh
|
add_test(NAME check-static-inits.sh
|
||||||
COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
|
COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh
|
||||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack
|
||||||
)
|
)
|
||||||
add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
|
add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh)
|
||||||
add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
|
add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh)
|
||||||
|
|
||||||
|
set_tests_properties(
|
||||||
|
check-static-inits.sh check-libstdc++.sh check-symbols.sh
|
||||||
|
PROPERTIES
|
||||||
|
ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
|
||||||
|
SKIP_RETURN_CODE 77)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
|
||||||
|
add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
|
||||||
|
add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
|
||||||
|
add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
|
||||||
set_tests_properties(
|
set_tests_properties(
|
||||||
check-static-inits.sh check-libstdc++.sh check-symbols.sh
|
check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
|
||||||
SKIP_RETURN_CODE 77)
|
SKIP_RETURN_CODE 77)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh)
|
# Needs to come last so that variables defined above are passed to
|
||||||
add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh)
|
# subdirectories.
|
||||||
add_test(NAME check-externs.sh COMMAND ./check-externs.sh)
|
add_subdirectory(test)
|
||||||
add_test(NAME check-includes.sh COMMAND ./check-includes.sh)
|
|
||||||
set_tests_properties(
|
|
||||||
check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh
|
|
||||||
PROPERTIES
|
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src
|
|
||||||
SKIP_RETURN_CODE 77)
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Needs to come last so that variables defined above are passed to
|
|
||||||
# subdirectories.
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
|
@ -148,12 +148,6 @@ AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread)
|
||||||
|
|
||||||
dnl ==========================================================================
|
dnl ==========================================================================
|
||||||
|
|
||||||
have_ot=true
|
|
||||||
if $have_ot; then
|
|
||||||
AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(HAVE_OT, $have_ot)
|
|
||||||
|
|
||||||
have_fallback=true
|
have_fallback=true
|
||||||
if $have_fallback; then
|
if $have_fallback; then
|
||||||
AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
|
AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
|
||||||
|
|
|
@ -29,11 +29,9 @@ HBSOURCES = $(HB_BASE_sources)
|
||||||
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
|
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
|
||||||
HBHEADERS = $(HB_BASE_headers)
|
HBHEADERS = $(HB_BASE_headers)
|
||||||
|
|
||||||
if HAVE_OT
|
|
||||||
HBSOURCES += $(HB_OT_sources)
|
HBSOURCES += $(HB_OT_sources)
|
||||||
HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources)
|
HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources)
|
||||||
HBHEADERS += $(HB_OT_headers)
|
HBHEADERS += $(HB_OT_headers)
|
||||||
endif
|
|
||||||
|
|
||||||
if HAVE_FALLBACK
|
if HAVE_FALLBACK
|
||||||
HBSOURCES += $(HB_FALLBACK_sources)
|
HBSOURCES += $(HB_FALLBACK_sources)
|
||||||
|
|
|
@ -260,6 +260,12 @@ struct Lookup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
|
||||||
|
{
|
||||||
|
const T *v = get_value (glyph_id, num_glyphs);
|
||||||
|
return v ? *v : Null(T);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
|
|
@ -44,21 +44,38 @@ namespace AAT {
|
||||||
using namespace OT;
|
using namespace OT;
|
||||||
|
|
||||||
|
|
||||||
|
struct KerxSubTableHeader
|
||||||
|
{
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (likely (c->check_struct (this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HBUINT32 length;
|
||||||
|
HBUINT32 coverage;
|
||||||
|
HBUINT32 tupleCount;
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (12);
|
||||||
|
};
|
||||||
|
|
||||||
struct KerxSubTableFormat0
|
struct KerxSubTableFormat0
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
{
|
{
|
||||||
hb_glyph_pair_t pair = {left, right};
|
hb_glyph_pair_t pair = {left, right};
|
||||||
int i = pairs.bsearch (pair);
|
int i = pairs.bsearch (pair);
|
||||||
if (i == -1)
|
return i == -1 ? 0 : pairs[i].get_kerning ();
|
||||||
return 0;
|
|
||||||
return pairs[i].get_kerning ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool apply (hb_aat_apply_context_t *c) const
|
inline bool apply (hb_aat_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
|
if (!c->plan->requested_kerning)
|
||||||
|
return false;
|
||||||
|
|
||||||
hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
|
hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
|
||||||
|
|
||||||
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||||
|
@ -73,10 +90,11 @@ struct KerxSubTableFormat0
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
KerxSubTableHeader header;
|
||||||
BinSearchArrayOf<KernPair, HBUINT32>
|
BinSearchArrayOf<KernPair, HBUINT32>
|
||||||
pairs; /* Sorted kern records. */
|
pairs; /* Sorted kern records. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (16, pairs);
|
DEFINE_SIZE_ARRAY (28, pairs);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxSubTableFormat1
|
struct KerxSubTableFormat1
|
||||||
|
@ -85,6 +103,9 @@ struct KerxSubTableFormat1
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
|
if (!c->plan->requested_kerning)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -98,23 +119,24 @@ struct KerxSubTableFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
KerxSubTableHeader header;
|
||||||
StateTable<HBUINT16> stateHeader;
|
StateTable<HBUINT16> stateHeader;
|
||||||
LOffsetTo<ArrayOf<HBUINT16> > valueTable;
|
LOffsetTo<ArrayOf<HBUINT16> > valueTable;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (20);
|
DEFINE_SIZE_STATIC (32);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxSubTableFormat2
|
struct KerxSubTableFormat2
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
|
||||||
const char *end, unsigned int num_glyphs) const
|
unsigned int num_glyphs) const
|
||||||
{
|
{
|
||||||
unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
|
unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs);
|
||||||
unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
|
unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs);
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
||||||
if (unlikely ((const char *) v < (const char *) &array ||
|
if (unlikely ((const char *) v < (const char *) &array ||
|
||||||
(const char *) v > (const char *) end - 2))
|
(const char *) v + v->static_size - (const char *) this <= header.length))
|
||||||
return 0;
|
return 0;
|
||||||
return *v;
|
return *v;
|
||||||
}
|
}
|
||||||
|
@ -123,8 +145,10 @@ struct KerxSubTableFormat2
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
|
if (!c->plan->requested_kerning)
|
||||||
|
return false;
|
||||||
|
|
||||||
accelerator_t accel (*this,
|
accelerator_t accel (*this,
|
||||||
c->sanitizer.end,
|
|
||||||
c->face->get_num_glyphs ());
|
c->face->get_num_glyphs ());
|
||||||
hb_kern_machine_t<accelerator_t> machine (accel);
|
hb_kern_machine_t<accelerator_t> machine (accel);
|
||||||
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||||
|
@ -145,32 +169,31 @@ struct KerxSubTableFormat2
|
||||||
struct accelerator_t
|
struct accelerator_t
|
||||||
{
|
{
|
||||||
const KerxSubTableFormat2 &table;
|
const KerxSubTableFormat2 &table;
|
||||||
const char *end;
|
|
||||||
unsigned int num_glyphs;
|
unsigned int num_glyphs;
|
||||||
|
|
||||||
inline accelerator_t (const KerxSubTableFormat2 &table_,
|
inline accelerator_t (const KerxSubTableFormat2 &table_,
|
||||||
const char *end_, unsigned int num_glyphs_)
|
unsigned int num_glyphs_)
|
||||||
: table (table_), end (end_), num_glyphs (num_glyphs_) {}
|
: table (table_), num_glyphs (num_glyphs_) {}
|
||||||
|
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
{
|
{
|
||||||
return table.get_kerning (left, right, end, num_glyphs);
|
return table.get_kerning (left, right, num_glyphs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
|
KerxSubTableHeader header;
|
||||||
|
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
|
||||||
LOffsetTo<Lookup<HBUINT16> >
|
LOffsetTo<Lookup<HBUINT16> >
|
||||||
leftClassTable; /* Offset from beginning of this subtable to
|
leftClassTable; /* Offset from beginning of this subtable to
|
||||||
* left-hand class table. */
|
* left-hand class table. */
|
||||||
LOffsetTo<Lookup<HBUINT16> >
|
LOffsetTo<Lookup<HBUINT16> >
|
||||||
rightClassTable;/* Offset from beginning of this subtable to
|
rightClassTable;/* Offset from beginning of this subtable to
|
||||||
* right-hand class table. */
|
* right-hand class table. */
|
||||||
LOffsetTo<FWORD>
|
LOffsetTo<FWORD> array; /* Offset from beginning of this subtable to
|
||||||
array; /* Offset from beginning of this subtable to
|
* the start of the kerning array. */
|
||||||
* the start of the kerning array. */
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (16);
|
DEFINE_SIZE_STATIC (28);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxSubTableFormat4
|
struct KerxSubTableFormat4
|
||||||
|
@ -193,17 +216,60 @@ struct KerxSubTableFormat4
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
KerxSubTableHeader header;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (1);
|
DEFINE_SIZE_STATIC (12);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxSubTableFormat6
|
struct KerxSubTableFormat6
|
||||||
{
|
{
|
||||||
|
enum Flags
|
||||||
|
{
|
||||||
|
ValuesAreLong = 0x00000001,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool is_long (void) const { return flags & ValuesAreLong; }
|
||||||
|
|
||||||
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
|
||||||
|
unsigned int num_glyphs) const
|
||||||
|
{
|
||||||
|
if (is_long ())
|
||||||
|
{
|
||||||
|
const U::Long &t = u.l;
|
||||||
|
unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
|
||||||
|
unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
|
||||||
|
unsigned int offset = l + r;
|
||||||
|
const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
|
||||||
|
if (unlikely ((const char *) v < (const char *) &t.array ||
|
||||||
|
(const char *) v + v->static_size - (const char *) this <= header.length))
|
||||||
|
return 0;
|
||||||
|
return *v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const U::Short &t = u.s;
|
||||||
|
unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
|
||||||
|
unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
|
||||||
|
unsigned int offset = l + r;
|
||||||
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
|
||||||
|
if (unlikely ((const char *) v < (const char *) &t.array ||
|
||||||
|
(const char *) v + v->static_size - (const char *) this <= header.length))
|
||||||
|
return 0;
|
||||||
|
return *v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline bool apply (hb_aat_apply_context_t *c) const
|
inline bool apply (hb_aat_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
/* TODO */
|
if (!c->plan->requested_kerning)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
accelerator_t accel (*this,
|
||||||
|
c->face->get_num_glyphs ());
|
||||||
|
hb_kern_machine_t<accelerator_t> machine (accel);
|
||||||
|
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
@ -212,30 +278,63 @@ struct KerxSubTableFormat6
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (likely (c->check_struct (this) &&
|
return_trace (likely (c->check_struct (this) &&
|
||||||
rowIndexTable.sanitize (c, this) &&
|
is_long () ?
|
||||||
columnIndexTable.sanitize (c, this) &&
|
(
|
||||||
kerningArray.sanitize (c, this) &&
|
u.l.rowIndexTable.sanitize (c, this) &&
|
||||||
kerningVector.sanitize (c, this)));
|
u.l.columnIndexTable.sanitize (c, this) &&
|
||||||
|
u.l.array.sanitize (c, this)
|
||||||
|
) : (
|
||||||
|
u.s.rowIndexTable.sanitize (c, this) &&
|
||||||
|
u.s.columnIndexTable.sanitize (c, this) &&
|
||||||
|
u.s.array.sanitize (c, this)
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct accelerator_t
|
||||||
|
{
|
||||||
|
const KerxSubTableFormat6 &table;
|
||||||
|
unsigned int num_glyphs;
|
||||||
|
|
||||||
|
inline accelerator_t (const KerxSubTableFormat6 &table_,
|
||||||
|
unsigned int num_glyphs_)
|
||||||
|
: table (table_), num_glyphs (num_glyphs_) {}
|
||||||
|
|
||||||
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||||
|
{
|
||||||
|
return table.get_kerning (left, right, num_glyphs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT32 flags;
|
KerxSubTableHeader header;
|
||||||
HBUINT16 rowCount;
|
HBUINT32 flags;
|
||||||
HBUINT16 columnCount;
|
HBUINT16 rowCount;
|
||||||
LOffsetTo<Lookup<HBUINT16> > rowIndexTable;
|
HBUINT16 columnCount;
|
||||||
LOffsetTo<Lookup<HBUINT16> > columnIndexTable;
|
union U
|
||||||
LOffsetTo<Lookup<HBUINT16> > kerningArray;
|
{
|
||||||
LOffsetTo<Lookup<HBUINT16> > kerningVector;
|
struct Long
|
||||||
|
{
|
||||||
|
LOffsetTo<Lookup<HBUINT32> > rowIndexTable;
|
||||||
|
LOffsetTo<Lookup<HBUINT32> > columnIndexTable;
|
||||||
|
LOffsetTo<FWORD32> array;
|
||||||
|
} l;
|
||||||
|
struct Short
|
||||||
|
{
|
||||||
|
LOffsetTo<Lookup<HBUINT16> > rowIndexTable;
|
||||||
|
LOffsetTo<Lookup<HBUINT16> > columnIndexTable;
|
||||||
|
LOffsetTo<FWORD> array;
|
||||||
|
} s;
|
||||||
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (24);
|
DEFINE_SIZE_STATIC (32);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KerxTable
|
struct KerxTable
|
||||||
{
|
{
|
||||||
friend struct kerx;
|
friend struct kerx;
|
||||||
|
|
||||||
inline unsigned int get_size (void) const { return length; }
|
inline unsigned int get_size (void) const { return u.header.length; }
|
||||||
inline unsigned int get_type (void) const { return coverage & SubtableType; }
|
inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; }
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
|
@ -269,19 +368,16 @@ struct KerxTable
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!length.sanitize (c) ||
|
if (!u.header.sanitize (c) ||
|
||||||
length < min_size ||
|
!c->check_range (this, u.header.length))
|
||||||
!c->check_range (this, length))
|
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
return_trace (dispatch (c));
|
return_trace (dispatch (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT32 length;
|
|
||||||
HBUINT32 coverage;
|
|
||||||
HBUINT32 tupleCount;
|
|
||||||
union {
|
union {
|
||||||
|
KerxSubTableHeader header;
|
||||||
KerxSubTableFormat0 format0;
|
KerxSubTableFormat0 format0;
|
||||||
KerxSubTableFormat1 format1;
|
KerxSubTableFormat1 format1;
|
||||||
KerxSubTableFormat2 format2;
|
KerxSubTableFormat2 format2;
|
||||||
|
@ -312,21 +408,22 @@ struct kerx
|
||||||
{
|
{
|
||||||
bool reverse;
|
bool reverse;
|
||||||
|
|
||||||
|
if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) ||
|
||||||
|
table->u.header.tupleCount)
|
||||||
|
goto skip; /* We do NOT handle cross-stream or variation kerning. */
|
||||||
|
|
||||||
if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
|
if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
|
||||||
bool (table->coverage & KerxTable::Vertical))
|
bool (table->u.header.coverage & KerxTable::Vertical))
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (table->coverage & KerxTable::CrossStream)
|
reverse = bool (table->u.header.coverage & KerxTable::Backwards) !=
|
||||||
goto skip; /* We do NOT handle cross-stream kerning. None of Apple fonts use it. */
|
|
||||||
|
|
||||||
reverse = bool (table->coverage & KerxTable::Backwards) !=
|
|
||||||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
||||||
|
|
||||||
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
|
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
c->buffer->reverse ();
|
c->buffer->reverse ();
|
||||||
|
|
||||||
c->sanitizer.set_object (*table);
|
c->sanitizer.set_object (*table);
|
||||||
|
|
||||||
|
@ -337,7 +434,7 @@ struct kerx
|
||||||
table->dispatch (c);
|
table->dispatch (c);
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
c->buffer->reverse ();
|
c->buffer->reverse ();
|
||||||
|
|
||||||
(void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
|
(void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,21 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||||
*blob = hb_ot_face_data (face)->morx.get_blob ();
|
*blob = hb_ot_face_data (face)->morx.get_blob ();
|
||||||
return morx;
|
return morx;
|
||||||
}
|
}
|
||||||
|
static inline const AAT::kerx&
|
||||||
|
_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||||
|
{
|
||||||
|
if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
|
||||||
|
{
|
||||||
|
if (blob)
|
||||||
|
*blob = hb_blob_get_empty ();
|
||||||
|
return Null(AAT::kerx);
|
||||||
|
}
|
||||||
|
const AAT::kerx& kerx = *(hb_ot_face_data (face)->kerx.get ());
|
||||||
|
if (blob)
|
||||||
|
*blob = hb_ot_face_data (face)->kerx.get_blob ();
|
||||||
|
return kerx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
hb_aat_layout_has_substitution (hb_face_t *face)
|
hb_aat_layout_has_substitution (hb_face_t *face)
|
||||||
|
@ -73,19 +88,21 @@ hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
|
||||||
morx.apply (&c);
|
morx.apply (&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hb_bool_t
|
||||||
|
hb_aat_layout_has_positioning (hb_face_t *face)
|
||||||
|
{
|
||||||
|
return _get_kerx (face).has_data ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
hb_blob_t *blob;
|
hb_blob_t *blob;
|
||||||
const AAT::ankr& ankr = _get_ankr (font->face, &blob);
|
|
||||||
const AAT::kerx& kerx = _get_kerx (font->face, &blob);
|
const AAT::kerx& kerx = _get_kerx (font->face, &blob);
|
||||||
const AAT::trak& trak = _get_trak (font->face, &blob);
|
|
||||||
|
|
||||||
AAT::hb_aat_apply_context_t c (font, buffer, blob);
|
AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
|
||||||
kerx.apply (&c, &ankr);
|
kerx.apply (&c);
|
||||||
trak.apply (&c);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
hb_buffer_t *buffer);
|
hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
HB_INTERNAL hb_bool_t
|
||||||
|
hb_aat_layout_has_positioning (hb_face_t *face);
|
||||||
|
|
||||||
HB_INTERNAL void
|
HB_INTERNAL void
|
||||||
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
|
|
|
@ -47,8 +47,27 @@ _hb_options_init (void)
|
||||||
u.i = 0;
|
u.i = 0;
|
||||||
u.opts.initialized = 1;
|
u.opts.initialized = 1;
|
||||||
|
|
||||||
char *c = getenv ("HB_OPTIONS");
|
const char *c = getenv ("HB_OPTIONS");
|
||||||
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
|
if (c)
|
||||||
|
{
|
||||||
|
while (*c)
|
||||||
|
{
|
||||||
|
const char *p = strchr (c, ':');
|
||||||
|
if (!p)
|
||||||
|
p = c + strlen (c);
|
||||||
|
|
||||||
|
#define OPTION(name, symbol) \
|
||||||
|
if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
|
||||||
|
|
||||||
|
OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
|
||||||
|
OPTION ("aat", aat);
|
||||||
|
|
||||||
|
#undef OPTION
|
||||||
|
|
||||||
|
c = *p ? p + 1 : p;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* This is idempotent and threadsafe. */
|
/* This is idempotent and threadsafe. */
|
||||||
_hb_options.set_relaxed (u.i);
|
_hb_options.set_relaxed (u.i);
|
||||||
|
|
|
@ -43,9 +43,10 @@
|
||||||
|
|
||||||
struct hb_options_t
|
struct hb_options_t
|
||||||
{
|
{
|
||||||
unsigned int unused : 1; /* In-case sign bit is here. */
|
bool unused : 1; /* In-case sign bit is here. */
|
||||||
unsigned int initialized : 1;
|
bool initialized : 1;
|
||||||
unsigned int uniscribe_bug_compatible : 1;
|
bool uniscribe_bug_compatible : 1;
|
||||||
|
bool aat : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
union hb_options_union_t {
|
union hb_options_union_t {
|
||||||
|
|
|
@ -257,6 +257,13 @@ struct hb_sanitize_context_t :
|
||||||
|
|
||||||
inline void set_max_ops (int max_ops_) { max_ops = max_ops_; }
|
inline void set_max_ops (int max_ops_) { max_ops = max_ops_; }
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
* This set_object() thing is to use sanitize at runtime lookup
|
||||||
|
* application time. This is very distinct from the regular
|
||||||
|
* sanitizer operation, so, eventually, separate into another
|
||||||
|
* type and make hb_aat_apply_context_t use that one instead
|
||||||
|
* of abusing this one.
|
||||||
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void set_object (const T& obj)
|
inline void set_object (const T& obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,6 +92,9 @@ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
|
||||||
/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
|
/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
|
||||||
typedef HBINT16 FWORD;
|
typedef HBINT16 FWORD;
|
||||||
|
|
||||||
|
/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */
|
||||||
|
typedef HBINT32 FWORD32;
|
||||||
|
|
||||||
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
|
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
|
||||||
typedef HBUINT16 UFWORD;
|
typedef HBUINT16 UFWORD;
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,12 @@ struct KernSubTableFormat2
|
||||||
{
|
{
|
||||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
|
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
|
||||||
{
|
{
|
||||||
|
/* This subtable is disabled. It's not cleaer to me *exactly* where the offests are
|
||||||
|
* based from. I *think* they should be based from beginning of kern subtable wrapper,
|
||||||
|
* *NOT* "this". Since we know of no fonts that use this subtable, we are disabling
|
||||||
|
* it. Someday fix it and re-enable. Better yet, find fonts that use it... Meh,
|
||||||
|
* Windows doesn't implement it. Maybe just remove... */
|
||||||
|
return 0;
|
||||||
unsigned int l = (this+leftClassTable).get_class (left);
|
unsigned int l = (this+leftClassTable).get_class (left);
|
||||||
unsigned int r = (this+rightClassTable).get_class (right);
|
unsigned int r = (this+rightClassTable).get_class (right);
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
|
@ -204,6 +210,7 @@ struct KernSubTableFormat2
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (true); /* Disabled. See above. */
|
||||||
return_trace (rowWidth.sanitize (c) &&
|
return_trace (rowWidth.sanitize (c) &&
|
||||||
leftClassTable.sanitize (c, this) &&
|
leftClassTable.sanitize (c, this) &&
|
||||||
rightClassTable.sanitize (c, this) &&
|
rightClassTable.sanitize (c, this) &&
|
||||||
|
|
|
@ -621,6 +621,64 @@ struct hb_ot_apply_context_t :
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct hb_get_subtables_context_t :
|
||||||
|
hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
|
||||||
|
{
|
||||||
|
template <typename Type>
|
||||||
|
static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
|
||||||
|
{
|
||||||
|
const Type *typed_obj = (const Type *) obj;
|
||||||
|
return typed_obj->apply (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
|
||||||
|
|
||||||
|
struct hb_applicable_t
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
inline void init (const T &obj_, hb_apply_func_t apply_func_)
|
||||||
|
{
|
||||||
|
obj = &obj_;
|
||||||
|
apply_func = apply_func_;
|
||||||
|
digest.init ();
|
||||||
|
obj_.get_coverage ().add_coverage (&digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool apply (OT::hb_ot_apply_context_t *c) const
|
||||||
|
{
|
||||||
|
return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const void *obj;
|
||||||
|
hb_apply_func_t apply_func;
|
||||||
|
hb_set_digest_t digest;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef hb_vector_t<hb_applicable_t, 2> array_t;
|
||||||
|
|
||||||
|
/* Dispatch interface. */
|
||||||
|
inline const char *get_name (void) { return "GET_SUBTABLES"; }
|
||||||
|
template <typename T>
|
||||||
|
inline return_t dispatch (const T &obj)
|
||||||
|
{
|
||||||
|
hb_applicable_t *entry = array.push();
|
||||||
|
entry->init (obj, apply_to<T>);
|
||||||
|
return HB_VOID;
|
||||||
|
}
|
||||||
|
static return_t default_return_value (void) { return HB_VOID; }
|
||||||
|
bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
|
||||||
|
|
||||||
|
hb_get_subtables_context_t (array_t &array_) :
|
||||||
|
array (array_),
|
||||||
|
debug_depth (0) {}
|
||||||
|
|
||||||
|
array_t &array;
|
||||||
|
unsigned int debug_depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
||||||
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
||||||
|
@ -2562,6 +2620,39 @@ struct Extension
|
||||||
* GSUB/GPOS Common
|
* GSUB/GPOS Common
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct hb_ot_layout_lookup_accelerator_t
|
||||||
|
{
|
||||||
|
template <typename TLookup>
|
||||||
|
inline void init (const TLookup &lookup)
|
||||||
|
{
|
||||||
|
digest.init ();
|
||||||
|
lookup.add_coverage (&digest);
|
||||||
|
|
||||||
|
subtables.init ();
|
||||||
|
OT::hb_get_subtables_context_t c_get_subtables (subtables);
|
||||||
|
lookup.dispatch (&c_get_subtables);
|
||||||
|
}
|
||||||
|
inline void fini (void)
|
||||||
|
{
|
||||||
|
subtables.fini ();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool may_have (hb_codepoint_t g) const
|
||||||
|
{ return digest.may_have (g); }
|
||||||
|
|
||||||
|
inline bool apply (hb_ot_apply_context_t *c) const
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < subtables.len; i++)
|
||||||
|
if (subtables[i].apply (c))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
hb_set_digest_t digest;
|
||||||
|
hb_get_subtables_context_t::array_t subtables;
|
||||||
|
};
|
||||||
|
|
||||||
struct GSUBGPOS
|
struct GSUBGPOS
|
||||||
{
|
{
|
||||||
inline bool has_data (void) const { return version.to_int () != 0; }
|
inline bool has_data (void) const { return version.to_int () != 0; }
|
||||||
|
|
|
@ -1094,7 +1094,7 @@ struct GSUBProxy
|
||||||
accels (hb_ot_face_data (face)->GSUB->accels) {}
|
accels (hb_ot_face_data (face)->GSUB->accels) {}
|
||||||
|
|
||||||
const OT::GSUB &table;
|
const OT::GSUB &table;
|
||||||
const hb_ot_layout_lookup_accelerator_t *accels;
|
const OT::hb_ot_layout_lookup_accelerator_t *accels;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GPOSProxy
|
struct GPOSProxy
|
||||||
|
@ -1108,63 +1108,13 @@ struct GPOSProxy
|
||||||
accels (hb_ot_face_data (face)->GPOS->accels) {}
|
accels (hb_ot_face_data (face)->GPOS->accels) {}
|
||||||
|
|
||||||
const OT::GPOS &table;
|
const OT::GPOS &table;
|
||||||
const hb_ot_layout_lookup_accelerator_t *accels;
|
const OT::hb_ot_layout_lookup_accelerator_t *accels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct hb_get_subtables_context_t :
|
|
||||||
hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
|
|
||||||
{
|
|
||||||
template <typename Type>
|
|
||||||
static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
|
|
||||||
{
|
|
||||||
const Type *typed_obj = (const Type *) obj;
|
|
||||||
return typed_obj->apply (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
|
|
||||||
|
|
||||||
struct hb_applicable_t
|
|
||||||
{
|
|
||||||
inline void init (const void *obj_, hb_apply_func_t apply_func_)
|
|
||||||
{
|
|
||||||
obj = obj_;
|
|
||||||
apply_func = apply_func_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const void *obj;
|
|
||||||
hb_apply_func_t apply_func;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t;
|
|
||||||
|
|
||||||
/* Dispatch interface. */
|
|
||||||
inline const char *get_name (void) { return "GET_SUBTABLES"; }
|
|
||||||
template <typename T>
|
|
||||||
inline return_t dispatch (const T &obj)
|
|
||||||
{
|
|
||||||
hb_applicable_t *entry = array.push();
|
|
||||||
entry->init (&obj, apply_to<T>);
|
|
||||||
return HB_VOID;
|
|
||||||
}
|
|
||||||
static return_t default_return_value (void) { return HB_VOID; }
|
|
||||||
bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
|
|
||||||
|
|
||||||
hb_get_subtables_context_t (array_t &array_) :
|
|
||||||
array (array_),
|
|
||||||
debug_depth (0) {}
|
|
||||||
|
|
||||||
array_t &array;
|
|
||||||
unsigned int debug_depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
apply_forward (OT::hb_ot_apply_context_t *c,
|
apply_forward (OT::hb_ot_apply_context_t *c,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel,
|
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
const hb_get_subtables_context_t::array_t &subtables)
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
@ -1175,12 +1125,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
|
||||||
(buffer->cur().mask & c->lookup_mask) &&
|
(buffer->cur().mask & c->lookup_mask) &&
|
||||||
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < subtables.len; i++)
|
applied = accel.apply (c);
|
||||||
if (subtables[i].apply (c))
|
|
||||||
{
|
|
||||||
applied = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applied)
|
if (applied)
|
||||||
|
@ -1193,8 +1138,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
apply_backward (OT::hb_ot_apply_context_t *c,
|
apply_backward (OT::hb_ot_apply_context_t *c,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel,
|
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
const hb_get_subtables_context_t::array_t &subtables)
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
@ -1204,12 +1148,8 @@ apply_backward (OT::hb_ot_apply_context_t *c,
|
||||||
(buffer->cur().mask & c->lookup_mask) &&
|
(buffer->cur().mask & c->lookup_mask) &&
|
||||||
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < subtables.len; i++)
|
if (accel.apply (c))
|
||||||
if (subtables[i].apply (c))
|
ret = true;
|
||||||
{
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* The reverse lookup doesn't "advance" cursor (for good reason). */
|
/* The reverse lookup doesn't "advance" cursor (for good reason). */
|
||||||
buffer->idx--;
|
buffer->idx--;
|
||||||
|
@ -1223,7 +1163,7 @@ template <typename Proxy>
|
||||||
static inline void
|
static inline void
|
||||||
apply_string (OT::hb_ot_apply_context_t *c,
|
apply_string (OT::hb_ot_apply_context_t *c,
|
||||||
const typename Proxy::Lookup &lookup,
|
const typename Proxy::Lookup &lookup,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
{
|
{
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
|
||||||
|
@ -1232,10 +1172,6 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
||||||
|
|
||||||
c->set_lookup_props (lookup.get_props ());
|
c->set_lookup_props (lookup.get_props ());
|
||||||
|
|
||||||
hb_get_subtables_context_t::array_t subtables;
|
|
||||||
hb_get_subtables_context_t c_get_subtables (subtables);
|
|
||||||
lookup.dispatch (&c_get_subtables);
|
|
||||||
|
|
||||||
if (likely (!lookup.is_reverse ()))
|
if (likely (!lookup.is_reverse ()))
|
||||||
{
|
{
|
||||||
/* in/out forward substitution/positioning */
|
/* in/out forward substitution/positioning */
|
||||||
|
@ -1244,7 +1180,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
||||||
buffer->idx = 0;
|
buffer->idx = 0;
|
||||||
|
|
||||||
bool ret;
|
bool ret;
|
||||||
ret = apply_forward (c, accel, subtables);
|
ret = apply_forward (c, accel);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
if (!Proxy::inplace)
|
if (!Proxy::inplace)
|
||||||
|
@ -1260,7 +1196,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
||||||
buffer->remove_output ();
|
buffer->remove_output ();
|
||||||
buffer->idx = buffer->len - 1;
|
buffer->idx = buffer->len - 1;
|
||||||
|
|
||||||
apply_backward (c, accel, subtables);
|
apply_backward (c, accel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1319,7 +1255,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
|
||||||
void
|
void
|
||||||
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||||
const OT::SubstLookup &lookup,
|
const OT::SubstLookup &lookup,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
{
|
{
|
||||||
apply_string<GSUBProxy> (c, lookup, accel);
|
apply_string<GSUBProxy> (c, lookup, accel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,32 +112,16 @@ hb_ot_layout_substitute_start (hb_font_t *font,
|
||||||
hb_buffer_t *buffer);
|
hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
struct hb_ot_layout_lookup_accelerator_t
|
|
||||||
{
|
|
||||||
template <typename TLookup>
|
|
||||||
inline void init (const TLookup &lookup)
|
|
||||||
{
|
|
||||||
digest.init ();
|
|
||||||
lookup.add_coverage (&digest);
|
|
||||||
}
|
|
||||||
inline void fini (void) {}
|
|
||||||
|
|
||||||
inline bool may_have (hb_codepoint_t g) const
|
|
||||||
{ return digest.may_have (g); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
hb_set_digest_t digest;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace OT {
|
namespace OT {
|
||||||
struct hb_ot_apply_context_t;
|
struct hb_ot_apply_context_t;
|
||||||
struct SubstLookup;
|
struct SubstLookup;
|
||||||
|
struct hb_ot_layout_lookup_accelerator_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
HB_INTERNAL void
|
HB_INTERNAL void
|
||||||
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||||
const OT::SubstLookup &lookup,
|
const OT::SubstLookup &lookup,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel);
|
const OT::hb_ot_layout_lookup_accelerator_t &accel);
|
||||||
|
|
||||||
|
|
||||||
/* Should be called before all the position_lookup's are done. */
|
/* Should be called before all the position_lookup's are done. */
|
||||||
|
|
|
@ -201,7 +201,7 @@ struct arabic_fallback_plan_t
|
||||||
|
|
||||||
hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
|
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
|
||||||
|
|
|
@ -460,6 +460,10 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
|
||||||
|
!font->has_glyph_h_kerning_func () :
|
||||||
|
!font->has_glyph_v_kerning_func ())
|
||||||
|
return;
|
||||||
hb_ot_shape_fallback_kern_driver_t driver (font, buffer);
|
hb_ot_shape_fallback_kern_driver_t driver (font, buffer);
|
||||||
hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
|
hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
|
||||||
machine.kern (font, buffer, plan->kern_mask);
|
machine.kern (font, buffer, plan->kern_mask);
|
||||||
|
|
|
@ -42,6 +42,17 @@
|
||||||
#include "hb-aat-layout.hh"
|
#include "hb-aat-layout.hh"
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_hb_apply_morx (hb_face_t *face)
|
||||||
|
{
|
||||||
|
if (hb_options ().aat &&
|
||||||
|
hb_aat_layout_has_substitution (face))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !hb_ot_layout_has_substitution (face) &&
|
||||||
|
hb_aat_layout_has_substitution (face);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
||||||
const int *coords,
|
const int *coords,
|
||||||
|
@ -55,24 +66,56 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
||||||
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
|
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
|
||||||
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
|
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
|
||||||
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
|
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
|
||||||
|
|
||||||
plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
|
|
||||||
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
|
|
||||||
|
|
||||||
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
|
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
|
||||||
plan.kerning_requested = !!plan.kern_mask;
|
hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
|
||||||
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
|
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
|
||||||
|
plan.kern_mask = plan.map.get_mask (kern_tag);
|
||||||
plan.apply_morx = !hb_ot_layout_has_substitution (face) &&
|
|
||||||
hb_aat_layout_has_substitution (face);
|
|
||||||
|
|
||||||
|
plan.requested_kerning = !!plan.kern_mask;
|
||||||
|
bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
|
||||||
bool disable_gpos = plan.shaper->gpos_tag &&
|
bool disable_gpos = plan.shaper->gpos_tag &&
|
||||||
plan.shaper->gpos_tag != plan.map.chosen_script[1];
|
plan.shaper->gpos_tag != plan.map.chosen_script[1];
|
||||||
plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
|
|
||||||
plan.apply_kern = !plan.apply_gpos && hb_ot_layout_has_kerning (face);
|
/*
|
||||||
plan.fallback_kerning = !plan.apply_gpos && !plan.apply_kern;
|
* Decide who provides glyph classes. GDEF or Unicode.
|
||||||
plan.fallback_mark_positioning = !plan.apply_gpos;
|
*/
|
||||||
plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
|
|
||||||
|
if (!hb_ot_layout_has_glyph_classes (face))
|
||||||
|
plan.fallback_glyph_classes = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decide who does substitutions. GSUB, morx, or fallback.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plan.apply_morx = _hb_apply_morx (face);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decide who does positioning. GPOS, kerx, kern, or fallback.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (hb_options ().aat && hb_aat_layout_has_positioning (face))
|
||||||
|
plan.apply_kerx = true;
|
||||||
|
else if (!disable_gpos && hb_ot_layout_has_positioning (face))
|
||||||
|
plan.apply_gpos = true;
|
||||||
|
else if (hb_aat_layout_has_positioning (face))
|
||||||
|
plan.apply_kerx = true;
|
||||||
|
|
||||||
|
if (plan.requested_kerning)
|
||||||
|
{
|
||||||
|
if (plan.apply_kerx)
|
||||||
|
;/* kerx supercedes kern. */
|
||||||
|
else if (!has_gpos_kern)
|
||||||
|
{
|
||||||
|
if (hb_ot_layout_has_kerning (face))
|
||||||
|
plan.apply_kern = true;
|
||||||
|
else
|
||||||
|
plan.fallback_kerning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
|
||||||
|
if (!plan.apply_gpos)
|
||||||
|
plan.fallback_mark_positioning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,8 +272,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||||
|
|
||||||
/* Ugly that we have to do this here...
|
/* Ugly that we have to do this here...
|
||||||
* If we are going to apply morx, choose default shaper. */
|
* If we are going to apply morx, choose default shaper. */
|
||||||
if (!hb_ot_layout_has_substitution (planner.face) &&
|
if (_hb_apply_morx (planner.face))
|
||||||
hb_aat_layout_has_substitution (planner.face))
|
|
||||||
planner.shaper = &_hb_ot_complex_shaper_default;
|
planner.shaper = &_hb_ot_complex_shaper_default;
|
||||||
else
|
else
|
||||||
planner.shaper = hb_ot_shape_complex_categorize (&planner);
|
planner.shaper = hb_ot_shape_complex_categorize (&planner);
|
||||||
|
@ -792,6 +834,8 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
|
||||||
|
|
||||||
if (c->plan->apply_gpos)
|
if (c->plan->apply_gpos)
|
||||||
c->plan->position (c->font, c->buffer);
|
c->plan->position (c->font, c->buffer);
|
||||||
|
else if (c->plan->apply_kerx)
|
||||||
|
hb_aat_layout_position (c->plan, c->font, c->buffer);
|
||||||
|
|
||||||
switch (c->plan->shaper->zero_width_marks)
|
switch (c->plan->shaper->zero_width_marks)
|
||||||
{
|
{
|
||||||
|
@ -835,16 +879,12 @@ hb_ot_position (const hb_ot_shape_context_t *c)
|
||||||
|
|
||||||
/* Visual fallback goes here. */
|
/* Visual fallback goes here. */
|
||||||
|
|
||||||
if (!c->plan->kerning_requested)
|
if (c->plan->apply_kern)
|
||||||
;
|
|
||||||
else if (c->plan->apply_kern)
|
|
||||||
hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
|
hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
|
||||||
else if (c->plan->fallback_kerning)
|
else if (c->plan->fallback_kerning)
|
||||||
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
||||||
|
|
||||||
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
||||||
|
|
||||||
//hb_aat_layout_position (c->font, c->buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -43,14 +43,15 @@ struct hb_ot_shape_plan_t
|
||||||
hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
|
hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
|
||||||
hb_mask_t kern_mask;
|
hb_mask_t kern_mask;
|
||||||
|
|
||||||
|
bool requested_kerning : 1;
|
||||||
bool has_frac : 1;
|
bool has_frac : 1;
|
||||||
bool kerning_requested : 1;
|
|
||||||
bool has_gpos_mark : 1;
|
bool has_gpos_mark : 1;
|
||||||
bool fallback_glyph_classes : 1;
|
bool fallback_glyph_classes : 1;
|
||||||
bool fallback_kerning : 1;
|
bool fallback_kerning : 1;
|
||||||
bool fallback_mark_positioning : 1;
|
bool fallback_mark_positioning : 1;
|
||||||
|
|
||||||
bool apply_morx : 1;
|
bool apply_morx : 1;
|
||||||
|
bool apply_kerx : 1;
|
||||||
bool apply_kern : 1;
|
bool apply_kern : 1;
|
||||||
bool apply_gpos : 1;
|
bool apply_gpos : 1;
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,7 @@ HB_SHAPER_IMPLEMENT (graphite2)
|
||||||
HB_SHAPER_IMPLEMENT (coretext_aat)
|
HB_SHAPER_IMPLEMENT (coretext_aat)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OT
|
|
||||||
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISCRIBE
|
#ifdef HAVE_UNISCRIBE
|
||||||
HB_SHAPER_IMPLEMENT (uniscribe)
|
HB_SHAPER_IMPLEMENT (uniscribe)
|
||||||
|
|
|
@ -45,10 +45,8 @@
|
||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
#define HB_H_IN
|
#define HB_H_IN
|
||||||
#ifdef HAVE_OT
|
|
||||||
#include "hb-ot.h"
|
#include "hb-ot.h"
|
||||||
#define HB_OT_H_IN
|
#define HB_OT_H_IN
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -73,14 +73,13 @@ test_unicode_LDADD += $(top_builddir)/src/libharfbuzz-icu.la $(ICU_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
if HAVE_OT
|
|
||||||
|
|
||||||
TEST_PROGS += \
|
TEST_PROGS += \
|
||||||
test-ot-color \
|
test-ot-color \
|
||||||
test-ot-tag \
|
test-ot-tag \
|
||||||
test-ot-extents-cff \
|
test-ot-extents-cff \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
||||||
if HAVE_PTHREAD
|
if HAVE_PTHREAD
|
||||||
if HAVE_FREETYPE
|
if HAVE_FREETYPE
|
||||||
TEST_PROGS += test-multithread
|
TEST_PROGS += test-multithread
|
||||||
|
@ -100,7 +99,6 @@ test_ot_math_LDADD = $(LDADD) $(FREETYPE_LIBS)
|
||||||
test_ot_math_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
|
test_ot_math_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
|
||||||
endif # HAVE_FREETYPE
|
endif # HAVE_FREETYPE
|
||||||
|
|
||||||
endif # HAVE_OT
|
|
||||||
|
|
||||||
# Tests for header compilation
|
# Tests for header compilation
|
||||||
TEST_PROGS += \
|
TEST_PROGS += \
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <hb.h>
|
#include <hb.h>
|
||||||
|
#include <hb-ot.h>
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
#ifdef HAVE_GLIB
|
||||||
#include <hb-glib.h>
|
#include <hb-glib.h>
|
||||||
|
@ -45,10 +46,6 @@
|
||||||
#include <hb-ft.h>
|
#include <hb-ft.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OT
|
|
||||||
#include <hb-ot.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISCRIBE
|
#ifdef HAVE_UNISCRIBE
|
||||||
#include <hb-uniscribe.h>
|
#include <hb-uniscribe.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,14 +52,11 @@ hb_subset_LDADD = \
|
||||||
$(top_builddir)/src/libharfbuzz-subset.la
|
$(top_builddir)/src/libharfbuzz-subset.la
|
||||||
bin_PROGRAMS += hb-subset
|
bin_PROGRAMS += hb-subset
|
||||||
|
|
||||||
if HAVE_OT
|
|
||||||
hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources)
|
hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources)
|
||||||
bin_PROGRAMS += hb-ot-shape-closure
|
bin_PROGRAMS += hb-ot-shape-closure
|
||||||
endif # HAVE_OT
|
|
||||||
|
|
||||||
endif # HAVE_GLIB
|
endif # HAVE_GLIB
|
||||||
|
|
||||||
#if HAVE_OT
|
|
||||||
#if HAVE_FONTCONFIG
|
#if HAVE_FONTCONFIG
|
||||||
#hb_fc_list_SOURCES = \
|
#hb_fc_list_SOURCES = \
|
||||||
# hb-fc.cc \
|
# hb-fc.cc \
|
||||||
|
@ -72,6 +69,5 @@ endif # HAVE_GLIB
|
||||||
# $(NULL)
|
# $(NULL)
|
||||||
#bin_PROGRAMS += hb-fc-list
|
#bin_PROGRAMS += hb-fc-list
|
||||||
#endif # HAVE_FONTCONFIG
|
#endif # HAVE_FONTCONFIG
|
||||||
#endif # HAVE_OT
|
|
||||||
|
|
||||||
-include $(top_srcdir)/git.mk
|
-include $(top_srcdir)/git.mk
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
#include <hb-ft.h>
|
#include <hb-ft.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OT
|
|
||||||
#include <hb-ot.h>
|
#include <hb-ot.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct supported_font_funcs_t {
|
static struct supported_font_funcs_t {
|
||||||
char name[4];
|
char name[4];
|
||||||
|
@ -41,9 +39,7 @@ static struct supported_font_funcs_t {
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
{"ft", hb_ft_font_set_funcs},
|
{"ft", hb_ft_font_set_funcs},
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_OT
|
|
||||||
{"ot", hb_ot_font_set_funcs},
|
{"ot", hb_ot_font_set_funcs},
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <hb.h>
|
#include <hb.h>
|
||||||
#ifdef HAVE_OT
|
|
||||||
#include <hb-ot.h>
|
#include <hb-ot.h>
|
||||||
#endif
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gprintf.h>
|
#include <glib/gprintf.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue