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
|
||||
- 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:
|
||||
docker:
|
||||
- image: ubuntu:17.10
|
||||
|
@ -274,6 +285,7 @@ workflows:
|
|||
# macOS
|
||||
- macos-llvm-gcc-4.2
|
||||
- macos-notest-apple-gcc-i686-4.2
|
||||
- macos-notest-ios
|
||||
|
||||
# both autotools and cmake
|
||||
- distcheck
|
||||
|
|
137
CMakeLists.txt
137
CMakeLists.txt
|
@ -82,12 +82,21 @@ if (HB_CHECK)
|
|||
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
|
||||
${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_BINARY_DIR}/src
|
||||
)
|
||||
|
||||
add_definitions(-DHAVE_OT)
|
||||
add_definitions(-DHAVE_FALLBACK)
|
||||
|
||||
# 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_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
|
||||
|
||||
find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
|
||||
if (APPLICATION_SERVICES_FRAMEWORK)
|
||||
list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
|
||||
endif (APPLICATION_SERVICES_FRAMEWORK)
|
||||
if (HB_IOS)
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
if (COREFOUNDATION)
|
||||
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 ()
|
||||
|
||||
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})
|
||||
|
||||
## Define harfbuzz-subset library
|
||||
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
|
||||
add_dependencies(harfbuzz-subset harfbuzz)
|
||||
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
|
||||
if (NOT HB_DISABLE_SUBSET)
|
||||
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
|
||||
add_dependencies(harfbuzz-subset harfbuzz)
|
||||
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
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_DIRECTORIES "")
|
||||
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
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
|
||||
|
@ -828,51 +861,53 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
|
|||
endif ()
|
||||
|
||||
|
||||
## src/ executables
|
||||
foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
|
||||
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
|
||||
set (prog_name test-test)
|
||||
endif ()
|
||||
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")
|
||||
if (NOT HB_DISABLE_TESTS)
|
||||
## src/ executables
|
||||
foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
|
||||
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
|
||||
set (prog_name test-test)
|
||||
endif ()
|
||||
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")
|
||||
|
||||
## Tests
|
||||
if (UNIX OR MINGW)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
# generate harfbuzz.def after build completion
|
||||
add_custom_command(TARGET harfbuzz POST_BUILD
|
||||
COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
|
||||
## Tests
|
||||
if (UNIX OR MINGW)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
# generate harfbuzz.def after build completion
|
||||
add_custom_command(TARGET harfbuzz POST_BUILD
|
||||
COMMAND "${PYTHON_EXECUTABLE}" ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def ${project_headers}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
add_test(NAME 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
|
||||
)
|
||||
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-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
|
||||
)
|
||||
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)
|
||||
|
||||
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(
|
||||
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
|
||||
ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src"
|
||||
WORKING_DIRECTORY ${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(
|
||||
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)
|
||||
# Needs to come last so that variables defined above are passed to
|
||||
# subdirectories.
|
||||
add_subdirectory(test)
|
||||
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 ==========================================================================
|
||||
|
||||
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
|
||||
if $have_fallback; then
|
||||
AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
|
||||
|
|
|
@ -29,11 +29,9 @@ HBSOURCES = $(HB_BASE_sources)
|
|||
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
|
||||
HBHEADERS = $(HB_BASE_headers)
|
||||
|
||||
if HAVE_OT
|
||||
HBSOURCES += $(HB_OT_sources)
|
||||
HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources)
|
||||
HBHEADERS += $(HB_OT_headers)
|
||||
endif
|
||||
|
||||
if HAVE_FALLBACK
|
||||
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
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
|
|
@ -44,21 +44,38 @@ namespace AAT {
|
|||
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
|
||||
{
|
||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||
{
|
||||
hb_glyph_pair_t pair = {left, right};
|
||||
int i = pairs.bsearch (pair);
|
||||
if (i == -1)
|
||||
return 0;
|
||||
return pairs[i].get_kerning ();
|
||||
return i == -1 ? 0 : pairs[i].get_kerning ();
|
||||
}
|
||||
|
||||
inline bool apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
|
||||
if (!c->plan->requested_kerning)
|
||||
return false;
|
||||
|
||||
hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
|
||||
|
||||
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||
|
@ -73,10 +90,11 @@ struct KerxSubTableFormat0
|
|||
}
|
||||
|
||||
protected:
|
||||
KerxSubTableHeader header;
|
||||
BinSearchArrayOf<KernPair, HBUINT32>
|
||||
pairs; /* Sorted kern records. */
|
||||
pairs; /* Sorted kern records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (16, pairs);
|
||||
DEFINE_SIZE_ARRAY (28, pairs);
|
||||
};
|
||||
|
||||
struct KerxSubTableFormat1
|
||||
|
@ -85,6 +103,9 @@ struct KerxSubTableFormat1
|
|||
{
|
||||
TRACE_APPLY (this);
|
||||
|
||||
if (!c->plan->requested_kerning)
|
||||
return false;
|
||||
|
||||
/* TODO */
|
||||
|
||||
return_trace (true);
|
||||
|
@ -98,23 +119,24 @@ struct KerxSubTableFormat1
|
|||
}
|
||||
|
||||
protected:
|
||||
KerxSubTableHeader header;
|
||||
StateTable<HBUINT16> stateHeader;
|
||||
LOffsetTo<ArrayOf<HBUINT16> > valueTable;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (20);
|
||||
DEFINE_SIZE_STATIC (32);
|
||||
};
|
||||
|
||||
struct KerxSubTableFormat2
|
||||
{
|
||||
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 r = *(this+rightClassTable).get_value (right, num_glyphs);
|
||||
unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs);
|
||||
unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs);
|
||||
unsigned int offset = l + r;
|
||||
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
||||
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 *v;
|
||||
}
|
||||
|
@ -123,8 +145,10 @@ struct KerxSubTableFormat2
|
|||
{
|
||||
TRACE_APPLY (this);
|
||||
|
||||
if (!c->plan->requested_kerning)
|
||||
return false;
|
||||
|
||||
accelerator_t accel (*this,
|
||||
c->sanitizer.end,
|
||||
c->face->get_num_glyphs ());
|
||||
hb_kern_machine_t<accelerator_t> machine (accel);
|
||||
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||
|
@ -145,32 +169,31 @@ struct KerxSubTableFormat2
|
|||
struct accelerator_t
|
||||
{
|
||||
const KerxSubTableFormat2 &table;
|
||||
const char *end;
|
||||
unsigned int num_glyphs;
|
||||
|
||||
inline accelerator_t (const KerxSubTableFormat2 &table_,
|
||||
const char *end_, unsigned int num_glyphs_)
|
||||
: table (table_), end (end_), num_glyphs (num_glyphs_) {}
|
||||
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, end, num_glyphs);
|
||||
return table.get_kerning (left, right, num_glyphs);
|
||||
}
|
||||
};
|
||||
|
||||
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> >
|
||||
leftClassTable; /* Offset from beginning of this subtable to
|
||||
* left-hand class table. */
|
||||
leftClassTable; /* Offset from beginning of this subtable to
|
||||
* left-hand class table. */
|
||||
LOffsetTo<Lookup<HBUINT16> >
|
||||
rightClassTable;/* Offset from beginning of this subtable to
|
||||
* right-hand class table. */
|
||||
LOffsetTo<FWORD>
|
||||
array; /* Offset from beginning of this subtable to
|
||||
* the start of the kerning array. */
|
||||
rightClassTable;/* Offset from beginning of this subtable to
|
||||
* right-hand class table. */
|
||||
LOffsetTo<FWORD> array; /* Offset from beginning of this subtable to
|
||||
* the start of the kerning array. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
DEFINE_SIZE_STATIC (28);
|
||||
};
|
||||
|
||||
struct KerxSubTableFormat4
|
||||
|
@ -193,17 +216,60 @@ struct KerxSubTableFormat4
|
|||
}
|
||||
|
||||
protected:
|
||||
KerxSubTableHeader header;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (1);
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -212,30 +278,63 @@ struct KerxSubTableFormat6
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
rowIndexTable.sanitize (c, this) &&
|
||||
columnIndexTable.sanitize (c, this) &&
|
||||
kerningArray.sanitize (c, this) &&
|
||||
kerningVector.sanitize (c, this)));
|
||||
is_long () ?
|
||||
(
|
||||
u.l.rowIndexTable.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:
|
||||
HBUINT32 flags;
|
||||
HBUINT16 rowCount;
|
||||
HBUINT16 columnCount;
|
||||
LOffsetTo<Lookup<HBUINT16> > rowIndexTable;
|
||||
LOffsetTo<Lookup<HBUINT16> > columnIndexTable;
|
||||
LOffsetTo<Lookup<HBUINT16> > kerningArray;
|
||||
LOffsetTo<Lookup<HBUINT16> > kerningVector;
|
||||
KerxSubTableHeader header;
|
||||
HBUINT32 flags;
|
||||
HBUINT16 rowCount;
|
||||
HBUINT16 columnCount;
|
||||
union U
|
||||
{
|
||||
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:
|
||||
DEFINE_SIZE_STATIC (24);
|
||||
DEFINE_SIZE_STATIC (32);
|
||||
};
|
||||
|
||||
struct KerxTable
|
||||
{
|
||||
friend struct kerx;
|
||||
|
||||
inline unsigned int get_size (void) const { return length; }
|
||||
inline unsigned int get_type (void) const { return coverage & SubtableType; }
|
||||
inline unsigned int get_size (void) const { return u.header.length; }
|
||||
inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; }
|
||||
|
||||
enum Coverage
|
||||
{
|
||||
|
@ -269,19 +368,16 @@ struct KerxTable
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!length.sanitize (c) ||
|
||||
length < min_size ||
|
||||
!c->check_range (this, length))
|
||||
if (!u.header.sanitize (c) ||
|
||||
!c->check_range (this, u.header.length))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (dispatch (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT32 length;
|
||||
HBUINT32 coverage;
|
||||
HBUINT32 tupleCount;
|
||||
union {
|
||||
KerxSubTableHeader header;
|
||||
KerxSubTableFormat0 format0;
|
||||
KerxSubTableFormat1 format1;
|
||||
KerxSubTableFormat2 format2;
|
||||
|
@ -312,21 +408,22 @@ struct kerx
|
|||
{
|
||||
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) !=
|
||||
bool (table->coverage & KerxTable::Vertical))
|
||||
goto skip;
|
||||
bool (table->u.header.coverage & KerxTable::Vertical))
|
||||
goto skip;
|
||||
|
||||
if (table->coverage & KerxTable::CrossStream)
|
||||
goto skip; /* We do NOT handle cross-stream kerning. None of Apple fonts use it. */
|
||||
|
||||
reverse = bool (table->coverage & KerxTable::Backwards) !=
|
||||
reverse = bool (table->u.header.coverage & KerxTable::Backwards) !=
|
||||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
||||
|
||||
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
|
||||
goto skip;
|
||||
goto skip;
|
||||
|
||||
if (reverse)
|
||||
c->buffer->reverse ();
|
||||
c->buffer->reverse ();
|
||||
|
||||
c->sanitizer.set_object (*table);
|
||||
|
||||
|
@ -337,7 +434,7 @@ struct kerx
|
|||
table->dispatch (c);
|
||||
|
||||
if (reverse)
|
||||
c->buffer->reverse ();
|
||||
c->buffer->reverse ();
|
||||
|
||||
(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 ();
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
||||
hb_bool_t
|
||||
hb_aat_layout_has_positioning (hb_face_t *face)
|
||||
{
|
||||
return _get_kerx (face).has_data ();
|
||||
}
|
||||
|
||||
void
|
||||
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
#if 0
|
||||
hb_blob_t *blob;
|
||||
const AAT::ankr& ankr = _get_ankr (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);
|
||||
kerx.apply (&c, &ankr);
|
||||
trak.apply (&c);
|
||||
#endif
|
||||
AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
|
||||
kerx.apply (&c);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
|
|||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
hb_aat_layout_has_positioning (hb_face_t *face);
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
|
|
|
@ -47,8 +47,27 @@ _hb_options_init (void)
|
|||
u.i = 0;
|
||||
u.opts.initialized = 1;
|
||||
|
||||
char *c = getenv ("HB_OPTIONS");
|
||||
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
|
||||
const char *c = getenv ("HB_OPTIONS");
|
||||
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. */
|
||||
_hb_options.set_relaxed (u.i);
|
||||
|
|
|
@ -43,9 +43,10 @@
|
|||
|
||||
struct hb_options_t
|
||||
{
|
||||
unsigned int unused : 1; /* In-case sign bit is here. */
|
||||
unsigned int initialized : 1;
|
||||
unsigned int uniscribe_bug_compatible : 1;
|
||||
bool unused : 1; /* In-case sign bit is here. */
|
||||
bool initialized : 1;
|
||||
bool uniscribe_bug_compatible : 1;
|
||||
bool aat : 1;
|
||||
};
|
||||
|
||||
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_; }
|
||||
|
||||
/* 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>
|
||||
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. */
|
||||
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. */
|
||||
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
|
||||
{
|
||||
/* 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 r = (this+rightClassTable).get_class (right);
|
||||
unsigned int offset = l + r;
|
||||
|
@ -204,6 +210,7 @@ struct KernSubTableFormat2
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (true); /* Disabled. See above. */
|
||||
return_trace (rowWidth.sanitize (c) &&
|
||||
leftClassTable.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 void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
||||
|
@ -2562,6 +2620,39 @@ struct Extension
|
|||
* 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
|
||||
{
|
||||
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) {}
|
||||
|
||||
const OT::GSUB &table;
|
||||
const hb_ot_layout_lookup_accelerator_t *accels;
|
||||
const OT::hb_ot_layout_lookup_accelerator_t *accels;
|
||||
};
|
||||
|
||||
struct GPOSProxy
|
||||
|
@ -1108,63 +1108,13 @@ struct GPOSProxy
|
|||
accels (hb_ot_face_data (face)->GPOS->accels) {}
|
||||
|
||||
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
|
||||
apply_forward (OT::hb_ot_apply_context_t *c,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel,
|
||||
const hb_get_subtables_context_t::array_t &subtables)
|
||||
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||
{
|
||||
bool ret = false;
|
||||
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) &&
|
||||
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
||||
{
|
||||
for (unsigned int i = 0; i < subtables.len; i++)
|
||||
if (subtables[i].apply (c))
|
||||
{
|
||||
applied = true;
|
||||
break;
|
||||
}
|
||||
applied = accel.apply (c);
|
||||
}
|
||||
|
||||
if (applied)
|
||||
|
@ -1193,8 +1138,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
|
|||
|
||||
static inline bool
|
||||
apply_backward (OT::hb_ot_apply_context_t *c,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel,
|
||||
const hb_get_subtables_context_t::array_t &subtables)
|
||||
const OT::hb_ot_layout_lookup_accelerator_t &accel)
|
||||
{
|
||||
bool ret = false;
|
||||
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) &&
|
||||
c->check_glyph_property (&buffer->cur(), c->lookup_props))
|
||||
{
|
||||
for (unsigned int i = 0; i < subtables.len; i++)
|
||||
if (subtables[i].apply (c))
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
if (accel.apply (c))
|
||||
ret = true;
|
||||
}
|
||||
/* The reverse lookup doesn't "advance" cursor (for good reason). */
|
||||
buffer->idx--;
|
||||
|
@ -1223,7 +1163,7 @@ template <typename Proxy>
|
|||
static inline void
|
||||
apply_string (OT::hb_ot_apply_context_t *c,
|
||||
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;
|
||||
|
||||
|
@ -1232,10 +1172,6 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
|||
|
||||
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 ()))
|
||||
{
|
||||
/* in/out forward substitution/positioning */
|
||||
|
@ -1244,7 +1180,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
|||
buffer->idx = 0;
|
||||
|
||||
bool ret;
|
||||
ret = apply_forward (c, accel, subtables);
|
||||
ret = apply_forward (c, accel);
|
||||
if (ret)
|
||||
{
|
||||
if (!Proxy::inplace)
|
||||
|
@ -1260,7 +1196,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
|||
buffer->remove_output ();
|
||||
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
|
||||
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -112,32 +112,16 @@ hb_ot_layout_substitute_start (hb_font_t *font,
|
|||
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 {
|
||||
struct hb_ot_apply_context_t;
|
||||
struct SubstLookup;
|
||||
struct hb_ot_layout_lookup_accelerator_t;
|
||||
}
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||
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. */
|
||||
|
|
|
@ -201,7 +201,7 @@ struct arabic_fallback_plan_t
|
|||
|
||||
hb_mask_t mask_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)
|
||||
|
|
|
@ -460,6 +460,10 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
|||
hb_font_t *font,
|
||||
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_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver);
|
||||
machine.kern (font, buffer, plan->kern_mask);
|
||||
|
|
|
@ -42,6 +42,17 @@
|
|||
#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
|
||||
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
|
||||
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.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.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.kerning_requested = !!plan.kern_mask;
|
||||
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
|
||||
|
||||
plan.apply_morx = !hb_ot_layout_has_substitution (face) &&
|
||||
hb_aat_layout_has_substitution (face);
|
||||
hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
|
||||
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
|
||||
plan.kern_mask = plan.map.get_mask (kern_tag);
|
||||
|
||||
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 &&
|
||||
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;
|
||||
plan.fallback_mark_positioning = !plan.apply_gpos;
|
||||
plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
|
||||
|
||||
/*
|
||||
* Decide who provides glyph classes. GDEF or Unicode.
|
||||
*/
|
||||
|
||||
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...
|
||||
* If we are going to apply morx, choose default shaper. */
|
||||
if (!hb_ot_layout_has_substitution (planner.face) &&
|
||||
hb_aat_layout_has_substitution (planner.face))
|
||||
if (_hb_apply_morx (planner.face))
|
||||
planner.shaper = &_hb_ot_complex_shaper_default;
|
||||
else
|
||||
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)
|
||||
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)
|
||||
{
|
||||
|
@ -835,16 +879,12 @@ hb_ot_position (const hb_ot_shape_context_t *c)
|
|||
|
||||
/* Visual fallback goes here. */
|
||||
|
||||
if (!c->plan->kerning_requested)
|
||||
;
|
||||
else if (c->plan->apply_kern)
|
||||
if (c->plan->apply_kern)
|
||||
hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
|
||||
else if (c->plan->fallback_kerning)
|
||||
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
||||
|
||||
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
||||
|
||||
//hb_aat_layout_position (c->font, c->buffer);
|
||||
}
|
||||
|
||||
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 kern_mask;
|
||||
|
||||
bool requested_kerning : 1;
|
||||
bool has_frac : 1;
|
||||
bool kerning_requested : 1;
|
||||
bool has_gpos_mark : 1;
|
||||
bool fallback_glyph_classes : 1;
|
||||
bool fallback_kerning : 1;
|
||||
bool fallback_mark_positioning : 1;
|
||||
|
||||
bool apply_morx : 1;
|
||||
bool apply_kerx : 1;
|
||||
bool apply_kern : 1;
|
||||
bool apply_gpos : 1;
|
||||
|
||||
|
|
|
@ -39,9 +39,7 @@ HB_SHAPER_IMPLEMENT (graphite2)
|
|||
HB_SHAPER_IMPLEMENT (coretext_aat)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OT
|
||||
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISCRIBE
|
||||
HB_SHAPER_IMPLEMENT (uniscribe)
|
||||
|
|
|
@ -45,10 +45,8 @@
|
|||
|
||||
#include "hb.h"
|
||||
#define HB_H_IN
|
||||
#ifdef HAVE_OT
|
||||
#include "hb-ot.h"
|
||||
#define HB_OT_H_IN
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -73,14 +73,13 @@ test_unicode_LDADD += $(top_builddir)/src/libharfbuzz-icu.la $(ICU_LIBS)
|
|||
endif
|
||||
|
||||
|
||||
if HAVE_OT
|
||||
|
||||
TEST_PROGS += \
|
||||
test-ot-color \
|
||||
test-ot-tag \
|
||||
test-ot-extents-cff \
|
||||
$(NULL)
|
||||
|
||||
|
||||
if HAVE_PTHREAD
|
||||
if HAVE_FREETYPE
|
||||
TEST_PROGS += test-multithread
|
||||
|
@ -100,7 +99,6 @@ test_ot_math_LDADD = $(LDADD) $(FREETYPE_LIBS)
|
|||
test_ot_math_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
|
||||
endif # HAVE_FREETYPE
|
||||
|
||||
endif # HAVE_OT
|
||||
|
||||
# Tests for header compilation
|
||||
TEST_PROGS += \
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#endif
|
||||
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
#ifdef HAVE_GLIB
|
||||
#include <hb-glib.h>
|
||||
|
@ -45,10 +46,6 @@
|
|||
#include <hb-ft.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OT
|
||||
#include <hb-ot.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISCRIBE
|
||||
#include <hb-uniscribe.h>
|
||||
#endif
|
||||
|
|
|
@ -52,14 +52,11 @@ hb_subset_LDADD = \
|
|||
$(top_builddir)/src/libharfbuzz-subset.la
|
||||
bin_PROGRAMS += hb-subset
|
||||
|
||||
if HAVE_OT
|
||||
hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources)
|
||||
bin_PROGRAMS += hb-ot-shape-closure
|
||||
endif # HAVE_OT
|
||||
|
||||
endif # HAVE_GLIB
|
||||
|
||||
#if HAVE_OT
|
||||
#if HAVE_FONTCONFIG
|
||||
#hb_fc_list_SOURCES = \
|
||||
# hb-fc.cc \
|
||||
|
@ -72,6 +69,5 @@ endif # HAVE_GLIB
|
|||
# $(NULL)
|
||||
#bin_PROGRAMS += hb-fc-list
|
||||
#endif # HAVE_FONTCONFIG
|
||||
#endif # HAVE_OT
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
|
|
@ -29,9 +29,7 @@
|
|||
#ifdef HAVE_FREETYPE
|
||||
#include <hb-ft.h>
|
||||
#endif
|
||||
#ifdef HAVE_OT
|
||||
#include <hb-ot.h>
|
||||
#endif
|
||||
|
||||
static struct supported_font_funcs_t {
|
||||
char name[4];
|
||||
|
@ -41,9 +39,7 @@ static struct supported_font_funcs_t {
|
|||
#ifdef HAVE_FREETYPE
|
||||
{"ft", hb_ft_font_set_funcs},
|
||||
#endif
|
||||
#ifdef HAVE_OT
|
||||
{"ot", hb_ot_font_set_funcs},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -46,9 +46,7 @@
|
|||
#endif
|
||||
|
||||
#include <hb.h>
|
||||
#ifdef HAVE_OT
|
||||
#include <hb-ot.h>
|
||||
#endif
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
|
|
Loading…
Reference in New Issue