Merge branch 'expand-tests' of github.com:googlefonts/harfbuzz into drophints
This commit is contained in:
commit
c8b230e437
10
.ci/fail.sh
10
.ci/fail.sh
|
@ -2,11 +2,17 @@
|
|||
|
||||
for f in $(find . -name '*.log' -not -name 'config.log'); do
|
||||
last=$(tail -1 $f)
|
||||
if [[ $last = FAIL* || $last = *failed* ]]; then
|
||||
if [[ $last = FAIL* ]]; then
|
||||
echo '====' $f '===='
|
||||
cat $f
|
||||
elif [[ $last = PASS* ]]; then
|
||||
# Do nothing.
|
||||
true
|
||||
else
|
||||
# Travis Linux images has an old automake that does not match the
|
||||
# patterns above, so in case of doubt just print the file.
|
||||
cat $f
|
||||
fi
|
||||
done
|
||||
|
||||
# Intentionally exiting with non-zero.
|
||||
exit 1
|
||||
|
|
|
@ -37,6 +37,21 @@ jobs:
|
|||
- run: make
|
||||
- run: make check || .ci/fail.sh
|
||||
|
||||
clang-O3-O0:
|
||||
docker:
|
||||
- image: multiarch/crossbuild
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update && apt install -y ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j4 && cd ..
|
||||
- run: CFLAGS="-O3" CXXFLAGS="-O3" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh
|
||||
- run: CFLAGS="-O0" CXXFLAGS="-O0" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh
|
||||
|
||||
fedora-outoftreebuild:
|
||||
docker:
|
||||
- image: fedora
|
||||
|
@ -153,6 +168,7 @@ workflows:
|
|||
# autotools based builds
|
||||
- alpine-O3
|
||||
- archlinux-debug-O0
|
||||
- clang-O3-O0
|
||||
- fedora-outoftreebuild
|
||||
|
||||
# cmake based builds
|
||||
|
|
|
@ -6,8 +6,8 @@ language: cpp
|
|||
env:
|
||||
global:
|
||||
- CPPFLAGS=""
|
||||
- CFLAGS="-Werror --coverage"
|
||||
- CXXFLAGS="-Werror -Wno-deprecated-register --coverage" # glib uses register and clang raises a warning
|
||||
- CFLAGS="-Werror -Werror=unused-function --coverage"
|
||||
- CXXFLAGS="-Werror -Werror=unused-function -Wno-deprecated-register --coverage" # glib uses register and clang raises a warning
|
||||
- LDFLAGS="--coverage"
|
||||
- CONFIGURE_OPTS="--with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2"
|
||||
- NOCONFIGURE=1
|
||||
|
|
|
@ -137,7 +137,7 @@ set (IN_HB_DIST FALSE)
|
|||
if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
|
||||
# perhaps we are on dist directory
|
||||
set (IN_HB_DIST TRUE)
|
||||
set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
|
||||
#set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
|
||||
endif ()
|
||||
|
||||
|
||||
|
@ -180,13 +180,13 @@ add_prefix_to_list(HB_SUBSET_headers "${PROJECT_SOURCE_DIR}/src/")
|
|||
|
||||
extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES})
|
||||
extract_make_variable(HB_OT_RAGEL_GENERATED_sources ${SRCSOURCES})
|
||||
if (IN_HB_DIST)
|
||||
#if (IN_HB_DIST)
|
||||
add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
|
||||
add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/")
|
||||
else ()
|
||||
add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
|
||||
add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
|
||||
endif ()
|
||||
#else ()
|
||||
# add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
|
||||
# add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/")
|
||||
#endif ()
|
||||
|
||||
extract_make_variable(HB_VIEW_sources ${UTILSOURCES})
|
||||
add_prefix_to_list(HB_VIEW_sources "${PROJECT_SOURCE_DIR}/util/")
|
||||
|
@ -234,17 +234,17 @@ endif ()
|
|||
|
||||
|
||||
## Generate hb-version.h
|
||||
if (NOT IN_HB_DIST)
|
||||
set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
|
||||
set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
|
||||
set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
|
||||
configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${HB_VERSION_H}.tmp"
|
||||
"${HB_VERSION_H}"
|
||||
)
|
||||
file(REMOVE "${HB_VERSION_H}.tmp")
|
||||
endif ()
|
||||
#if (NOT IN_HB_DIST)
|
||||
# set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
|
||||
# set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
|
||||
# set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
|
||||
# configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
|
||||
# execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
# "${HB_VERSION_H}.tmp"
|
||||
# "${HB_VERSION_H}"
|
||||
# )
|
||||
# file(REMOVE "${HB_VERSION_H}.tmp")
|
||||
#endif ()
|
||||
|
||||
|
||||
## Define sources and headers of the project
|
||||
|
@ -264,7 +264,7 @@ set (subset_project_sources
|
|||
set (project_extra_sources)
|
||||
|
||||
set (project_headers
|
||||
${HB_VERSION_H}
|
||||
#${HB_VERSION_H}
|
||||
|
||||
${HB_BASE_headers}
|
||||
${HB_OT_headers}
|
||||
|
@ -809,7 +809,7 @@ endif ()
|
|||
|
||||
## src/ executables
|
||||
if (NOT HB_DISABLE_TEST_PROGS)
|
||||
foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag)
|
||||
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
|
||||
|
|
|
@ -30,7 +30,6 @@ HBDEPS =
|
|||
HBSOURCES = $(HB_BASE_sources)
|
||||
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
|
||||
HBHEADERS = $(HB_BASE_headers)
|
||||
HBNODISTHEADERS = $(HB_NODIST_headers)
|
||||
|
||||
if WITH_LIBSTDCXX
|
||||
HBNOLIBCXXCFLAGS =
|
||||
|
@ -147,13 +146,13 @@ endif
|
|||
|
||||
base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined
|
||||
libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS)
|
||||
libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS)
|
||||
libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS)
|
||||
libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS)
|
||||
libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols)
|
||||
libharfbuzz_la_LIBADD = $(HBLIBS)
|
||||
EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
|
||||
pkginclude_HEADERS = $(HBHEADERS)
|
||||
nodist_pkginclude_HEADERS = $(HBNODISTHEADERS)
|
||||
nodist_pkginclude_HEADERS =
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = harfbuzz.pc
|
||||
cmakedir = $(libdir)/cmake/harfbuzz
|
||||
|
@ -382,17 +381,21 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
|
|||
dump_use_data_CPPFLAGS = $(HBCFLAGS)
|
||||
dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
check_PROGRAMS += test-ot-tag
|
||||
TESTS += test-ot-tag
|
||||
check_PROGRAMS += test-ot-tag test-unicode-ranges
|
||||
TESTS += test-ot-tag test-unicode-ranges
|
||||
|
||||
test_ot_tag_SOURCES = hb-ot-tag.cc
|
||||
test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN
|
||||
test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_unicode_ranges_SOURCES = test-unicode-ranges.cc
|
||||
test_unicode_ranges_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
TESTS_ENVIRONMENT = \
|
||||
srcdir="$(srcdir)" \
|
||||
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
|
||||
HBSOURCES="$(HBSOURCES)" \
|
||||
HBHEADERS="$(HBHEADERS) $(HBNODISTHEADERS)" \
|
||||
HBHEADERS="$(HBHEADERS)" \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
|
@ -422,7 +425,6 @@ HarfBuzz_0_0_gir_LIBS = \
|
|||
$(NULL)
|
||||
HarfBuzz_0_0_gir_FILES = \
|
||||
$(HBHEADERS) \
|
||||
$(HBNODISTHEADERS) \
|
||||
$(HBSOURCES) \
|
||||
$(HB_GOBJECT_sources) \
|
||||
$(HB_GOBJECT_headers) \
|
||||
|
|
|
@ -28,6 +28,7 @@ HB_BASE_sources = \
|
|||
hb-ot-maxp-table.hh \
|
||||
hb-ot-name-table.hh \
|
||||
hb-ot-os2-table.hh \
|
||||
hb-ot-os2-unicode-ranges.hh \
|
||||
hb-ot-post-macroman.hh \
|
||||
hb-ot-post-table.hh \
|
||||
hb-ot-tag.cc \
|
||||
|
@ -70,9 +71,6 @@ HB_BASE_headers = \
|
|||
hb-shape.h \
|
||||
hb-shape-plan.h \
|
||||
hb-unicode.h \
|
||||
$(NULL)
|
||||
|
||||
HB_NODIST_headers = \
|
||||
hb-version.h \
|
||||
$(NULL)
|
||||
|
||||
|
@ -83,12 +81,14 @@ HB_FALLBACK_sources = \
|
|||
HB_OT_sources = \
|
||||
hb-aat-layout.cc \
|
||||
hb-aat-layout-common-private.hh \
|
||||
hb-aat-layout-morx-table.hh \
|
||||
hb-aat-layout-ankr-table.hh \
|
||||
hb-aat-layout-kerx-table.hh \
|
||||
hb-aat-layout-morx-table.hh \
|
||||
hb-aat-layout-trak-table.hh \
|
||||
hb-aat-layout-private.hh \
|
||||
hb-ot-font.cc \
|
||||
hb-ot-layout.cc \
|
||||
hb-ot-layout-base-table.hh \
|
||||
hb-ot-layout-common-private.hh \
|
||||
hb-ot-layout-gdef-table.hh \
|
||||
hb-ot-layout-gpos-table.hh \
|
||||
|
@ -152,6 +152,7 @@ HB_OT_headers = \
|
|||
hb-ot-font.h \
|
||||
hb-ot-layout.h \
|
||||
hb-ot-math.h \
|
||||
hb-ot-base.h \
|
||||
hb-ot-shape.h \
|
||||
hb-ot-tag.h \
|
||||
hb-ot-var.h \
|
||||
|
|
|
@ -9,14 +9,28 @@
|
|||
# $ cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild
|
||||
# $ src/dev-run.sh [FONT-FILE] [TEXT]
|
||||
#
|
||||
# If you are using iTerm2, issue the script like this:
|
||||
# $ src/dev-run.sh img [FONT-FILE] [TEXT]
|
||||
#
|
||||
|
||||
[ $# = 0 ] && echo Usage: "src/dev-run.sh [FONT-FILE] [TEXT]" && exit
|
||||
command -v entr >/dev/null 2>&1 || { echo >&2 "This script needs `entr` be installed"; exit 1; }
|
||||
|
||||
|
||||
GDB=gdb
|
||||
# if gdb doesn't exist, hopefully lldb exist
|
||||
command -v $GDB >/dev/null 2>&1 || export GDB="lldb"
|
||||
|
||||
|
||||
[ $1 = "img" ] && img=1 && shift
|
||||
# http://iterm2.com/documentation-images.html
|
||||
osc="\033]"
|
||||
if [[ $TERM == screen* ]]; then osc="\033Ptmux;\033\033]"; fi
|
||||
st="\a"
|
||||
if [[ $TERM == screen* ]]; then st="\a"; fi
|
||||
|
||||
|
||||
tmp=$(mktemp)
|
||||
[ -f 'build/build.ninja' ] && CMAKENINJA=TRUE
|
||||
# or "fswatch -0 . -e build/ -e .git"
|
||||
find src/ | entr printf '\0' | while read -d ""; do
|
||||
|
@ -25,19 +39,29 @@ find src/ | entr printf '\0' | while read -d ""; do
|
|||
if [[ $CMAKENINJA ]]; then
|
||||
ninja -Cbuild hb-shape hb-view && {
|
||||
build/hb-shape $@
|
||||
build/hb-view $@
|
||||
if [ $img ]; then
|
||||
build/hb-view $@ -O png -o $tmp
|
||||
printf "\n${osc}1337;File=;inline=1:`cat $tmp | base64`${st}\n"
|
||||
else
|
||||
build/hb-view $@
|
||||
fi
|
||||
}
|
||||
else
|
||||
make -Cbuild/src -j5 -s lib && {
|
||||
build/util/hb-shape $@
|
||||
build/util/hb-view $@
|
||||
if [ $img ]; then
|
||||
build/util/hb-view $@ -O png -o $tmp
|
||||
printf "\n${osc}1337;File=;inline=1:`cat $tmp | base64`${st}\n"
|
||||
else
|
||||
build/util/hb-view $@
|
||||
fi
|
||||
}
|
||||
fi
|
||||
done
|
||||
|
||||
read -n 1 -p "[T]est, [D]ebug, [R]estart, [Q]uit?" answer
|
||||
read -n 1 -p "[C]heck, [D]ebug, [R]estart, [Q]uit? " answer
|
||||
case "$answer" in
|
||||
t|T )
|
||||
c|C )
|
||||
if [[ $CMAKENINJA ]]; then
|
||||
CTEST_OUTPUT_ON_FAILURE=1 CTEST_PARALLEL_LEVEL=5 ninja -Cbuild test
|
||||
else
|
||||
|
@ -48,7 +72,7 @@ d|D )
|
|||
if [[ $CMAKENINJA ]]; then
|
||||
echo "Not supported on cmake builds yet"
|
||||
else
|
||||
build/libtool --mode=execute $GDB build/util/hb-shape $@
|
||||
build/libtool --mode=execute $GDB -- build/util/hb-shape $@
|
||||
fi
|
||||
;;
|
||||
r|R )
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh
|
||||
# Input is a tab seperated list of unicode ranges from the otspec
|
||||
# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1).
|
||||
|
||||
import io
|
||||
import re
|
||||
import sys
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
print (u"""static Range os2UnicodeRangesSorted[] =
|
||||
{""")
|
||||
|
||||
args = sys.argv[1:]
|
||||
input_file = args[0]
|
||||
|
||||
with io.open(input_file, mode="r", encoding="utf-8") as f:
|
||||
|
||||
all_ranges = [];
|
||||
current_bit = 0
|
||||
while True:
|
||||
line = f.readline().strip()
|
||||
if not line:
|
||||
break
|
||||
fields = re.split(r'\t+', line)
|
||||
if len(fields) == 3:
|
||||
current_bit = fields[0]
|
||||
fields = fields[1:]
|
||||
elif len(fields) > 3:
|
||||
raise Error("bad input :(.")
|
||||
|
||||
name = fields[0]
|
||||
ranges = re.split("-", fields[1])
|
||||
if len(ranges) != 2:
|
||||
raise Error("bad input :(.")
|
||||
|
||||
v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name))
|
||||
all_ranges.append(v)
|
||||
|
||||
all_ranges = sorted(all_ranges, key=lambda t: t[0])
|
||||
|
||||
for ranges in all_ranges:
|
||||
start = ("0x%X" % ranges[0]).rjust(8)
|
||||
end = ("0x%X" % ranges[1]).rjust(8)
|
||||
bit = ("%s" % ranges[2]).rjust(3)
|
||||
|
||||
print " {%s, %s, %s}, // %s" % (start, end, bit, ranges[3])
|
||||
|
||||
print (u"""};""");
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
|
||||
#ifndef HB_AAT_LAYOUT_ANKR_TABLE_HH
|
||||
#define HB_AAT_LAYOUT_ANKR_TABLE_HH
|
||||
|
||||
#include "hb-aat-layout-common-private.hh"
|
||||
|
||||
#define HB_AAT_TAG_ankr HB_TAG('a','n','k','r')
|
||||
|
||||
|
||||
namespace AAT {
|
||||
|
||||
|
||||
/*
|
||||
* ankr -- Anchor point
|
||||
*/
|
||||
|
||||
struct Anchor
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
FWORD xCoordinate;
|
||||
FWORD yCoordinate;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct ankr
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_AAT_TAG_ankr;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && version == 0 &&
|
||||
lookupTable.sanitize (c, this) &&
|
||||
anchors.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 version; /* Version number (set to zero) */
|
||||
HBUINT16 flags; /* Flags (currently unused; set to zero) */
|
||||
LOffsetTo<Lookup<HBUINT16> > lookupTable; /* Offset to the table's lookup table */
|
||||
LOffsetTo<ArrayOf<Anchor, HBUINT32> >
|
||||
anchors; /* Offset to the glyph data table */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
} /* namespace AAT */
|
||||
|
||||
|
||||
#endif /* HB_AAT_LAYOUT_ANKR_TABLE_HH */
|
|
@ -263,6 +263,13 @@ struct kerx
|
|||
{
|
||||
static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
|
||||
|
||||
inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
/* TODO */
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
struct SubTableWrapper
|
||||
{
|
||||
enum coverage_flags_t {
|
||||
|
|
|
@ -37,4 +37,7 @@
|
|||
HB_INTERNAL void
|
||||
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
#endif /* HB_AAT_LAYOUT_PRIVATE_HH */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2018 Google, Inc.
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2018 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
|
@ -39,16 +39,26 @@ namespace AAT {
|
|||
|
||||
struct TrackTableEntry
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base, unsigned int size) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
return_trace (c->check_struct (this) && (values.sanitize (c, base, size)));
|
||||
}
|
||||
|
||||
inline float get_track_value () const
|
||||
{
|
||||
return track.to_float ();
|
||||
}
|
||||
|
||||
inline int get_value (const void *base, unsigned int index) const
|
||||
{
|
||||
return (base+values)[index];
|
||||
}
|
||||
|
||||
protected:
|
||||
Fixed track; /* Track value for this record. */
|
||||
HBUINT16 trackNameID; /* The 'name' table index for this track */
|
||||
OffsetTo<UnsizedArrayOf<Fixed> >
|
||||
OffsetTo<UnsizedArrayOf<FWORD> >
|
||||
values; /* Offset from start of tracking table to
|
||||
* per-size tracking values for this track. */
|
||||
|
||||
|
@ -58,18 +68,66 @@ struct TrackTableEntry
|
|||
|
||||
struct TrackData
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
return_trace (c->check_struct (this) &&
|
||||
sizeTable.sanitize (c, base, nSizes) &&
|
||||
trackTable.sanitize (c, nTracks, base, nSizes));
|
||||
}
|
||||
|
||||
inline float get_tracking (const void *base, float ptem) const
|
||||
{
|
||||
/* CoreText points are CSS pixels (96 per inch),
|
||||
* NOT typographic points (72 per inch).
|
||||
*
|
||||
* https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
|
||||
*/
|
||||
float csspx = ptem * 96.f / 72.f;
|
||||
Fixed fixed_size;
|
||||
fixed_size.set_float (csspx);
|
||||
|
||||
/* XXX Clean this up. Make it work with nSizes==1 and 0. */
|
||||
|
||||
unsigned int sizes = nSizes;
|
||||
|
||||
const TrackTableEntry *trackTableEntry = nullptr;
|
||||
for (unsigned int i = 0; i < sizes; ++i)
|
||||
// For now we only seek for track entries with zero tracking value
|
||||
if (trackTable[i].get_track_value () == 0.)
|
||||
trackTableEntry = &trackTable[0];
|
||||
|
||||
// We couldn't match any, exit
|
||||
if (!trackTableEntry) return 0.;
|
||||
|
||||
/* TODO bfind() */
|
||||
unsigned int size_index;
|
||||
UnsizedArrayOf<Fixed> size_table = base+sizeTable;
|
||||
for (size_index = 0; size_index < sizes; ++size_index)
|
||||
if (size_table[size_index] >= fixed_size)
|
||||
break;
|
||||
|
||||
// TODO(ebraminio): We don't attempt to extrapolate to larger or
|
||||
// smaller values for now but we should do, per spec
|
||||
if (size_index == sizes)
|
||||
return trackTableEntry->get_value (base, sizes - 1);
|
||||
if (size_index == 0 || size_table[size_index] == fixed_size)
|
||||
return trackTableEntry->get_value (base, size_index);
|
||||
|
||||
float s0 = size_table[size_index - 1].to_float ();
|
||||
float s1 = size_table[size_index].to_float ();
|
||||
float t = (csspx - s0) / (s1 - s0);
|
||||
return t * trackTableEntry->get_value (base, size_index) +
|
||||
(1.0 - t) * trackTableEntry->get_value (base, size_index - 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
||||
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
||||
LOffsetTo<UnsizedArrayOf<Fixed> >
|
||||
LOffsetTo<UnsizedArrayOf<Fixed> > /* Offset to array[nSizes] of size values. */
|
||||
sizeTable;
|
||||
TrackTableEntry trackTable[VAR];/* Array[nSizes] of size values. */
|
||||
UnsizedArrayOf<TrackTableEntry>
|
||||
trackTable; /* Array[nTracks] of TrackTableEntry records. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, trackTable);
|
||||
|
@ -82,15 +140,55 @@ struct trak
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
|
||||
return_trace (c->check_struct (this) &&
|
||||
horizData.sanitize (c, this, this) &&
|
||||
vertData.sanitize (c, this, this));
|
||||
}
|
||||
|
||||
inline bool apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
|
||||
const float ptem = c->font->ptem;
|
||||
if (ptem <= 0.f)
|
||||
return_trace (false);
|
||||
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
||||
{
|
||||
const TrackData &trackData = this+horizData;
|
||||
float tracking = trackData.get_tracking (this, ptem);
|
||||
hb_position_t advance_to_add = c->font->em_scalef_x (tracking / 2);
|
||||
foreach_grapheme (buffer, start, end)
|
||||
{
|
||||
/* TODO This is wrong. */
|
||||
buffer->pos[start].x_advance += advance_to_add;
|
||||
buffer->pos[end].x_advance += advance_to_add;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const TrackData &trackData = this+vertData;
|
||||
float tracking = trackData.get_tracking (this, ptem);
|
||||
hb_position_t advance_to_add = c->font->em_scalef_y (tracking / 2);
|
||||
foreach_grapheme (buffer, start, end)
|
||||
{
|
||||
/* TODO This is wrong. */
|
||||
buffer->pos[start].y_advance += advance_to_add;
|
||||
buffer->pos[end].y_advance += advance_to_add;
|
||||
}
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<> version; /* Version of the tracking table--currently
|
||||
* 0x00010000u for version 1.0. */
|
||||
HBUINT16 format; /* Format of the tracking table */
|
||||
OffsetTo<TrackData> horizOffset; /* TrackData for horizontal text */
|
||||
OffsetTo<TrackData> vertOffset; /* TrackData for vertical text */
|
||||
OffsetTo<TrackData> horizData; /* TrackData for horizontal text */
|
||||
OffsetTo<TrackData> vertData; /* TrackData for vertical text */
|
||||
HBUINT16 reserved; /* Reserved. Set to 0. */
|
||||
|
||||
public:
|
||||
|
|
|
@ -30,14 +30,48 @@
|
|||
#include "hb-ot-layout-gsubgpos-private.hh"
|
||||
|
||||
#include "hb-aat-layout-private.hh"
|
||||
#include "hb-aat-layout-morx-table.hh"
|
||||
#include "hb-aat-layout-ankr-table.hh"
|
||||
#include "hb-aat-layout-kerx-table.hh"
|
||||
#include "hb-aat-layout-morx-table.hh"
|
||||
#include "hb-aat-layout-trak-table.hh"
|
||||
|
||||
/*
|
||||
* mort/morx
|
||||
* morx/kerx/trak
|
||||
*/
|
||||
|
||||
static inline const AAT::ankr&
|
||||
_get_ankr (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 OT::Null(AAT::ankr);
|
||||
}
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
const AAT::ankr& ankr = *(layout->ankr.get ());
|
||||
if (blob)
|
||||
*blob = layout->ankr.blob;
|
||||
return ankr;
|
||||
}
|
||||
|
||||
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 OT::Null(AAT::kerx);
|
||||
}
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
/* XXX this doesn't call set_num_glyphs on sanitizer. */
|
||||
const AAT::kerx& kerx = *(layout->kerx.get ());
|
||||
if (blob)
|
||||
*blob = layout->kerx.blob;
|
||||
return kerx;
|
||||
}
|
||||
|
||||
static inline const AAT::morx&
|
||||
_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||
{
|
||||
|
@ -55,20 +89,36 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
|||
return morx;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_aat_layout_create (hb_face_t *face)
|
||||
static inline const AAT::trak&
|
||||
_get_trak (hb_face_t *face, hb_blob_t **blob = nullptr)
|
||||
{
|
||||
OT::Sanitizer<AAT::morx> sanitizer;
|
||||
sanitizer.set_num_glyphs (face->get_num_glyphs ());
|
||||
hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX));
|
||||
OT::Sanitizer<AAT::morx>::lock_instance (morx_blob);
|
||||
|
||||
if (0)
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
|
||||
{
|
||||
OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ());
|
||||
if (blob)
|
||||
*blob = hb_blob_get_empty ();
|
||||
return OT::Null(AAT::trak);
|
||||
}
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
const AAT::trak& trak = *(layout->trak.get ());
|
||||
if (blob)
|
||||
*blob = layout->trak.blob;
|
||||
return trak;
|
||||
}
|
||||
|
||||
// static inline void
|
||||
// _hb_aat_layout_create (hb_face_t *face)
|
||||
// {
|
||||
// OT::Sanitizer<AAT::morx> sanitizer;
|
||||
// sanitizer.set_num_glyphs (face->get_num_glyphs ());
|
||||
// hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX));
|
||||
// OT::Sanitizer<AAT::morx>::lock_instance (morx_blob);
|
||||
|
||||
// if (0)
|
||||
// {
|
||||
// OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ());
|
||||
// }
|
||||
// }
|
||||
|
||||
void
|
||||
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
|
@ -78,3 +128,16 @@ hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
|
|||
AAT::hb_aat_apply_context_t c (font, buffer, blob);
|
||||
morx.apply (&c);
|
||||
}
|
||||
|
||||
void
|
||||
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -692,8 +692,8 @@ struct F2DOT14 : HBINT16
|
|||
/* 32-bit signed fixed-point number (16.16). */
|
||||
struct Fixed: HBINT32
|
||||
{
|
||||
//inline float to_float (void) const { return ???; }
|
||||
//inline void set_float (float f) { v.set (f * ???); }
|
||||
inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
|
||||
inline void set_float (float f) { v.set (round (f * 65536.0)); }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
@ -740,8 +740,6 @@ template <typename Type>
|
|||
struct Offset : Type
|
||||
{
|
||||
inline bool is_null (void) const { return 0 == *this; }
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (sizeof(Type));
|
||||
|
||||
inline void *serialize (hb_serialize_context_t *c, const void *base)
|
||||
{
|
||||
|
@ -749,6 +747,9 @@ struct Offset : Type
|
|||
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
|
||||
return t;
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (sizeof(Type));
|
||||
};
|
||||
|
||||
typedef Offset<HBUINT16> Offset16;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright © 2017 Elie Roux<elie.roux@telecom-bretagne.eu>
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_BASE_H
|
||||
#define HB_OT_BASE_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
|
||||
|
||||
// https://www.microsoft.com/typography/otspec/baselinetags.htm
|
||||
|
||||
#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g')
|
||||
#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b')
|
||||
#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t')
|
||||
#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o')
|
||||
#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b')
|
||||
#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h')
|
||||
#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n')
|
||||
|
||||
/* Methods */
|
||||
|
||||
// HB_EXTERN hb_bool_t
|
||||
// hb_ot_base_has_data (hb_face_t *face);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_BASE_H */
|
|
@ -0,0 +1,656 @@
|
|||
/*
|
||||
* Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
|
||||
* Copyright © 2018 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_BASE_TABLE_HH
|
||||
#define HB_OT_LAYOUT_BASE_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-ot-layout-common-private.hh"
|
||||
#include "hb-ot-base.h"
|
||||
|
||||
namespace OT {
|
||||
|
||||
#define NOT_INDEXED ((unsigned int) -1)
|
||||
|
||||
/*
|
||||
* BASE -- The BASE Table
|
||||
*/
|
||||
|
||||
struct BaseCoordFormat1
|
||||
{
|
||||
inline int get_coord (void) const { return coordinate; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
HBINT16 coordinate; /* X or Y value, in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct BaseCoordFormat2
|
||||
{
|
||||
inline int get_coord (void) const
|
||||
{
|
||||
/* TODO */
|
||||
return coordinate;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
HBINT16 coordinate; /* X or Y value, in design units */
|
||||
GlyphID referenceGlyph; /* Glyph ID of control glyph */
|
||||
HBUINT16 coordPoint; /* Index of contour point on the
|
||||
* reference glyph */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct BaseCoordFormat3
|
||||
{
|
||||
inline int get_coord (void) const
|
||||
{
|
||||
/* TODO */
|
||||
return coordinate;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 3 */
|
||||
HBINT16 coordinate; /* X or Y value, in design units */
|
||||
OffsetTo<Device> deviceTable; /* Offset to Device table for X or
|
||||
* Y value, from beginning of
|
||||
* BaseCoord table (may be NULL). */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct BaseCoord
|
||||
{
|
||||
inline int get_coord (void) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_coord ();
|
||||
case 2: return u.format2.get_coord ();
|
||||
case 3: return u.format3.get_coord ();
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
case 2: return_trace (u.format2.sanitize (c));
|
||||
case 3: return_trace (u.format3.sanitize (c));
|
||||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format;
|
||||
BaseCoordFormat1 format1;
|
||||
BaseCoordFormat2 format2;
|
||||
BaseCoordFormat3 format3;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
struct FeatMinMaxRecord
|
||||
{
|
||||
inline int get_min_value (void) const
|
||||
{ return (this+minCoord).get_coord(); }
|
||||
|
||||
inline int get_max_value (void) const
|
||||
{ return (this+maxCoord).get_coord(); }
|
||||
|
||||
inline const Tag &get_tag () const
|
||||
{ return tag; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
minCoord.sanitize (c, base) &&
|
||||
maxCoord.sanitize (c, base));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag tag; /* 4-byte feature identification tag--must
|
||||
* match feature tag in FeatureList */
|
||||
OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines
|
||||
* the minimum extent value, from beginning
|
||||
* of MinMax table (may be NULL) */
|
||||
OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines
|
||||
* the maximum extent value, from beginning
|
||||
* of MinMax table (may be NULL) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
|
||||
};
|
||||
|
||||
struct MinMax
|
||||
{
|
||||
inline unsigned int get_feature_tag_index (Tag featureTableTag) const
|
||||
{
|
||||
/* TODO bsearch */
|
||||
unsigned int count = featMinMaxRecords.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
Tag tag = featMinMaxRecords[i].get_tag();
|
||||
int cmp = tag.cmp(featureTableTag);
|
||||
if (cmp == 0) return i;
|
||||
if (cmp > 0) return NOT_INDEXED;
|
||||
}
|
||||
return NOT_INDEXED;
|
||||
}
|
||||
|
||||
inline int get_min_value (unsigned int featureTableTagIndex) const
|
||||
{
|
||||
if (featureTableTagIndex == NOT_INDEXED)
|
||||
return (this+minCoord).get_coord();
|
||||
return featMinMaxRecords[featureTableTagIndex].get_min_value();
|
||||
}
|
||||
|
||||
inline int get_max_value (unsigned int featureTableTagIndex) const
|
||||
{
|
||||
if (featureTableTagIndex == NOT_INDEXED)
|
||||
return (this+maxCoord).get_coord();
|
||||
return featMinMaxRecords[featureTableTagIndex].get_max_value();
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
minCoord.sanitize (c, this) &&
|
||||
maxCoord.sanitize (c, this) &&
|
||||
featMinMaxRecords.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines
|
||||
* minimum extent value, from the beginning
|
||||
* of MinMax table (may be NULL) */
|
||||
OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines
|
||||
* maximum extent value, from the beginning
|
||||
* of MinMax table (may be NULL) */
|
||||
ArrayOf<FeatMinMaxRecord>
|
||||
featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical
|
||||
* order by featureTableTag */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
|
||||
};
|
||||
|
||||
/* TODO... */
|
||||
struct BaseLangSysRecord
|
||||
{
|
||||
inline const Tag& get_tag(void) const
|
||||
{ return baseLangSysTag; }
|
||||
|
||||
inline unsigned int get_feature_tag_index (Tag featureTableTag) const
|
||||
{ return (this+minMax).get_feature_tag_index(featureTableTag); }
|
||||
|
||||
inline int get_min_value (unsigned int featureTableTagIndex) const
|
||||
{ return (this+minMax).get_min_value(featureTableTagIndex); }
|
||||
|
||||
inline int get_max_value (unsigned int featureTableTagIndex) const
|
||||
{ return (this+minMax).get_max_value(featureTableTagIndex); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
minMax.sanitize (c, base));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag baseLangSysTag;
|
||||
OffsetTo<MinMax> minMax;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
|
||||
};
|
||||
|
||||
struct BaseValues
|
||||
{
|
||||
inline unsigned int get_default_base_tag_index (void) const
|
||||
{ return defaultIndex; }
|
||||
|
||||
inline int get_base_coord (unsigned int baselineTagIndex) const
|
||||
{
|
||||
return (this+baseCoords[baselineTagIndex]).get_coord();
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
defaultIndex <= baseCoordCount &&
|
||||
baseCoords.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Index defaultIndex;
|
||||
HBUINT16 baseCoordCount;
|
||||
OffsetArrayOf<BaseCoord> baseCoords;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, baseCoords);
|
||||
|
||||
};
|
||||
|
||||
struct BaseScript {
|
||||
|
||||
inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
|
||||
{
|
||||
Tag tag;
|
||||
int cmp;
|
||||
for (unsigned int i = 0; i < baseLangSysCount; i++) {
|
||||
tag = baseLangSysRecords[i].get_tag();
|
||||
// taking advantage of alphabetical order
|
||||
cmp = tag.cmp(baseLangSysTag);
|
||||
if (cmp == 0) return i;
|
||||
if (cmp > 0) return NOT_INDEXED;
|
||||
}
|
||||
return NOT_INDEXED;
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{
|
||||
if (baseLangSysIndex == NOT_INDEXED) {
|
||||
if (unlikely(defaultMinMax)) return NOT_INDEXED;
|
||||
return (this+defaultMinMax).get_feature_tag_index(featureTableTag);
|
||||
}
|
||||
if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED;
|
||||
return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag);
|
||||
}
|
||||
|
||||
inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
if (baseLangSysIndex == NOT_INDEXED)
|
||||
return (this+defaultMinMax).get_min_value(featureTableTagIndex);
|
||||
return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
if (baseLangSysIndex == NOT_INDEXED)
|
||||
return (this+defaultMinMax).get_min_value(featureTableTagIndex);
|
||||
return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline unsigned int get_default_base_tag_index (void) const
|
||||
{ return (this+baseValues).get_default_base_tag_index(); }
|
||||
|
||||
inline int get_base_coord (unsigned int baselineTagIndex) const
|
||||
{ return (this+baseValues).get_base_coord(baselineTagIndex); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
baseValues.sanitize (c, this) &&
|
||||
defaultMinMax.sanitize (c, this) &&
|
||||
baseLangSysRecords.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<BaseValues> baseValues;
|
||||
OffsetTo<MinMax> defaultMinMax;
|
||||
HBUINT16 baseLangSysCount;
|
||||
ArrayOf<BaseLangSysRecord> baseLangSysRecords;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
|
||||
};
|
||||
|
||||
|
||||
struct BaseScriptRecord {
|
||||
|
||||
inline const Tag& get_tag (void) const
|
||||
{ return baseScriptTag; }
|
||||
|
||||
inline unsigned int get_default_base_tag_index(void) const
|
||||
{ return (this+baseScript).get_default_base_tag_index(); }
|
||||
|
||||
inline int get_base_coord(unsigned int baselineTagIndex) const
|
||||
{ return (this+baseScript).get_base_coord(baselineTagIndex); }
|
||||
|
||||
inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
|
||||
{ return (this+baseScript).get_lang_tag_index(baseLangSysTag); }
|
||||
|
||||
inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{ return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); }
|
||||
|
||||
inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{ return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); }
|
||||
|
||||
inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{ return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
baseScript != Null(OffsetTo<BaseScript>) &&
|
||||
baseScript.sanitize (c, base));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag baseScriptTag;
|
||||
OffsetTo<BaseScript> baseScript;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct BaseScriptList {
|
||||
|
||||
inline unsigned int get_base_script_index (Tag baseScriptTag) const
|
||||
{
|
||||
for (unsigned int i = 0; i < baseScriptCount; i++)
|
||||
if (baseScriptRecords[i].get_tag() == baseScriptTag)
|
||||
return i;
|
||||
return NOT_INDEXED;
|
||||
}
|
||||
|
||||
inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const
|
||||
{
|
||||
if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
|
||||
return baseScriptRecords[baseScriptIndex].get_default_base_tag_index();
|
||||
}
|
||||
|
||||
inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
|
||||
{
|
||||
return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex);
|
||||
}
|
||||
|
||||
inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
|
||||
{
|
||||
if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
|
||||
return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{
|
||||
if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
|
||||
return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag);
|
||||
}
|
||||
|
||||
inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
baseScriptRecords.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 baseScriptCount;
|
||||
ArrayOf<BaseScriptRecord> baseScriptRecords;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, baseScriptRecords);
|
||||
|
||||
};
|
||||
|
||||
struct BaseTagList
|
||||
{
|
||||
|
||||
inline unsigned int get_tag_index(Tag baselineTag) const
|
||||
{
|
||||
for (unsigned int i = 0; i < baseTagCount; i++)
|
||||
if (baselineTags[i] == baselineTag)
|
||||
return i;
|
||||
return NOT_INDEXED;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 baseTagCount;
|
||||
SortedArrayOf<Tag> baselineTags;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, baselineTags);
|
||||
};
|
||||
|
||||
struct Axis
|
||||
{
|
||||
|
||||
inline unsigned int get_base_tag_index(Tag baselineTag) const
|
||||
{
|
||||
if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED;
|
||||
return (this+baseTagList).get_tag_index(baselineTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
|
||||
{
|
||||
if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
|
||||
return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex);
|
||||
}
|
||||
|
||||
inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
|
||||
{
|
||||
return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex);
|
||||
}
|
||||
|
||||
inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
|
||||
{
|
||||
if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
|
||||
return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{
|
||||
if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
|
||||
return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag);
|
||||
}
|
||||
|
||||
inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
baseTagList.sanitize (c, this) &&
|
||||
baseScriptList.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<BaseTagList> baseTagList;
|
||||
OffsetTo<BaseScriptList> baseScriptList;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct BASE
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_BASE;
|
||||
|
||||
inline bool has_vert_axis(void)
|
||||
{ return vertAxis != Null(OffsetTo<Axis>); }
|
||||
|
||||
inline bool has_horiz_axis(void)
|
||||
{ return horizAxis != Null(OffsetTo<Axis>); }
|
||||
|
||||
// horizontal axis base coords:
|
||||
|
||||
inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const
|
||||
{
|
||||
if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+horizAxis).get_base_tag_index(baselineTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
|
||||
{
|
||||
if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
|
||||
}
|
||||
|
||||
inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
|
||||
{
|
||||
return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
|
||||
}
|
||||
|
||||
// vertical axis base coords:
|
||||
|
||||
inline unsigned int get_vert_base_tag_index(Tag baselineTag) const
|
||||
{
|
||||
if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+vertAxis).get_base_tag_index(baselineTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
|
||||
{
|
||||
if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
|
||||
}
|
||||
|
||||
inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
|
||||
{
|
||||
return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
|
||||
}
|
||||
|
||||
// horizontal axis min/max coords:
|
||||
|
||||
inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
|
||||
{
|
||||
if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{
|
||||
if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
|
||||
}
|
||||
|
||||
inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
// vertical axis min/max coords:
|
||||
|
||||
inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
|
||||
{
|
||||
if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
|
||||
}
|
||||
|
||||
inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
|
||||
{
|
||||
if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
|
||||
return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
|
||||
}
|
||||
|
||||
inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
|
||||
{
|
||||
return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (version.major == 1) &&
|
||||
horizAxis.sanitize (c, this) &&
|
||||
vertAxis.sanitize (c, this) &&
|
||||
(version.to_int () < 0x00010001u || varStore.sanitize (c, this)));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<> version;
|
||||
OffsetTo<Axis> horizAxis;
|
||||
OffsetTo<Axis> vertAxis;
|
||||
LOffsetTo<VariationStore>
|
||||
varStore; /* Offset to the table of Item Variation
|
||||
* Store--from beginning of BASE
|
||||
* header (may be NULL). Introduced
|
||||
* in version 0x00010001. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
|
|
@ -110,7 +110,7 @@ struct CaretValueFormat1
|
|||
|
||||
protected:
|
||||
HBUINT16 caretValueFormat; /* Format identifier--format = 1 */
|
||||
HBINT16 coordinate; /* X or Y value, in design units */
|
||||
FWORD coordinate; /* X or Y value, in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
@ -161,7 +161,7 @@ struct CaretValueFormat3
|
|||
|
||||
protected:
|
||||
HBUINT16 caretValueFormat; /* Format identifier--format = 3 */
|
||||
HBINT16 coordinate; /* X or Y value, in design units */
|
||||
FWORD coordinate; /* X or Y value, in design units */
|
||||
OffsetTo<Device>
|
||||
deviceTable; /* Offset to Device table for X or Y
|
||||
* value--from beginning of CaretValue
|
||||
|
|
|
@ -248,8 +248,8 @@ struct AnchorFormat1
|
|||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
HBINT16 xCoordinate; /* Horizontal value--in design units */
|
||||
HBINT16 yCoordinate; /* Vertical value--in design units */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
@ -279,8 +279,8 @@ struct AnchorFormat2
|
|||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
HBINT16 xCoordinate; /* Horizontal value--in design units */
|
||||
HBINT16 yCoordinate; /* Vertical value--in design units */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
HBUINT16 anchorPoint; /* Index to glyph contour point */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
|
@ -309,8 +309,8 @@ struct AnchorFormat3
|
|||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 3 */
|
||||
HBINT16 xCoordinate; /* Horizontal value--in design units */
|
||||
HBINT16 yCoordinate; /* Vertical value--in design units */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
OffsetTo<Device>
|
||||
xDeviceTable; /* Offset to Device table for X
|
||||
* coordinate-- from beginning of
|
||||
|
|
|
@ -114,7 +114,7 @@ struct SingleSubstFormat1
|
|||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of Substitution table */
|
||||
HBINT16 deltaGlyphID; /* Add to original GlyphID to get
|
||||
HBINT16 deltaGlyphID; /* Add to original GlyphID to get
|
||||
* substitute GlyphID */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
|
|
|
@ -122,6 +122,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font,
|
|||
*/
|
||||
|
||||
namespace OT {
|
||||
struct BASE;
|
||||
struct GDEF;
|
||||
struct GSUB;
|
||||
struct GPOS;
|
||||
|
@ -131,8 +132,9 @@ namespace OT {
|
|||
}
|
||||
|
||||
namespace AAT {
|
||||
struct morx;
|
||||
struct ankr;
|
||||
struct kerx;
|
||||
struct morx;
|
||||
struct trak;
|
||||
}
|
||||
|
||||
|
@ -168,11 +170,13 @@ struct hb_ot_layout_t
|
|||
const struct OT::GPOS *gpos;
|
||||
|
||||
/* TODO Move the following out of this struct. */
|
||||
OT::hb_lazy_table_loader_t<struct OT::BASE> base;
|
||||
OT::hb_lazy_table_loader_t<struct OT::MATH> math;
|
||||
OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
|
||||
OT::hb_lazy_table_loader_t<struct OT::avar> avar;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
|
||||
OT::hb_lazy_table_loader_t<struct AAT::trak> trak;
|
||||
|
||||
unsigned int gsub_lookup_count;
|
||||
|
@ -363,6 +367,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
|||
return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Loop over grapheme. Based on foreach_cluster(). */
|
||||
#define foreach_grapheme(buffer, start, end) \
|
||||
for (unsigned int \
|
||||
_count = buffer->len, \
|
||||
start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \
|
||||
start < _count; \
|
||||
start = end, end = _next_grapheme (buffer, start))
|
||||
|
||||
static inline unsigned int
|
||||
_next_grapheme (hb_buffer_t *buffer, unsigned int start)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start]))
|
||||
;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
#define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
|
||||
|
||||
static inline bool
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "hb-open-type-private.hh"
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
#include "hb-ot-layout-base-table.hh"
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
#include "hb-ot-layout-gpos-table.hh"
|
||||
|
@ -62,9 +63,13 @@ _hb_ot_layout_create (hb_face_t *face)
|
|||
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
|
||||
|
||||
layout->math.init (face);
|
||||
layout->base.init (face);
|
||||
layout->fvar.init (face);
|
||||
layout->avar.init (face);
|
||||
layout->ankr.init (face);
|
||||
layout->kerx.init (face);
|
||||
layout->morx.init (face);
|
||||
layout->trak.init (face);
|
||||
|
||||
{
|
||||
/*
|
||||
|
@ -212,13 +217,25 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
|||
hb_blob_destroy (layout->gpos_blob);
|
||||
|
||||
layout->math.fini ();
|
||||
layout->base.fini ();
|
||||
layout->fvar.fini ();
|
||||
layout->avar.fini ();
|
||||
layout->ankr.fini ();
|
||||
layout->kerx.fini ();
|
||||
layout->morx.fini ();
|
||||
layout->trak.fini ();
|
||||
|
||||
free (layout);
|
||||
}
|
||||
|
||||
// static inline const OT::BASE&
|
||||
// _get_base (hb_face_t *face)
|
||||
// {
|
||||
// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
|
||||
// hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
// return *(layout->base.get ());
|
||||
// }
|
||||
|
||||
static inline const OT::GDEF&
|
||||
_get_gdef (hb_face_t *face)
|
||||
{
|
||||
|
@ -1264,3 +1281,27 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
|||
{
|
||||
apply_string<GSUBProxy> (c, lookup, accel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* OT::BASE
|
||||
*/
|
||||
|
||||
// /**
|
||||
// * hb_ot_base_has_data:
|
||||
// * @face: #hb_face_t to test
|
||||
// *
|
||||
// * This function allows to verify the presence of an OpenType BASE table on the
|
||||
// * face.
|
||||
// *
|
||||
// * Return value: true if face has a BASE table, false otherwise
|
||||
// *
|
||||
// * Since: XXX
|
||||
// **/
|
||||
// hb_bool_t
|
||||
// hb_ot_base_has_data (hb_face_t *face)
|
||||
// {
|
||||
// return &_get_base (face) != &OT::Null(OT::BASE);
|
||||
// }
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
|
||||
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
|
||||
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
|
||||
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
|
||||
|
|
|
@ -39,9 +39,39 @@ namespace OT {
|
|||
|
||||
#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
|
||||
|
||||
struct maxpV1Tail
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
HBUINT16 maxPoints; /* Maximum points in a non-composite glyph. */
|
||||
HBUINT16 maxContours; /* Maximum contours in a non-composite glyph. */
|
||||
HBUINT16 maxCompositePoints; /* Maximum points in a composite glyph. */
|
||||
HBUINT16 maxCompositeContours; /* Maximum contours in a composite glyph. */
|
||||
HBUINT16 maxZones; /* 1 if instructions do not use the twilight zone (Z0),
|
||||
* or 2 if instructions do use Z0; should be set to 2 in
|
||||
* most cases. */
|
||||
HBUINT16 maxTwilightPoints; /* Maximum points used in Z0. */
|
||||
HBUINT16 maxStorage; /* Number of Storage Area locations. */
|
||||
HBUINT16 maxFunctionDefs; /* Number of FDEFs, equal to the highest function number + 1. */
|
||||
HBUINT16 maxInstructionDefs; /* Number of IDEFs. */
|
||||
HBUINT16 maxStackElements; /* Maximum stack depth. (This includes Font and CVT
|
||||
* Programs, as well as the instructions for each glyph.) */
|
||||
HBUINT16 maxSizeOfInstructions; /* Maximum byte count for glyph instructions. */
|
||||
HBUINT16 maxComponentElements; /* Maximum number of components referenced at
|
||||
* "top level" for any composite glyph. */
|
||||
HBUINT16 maxComponentDepth; /* Maximum levels of recursion; 1 for simple components. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (26);
|
||||
};
|
||||
|
||||
|
||||
struct maxp
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_maxp;
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_maxp;
|
||||
|
||||
inline unsigned int get_num_glyphs (void) const
|
||||
{
|
||||
|
@ -56,9 +86,15 @@ struct maxp
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (version.major == 1 ||
|
||||
(version.major == 0 && version.minor == 0x5000u)));
|
||||
if (unlikely (!c->check_struct (this)))
|
||||
return_trace (false);
|
||||
|
||||
if (version.major == 1)
|
||||
{
|
||||
const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this);
|
||||
return v1.sanitize (c);
|
||||
}
|
||||
return_trace (likely (version.major == 0 && version.minor == 0x5000u));
|
||||
}
|
||||
|
||||
inline bool subset (hb_subset_plan_t *plan) const
|
||||
|
@ -73,17 +109,34 @@ struct maxp
|
|||
OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
|
||||
|
||||
maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
|
||||
if (plan->drop_hints)
|
||||
drop_hint_fields (plan, maxp_prime);
|
||||
|
||||
bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob);
|
||||
hb_blob_destroy (maxp_prime_blob);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
|
||||
static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime)
|
||||
{
|
||||
if (maxp_prime->version.major == 1)
|
||||
{
|
||||
maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime);
|
||||
v1.maxZones.set (1);
|
||||
v1.maxTwilightPoints.set (0);
|
||||
v1.maxStorage.set (0);
|
||||
v1.maxFunctionDefs.set (0);
|
||||
v1.maxInstructionDefs.set (0);
|
||||
v1.maxStackElements.set (0);
|
||||
v1.maxSizeOfInstructions.set (0);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
|
||||
* 0x00005000u or 0x00010000u. */
|
||||
HBUINT16 numGlyphs; /* The number of glyphs in the font. */
|
||||
/*maxpV1Tail v1Tail[VAR]; */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define HB_OT_OS2_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
#include "hb-ot-os2-unicode-ranges.hh"
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
@ -67,11 +67,40 @@ struct os2
|
|||
os2_prime->usFirstCharIndex.set (min_cp);
|
||||
os2_prime->usLastCharIndex.set (max_cp);
|
||||
|
||||
_update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange);
|
||||
bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob);
|
||||
|
||||
hb_blob_destroy (os2_prime_blob);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
|
||||
HBUINT32 ulUnicodeRange[4]) const
|
||||
{
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
ulUnicodeRange[i].set (0);
|
||||
|
||||
for (unsigned int i = 0; i < codepoints.len; i++)
|
||||
{
|
||||
hb_codepoint_t cp = codepoints[i];
|
||||
unsigned int bit = hb_get_unicode_range_bit (cp);
|
||||
if (bit < 128)
|
||||
{
|
||||
unsigned int block = bit / 32;
|
||||
unsigned int bit_in_block = bit % 32;
|
||||
unsigned int mask = 1 << bit_in_block;
|
||||
ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
|
||||
}
|
||||
if (cp >= 0x10000 && cp <= 0x110000)
|
||||
{
|
||||
/* the spec says that bit 57 ("Non Plane 0") implies that there's
|
||||
at least one codepoint beyond the BMP; so I also include all
|
||||
the non-BMP codepoints here */
|
||||
ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
|
||||
uint16_t *min_cp, /* OUT */
|
||||
uint16_t *max_cp /* OUT */)
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright © 2018 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Garret Rieger
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_OS2_UNICODE_RANGES_HH
|
||||
#define HB_OT_OS2_UNICODE_RANGES_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-dsalgs.hh"
|
||||
|
||||
namespace OT {
|
||||
|
||||
struct Range {
|
||||
hb_codepoint_t start;
|
||||
hb_codepoint_t end;
|
||||
unsigned int bit;
|
||||
};
|
||||
|
||||
/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */
|
||||
static Range os2UnicodeRangesSorted[] =
|
||||
{
|
||||
{ 0x0, 0x7F, 0}, // Basic Latin
|
||||
{ 0x80, 0xFF, 1}, // Latin-1 Supplement
|
||||
{ 0x100, 0x17F, 2}, // Latin Extended-A
|
||||
{ 0x180, 0x24F, 3}, // Latin Extended-B
|
||||
{ 0x250, 0x2AF, 4}, // IPA Extensions
|
||||
{ 0x2B0, 0x2FF, 5}, // Spacing Modifier Letters
|
||||
{ 0x300, 0x36F, 6}, // Combining Diacritical Marks
|
||||
{ 0x370, 0x3FF, 7}, // Greek and Coptic
|
||||
{ 0x400, 0x4FF, 9}, // Cyrillic
|
||||
{ 0x500, 0x52F, 9}, // Cyrillic Supplement
|
||||
{ 0x530, 0x58F, 10}, // Armenian
|
||||
{ 0x590, 0x5FF, 11}, // Hebrew
|
||||
{ 0x600, 0x6FF, 13}, // Arabic
|
||||
{ 0x700, 0x74F, 71}, // Syriac
|
||||
{ 0x750, 0x77F, 13}, // Arabic Supplement
|
||||
{ 0x780, 0x7BF, 72}, // Thaana
|
||||
{ 0x7C0, 0x7FF, 14}, // NKo
|
||||
{ 0x900, 0x97F, 15}, // Devanagari
|
||||
{ 0x980, 0x9FF, 16}, // Bengali
|
||||
{ 0xA00, 0xA7F, 17}, // Gurmukhi
|
||||
{ 0xA80, 0xAFF, 18}, // Gujarati
|
||||
{ 0xB00, 0xB7F, 19}, // Oriya
|
||||
{ 0xB80, 0xBFF, 20}, // Tamil
|
||||
{ 0xC00, 0xC7F, 21}, // Telugu
|
||||
{ 0xC80, 0xCFF, 22}, // Kannada
|
||||
{ 0xD00, 0xD7F, 23}, // Malayalam
|
||||
{ 0xD80, 0xDFF, 73}, // Sinhala
|
||||
{ 0xE00, 0xE7F, 24}, // Thai
|
||||
{ 0xE80, 0xEFF, 25}, // Lao
|
||||
{ 0xF00, 0xFFF, 70}, // Tibetan
|
||||
{ 0x1000, 0x109F, 74}, // Myanmar
|
||||
{ 0x10A0, 0x10FF, 26}, // Georgian
|
||||
{ 0x1100, 0x11FF, 28}, // Hangul Jamo
|
||||
{ 0x1200, 0x137F, 75}, // Ethiopic
|
||||
{ 0x1380, 0x139F, 75}, // Ethiopic Supplement
|
||||
{ 0x13A0, 0x13FF, 76}, // Cherokee
|
||||
{ 0x1400, 0x167F, 77}, // Unified Canadian Aboriginal Syllabics
|
||||
{ 0x1680, 0x169F, 78}, // Ogham
|
||||
{ 0x16A0, 0x16FF, 79}, // Runic
|
||||
{ 0x1700, 0x171F, 84}, // Tagalog
|
||||
{ 0x1720, 0x173F, 84}, // Hanunoo
|
||||
{ 0x1740, 0x175F, 84}, // Buhid
|
||||
{ 0x1760, 0x177F, 84}, // Tagbanwa
|
||||
{ 0x1780, 0x17FF, 80}, // Khmer
|
||||
{ 0x1800, 0x18AF, 81}, // Mongolian
|
||||
{ 0x1900, 0x194F, 93}, // Limbu
|
||||
{ 0x1950, 0x197F, 94}, // Tai Le
|
||||
{ 0x1980, 0x19DF, 95}, // New Tai Lue
|
||||
{ 0x19E0, 0x19FF, 80}, // Khmer Symbols
|
||||
{ 0x1A00, 0x1A1F, 96}, // Buginese
|
||||
{ 0x1B00, 0x1B7F, 27}, // Balinese
|
||||
{ 0x1B80, 0x1BBF, 112}, // Sundanese
|
||||
{ 0x1C00, 0x1C4F, 113}, // Lepcha
|
||||
{ 0x1C50, 0x1C7F, 114}, // Ol Chiki
|
||||
{ 0x1D00, 0x1D7F, 4}, // Phonetic Extensions
|
||||
{ 0x1D80, 0x1DBF, 4}, // Phonetic Extensions Supplement
|
||||
{ 0x1DC0, 0x1DFF, 6}, // Combining Diacritical Marks Supplement
|
||||
{ 0x1E00, 0x1EFF, 29}, // Latin Extended Additional
|
||||
{ 0x1F00, 0x1FFF, 30}, // Greek Extended
|
||||
{ 0x2000, 0x206F, 31}, // General Punctuation
|
||||
{ 0x2070, 0x209F, 32}, // Superscripts And Subscripts
|
||||
{ 0x20A0, 0x20CF, 33}, // Currency Symbols
|
||||
{ 0x20D0, 0x20FF, 34}, // Combining Diacritical Marks For Symbols
|
||||
{ 0x2100, 0x214F, 35}, // Letterlike Symbols
|
||||
{ 0x2150, 0x218F, 36}, // Number Forms
|
||||
{ 0x2190, 0x21FF, 37}, // Arrows
|
||||
{ 0x2200, 0x22FF, 38}, // Mathematical Operators
|
||||
{ 0x2300, 0x23FF, 39}, // Miscellaneous Technical
|
||||
{ 0x2400, 0x243F, 40}, // Control Pictures
|
||||
{ 0x2440, 0x245F, 41}, // Optical Character Recognition
|
||||
{ 0x2460, 0x24FF, 42}, // Enclosed Alphanumerics
|
||||
{ 0x2500, 0x257F, 43}, // Box Drawing
|
||||
{ 0x2580, 0x259F, 44}, // Block Elements
|
||||
{ 0x25A0, 0x25FF, 45}, // Geometric Shapes
|
||||
{ 0x2600, 0x26FF, 46}, // Miscellaneous Symbols
|
||||
{ 0x2700, 0x27BF, 47}, // Dingbats
|
||||
{ 0x27C0, 0x27EF, 38}, // Miscellaneous Mathematical Symbols-A
|
||||
{ 0x27F0, 0x27FF, 37}, // Supplemental Arrows-A
|
||||
{ 0x2800, 0x28FF, 82}, // Braille Patterns
|
||||
{ 0x2900, 0x297F, 37}, // Supplemental Arrows-B
|
||||
{ 0x2980, 0x29FF, 38}, // Miscellaneous Mathematical Symbols-B
|
||||
{ 0x2A00, 0x2AFF, 38}, // Supplemental Mathematical Operators
|
||||
{ 0x2B00, 0x2BFF, 37}, // Miscellaneous Symbols and Arrows
|
||||
{ 0x2C00, 0x2C5F, 97}, // Glagolitic
|
||||
{ 0x2C60, 0x2C7F, 29}, // Latin Extended-C
|
||||
{ 0x2C80, 0x2CFF, 8}, // Coptic
|
||||
{ 0x2D00, 0x2D2F, 26}, // Georgian Supplement
|
||||
{ 0x2D30, 0x2D7F, 98}, // Tifinagh
|
||||
{ 0x2D80, 0x2DDF, 75}, // Ethiopic Extended
|
||||
{ 0x2DE0, 0x2DFF, 9}, // Cyrillic Extended-A
|
||||
{ 0x2E00, 0x2E7F, 31}, // Supplemental Punctuation
|
||||
{ 0x2E80, 0x2EFF, 59}, // CJK Radicals Supplement
|
||||
{ 0x2F00, 0x2FDF, 59}, // Kangxi Radicals
|
||||
{ 0x2FF0, 0x2FFF, 59}, // Ideographic Description Characters
|
||||
{ 0x3000, 0x303F, 48}, // CJK Symbols And Punctuation
|
||||
{ 0x3040, 0x309F, 49}, // Hiragana
|
||||
{ 0x30A0, 0x30FF, 50}, // Katakana
|
||||
{ 0x3100, 0x312F, 51}, // Bopomofo
|
||||
{ 0x3130, 0x318F, 52}, // Hangul Compatibility Jamo
|
||||
{ 0x3190, 0x319F, 59}, // Kanbun
|
||||
{ 0x31A0, 0x31BF, 51}, // Bopomofo Extended
|
||||
{ 0x31C0, 0x31EF, 61}, // CJK Strokes
|
||||
{ 0x31F0, 0x31FF, 50}, // Katakana Phonetic Extensions
|
||||
{ 0x3200, 0x32FF, 54}, // Enclosed CJK Letters And Months
|
||||
{ 0x3300, 0x33FF, 55}, // CJK Compatibility
|
||||
{ 0x3400, 0x4DBF, 59}, // CJK Unified Ideographs Extension A
|
||||
{ 0x4DC0, 0x4DFF, 99}, // Yijing Hexagram Symbols
|
||||
{ 0x4E00, 0x9FFF, 59}, // CJK Unified Ideographs
|
||||
{ 0xA000, 0xA48F, 83}, // Yi Syllables
|
||||
{ 0xA490, 0xA4CF, 83}, // Yi Radicals
|
||||
{ 0xA500, 0xA63F, 12}, // Vai
|
||||
{ 0xA640, 0xA69F, 9}, // Cyrillic Extended-B
|
||||
{ 0xA700, 0xA71F, 5}, // Modifier Tone Letters
|
||||
{ 0xA720, 0xA7FF, 29}, // Latin Extended-D
|
||||
{ 0xA800, 0xA82F, 100}, // Syloti Nagri
|
||||
{ 0xA840, 0xA87F, 53}, // Phags-pa
|
||||
{ 0xA880, 0xA8DF, 115}, // Saurashtra
|
||||
{ 0xA900, 0xA92F, 116}, // Kayah Li
|
||||
{ 0xA930, 0xA95F, 117}, // Rejang
|
||||
{ 0xAA00, 0xAA5F, 118}, // Cham
|
||||
{ 0xAC00, 0xD7AF, 56}, // Hangul Syllables
|
||||
{ 0xD800, 0xDFFF, 57}, // Non-Plane 0 *
|
||||
{ 0xE000, 0xF8FF, 60}, // Private Use Area (plane 0)
|
||||
{ 0xF900, 0xFAFF, 61}, // CJK Compatibility Ideographs
|
||||
{ 0xFB00, 0xFB4F, 62}, // Alphabetic Presentation Forms
|
||||
{ 0xFB50, 0xFDFF, 63}, // Arabic Presentation Forms-A
|
||||
{ 0xFE00, 0xFE0F, 91}, // Variation Selectors
|
||||
{ 0xFE10, 0xFE1F, 65}, // Vertical Forms
|
||||
{ 0xFE20, 0xFE2F, 64}, // Combining Half Marks
|
||||
{ 0xFE30, 0xFE4F, 65}, // CJK Compatibility Forms
|
||||
{ 0xFE50, 0xFE6F, 66}, // Small Form Variants
|
||||
{ 0xFE70, 0xFEFF, 67}, // Arabic Presentation Forms-B
|
||||
{ 0xFF00, 0xFFEF, 68}, // Halfwidth And Fullwidth Forms
|
||||
{ 0xFFF0, 0xFFFF, 69}, // Specials
|
||||
{ 0x10000, 0x1007F, 101}, // Linear B Syllabary
|
||||
{ 0x10080, 0x100FF, 101}, // Linear B Ideograms
|
||||
{ 0x10100, 0x1013F, 101}, // Aegean Numbers
|
||||
{ 0x10140, 0x1018F, 102}, // Ancient Greek Numbers
|
||||
{ 0x10190, 0x101CF, 119}, // Ancient Symbols
|
||||
{ 0x101D0, 0x101FF, 120}, // Phaistos Disc
|
||||
{ 0x10280, 0x1029F, 121}, // Lycian
|
||||
{ 0x102A0, 0x102DF, 121}, // Carian
|
||||
{ 0x10300, 0x1032F, 85}, // Old Italic
|
||||
{ 0x10330, 0x1034F, 86}, // Gothic
|
||||
{ 0x10380, 0x1039F, 103}, // Ugaritic
|
||||
{ 0x103A0, 0x103DF, 104}, // Old Persian
|
||||
{ 0x10400, 0x1044F, 87}, // Deseret
|
||||
{ 0x10450, 0x1047F, 105}, // Shavian
|
||||
{ 0x10480, 0x104AF, 106}, // Osmanya
|
||||
{ 0x10800, 0x1083F, 107}, // Cypriot Syllabary
|
||||
{ 0x10900, 0x1091F, 58}, // Phoenician
|
||||
{ 0x10920, 0x1093F, 121}, // Lydian
|
||||
{ 0x10A00, 0x10A5F, 108}, // Kharoshthi
|
||||
{ 0x12000, 0x123FF, 110}, // Cuneiform
|
||||
{ 0x12400, 0x1247F, 110}, // Cuneiform Numbers and Punctuation
|
||||
{ 0x1D000, 0x1D0FF, 88}, // Byzantine Musical Symbols
|
||||
{ 0x1D100, 0x1D1FF, 88}, // Musical Symbols
|
||||
{ 0x1D200, 0x1D24F, 88}, // Ancient Greek Musical Notation
|
||||
{ 0x1D300, 0x1D35F, 109}, // Tai Xuan Jing Symbols
|
||||
{ 0x1D360, 0x1D37F, 111}, // Counting Rod Numerals
|
||||
{ 0x1D400, 0x1D7FF, 89}, // Mathematical Alphanumeric Symbols
|
||||
{ 0x1F000, 0x1F02F, 122}, // Mahjong Tiles
|
||||
{ 0x1F030, 0x1F09F, 122}, // Domino Tiles
|
||||
{ 0x20000, 0x2A6DF, 59}, // CJK Unified Ideographs Extension B
|
||||
{ 0x2F800, 0x2FA1F, 61}, // CJK Compatibility Ideographs Supplement
|
||||
{ 0xE0000, 0xE007F, 92}, // Tags
|
||||
{ 0xE0100, 0xE01EF, 91}, // Variation Selectors Supplement
|
||||
{ 0xF0000, 0xFFFFD, 90}, // Private Use (plane 15)
|
||||
{0x100000, 0x10FFFD, 90}, // Private Use (plane 16)
|
||||
};
|
||||
|
||||
static int
|
||||
_compare_range (const void *_key, const void *_item, void *_arg)
|
||||
{
|
||||
hb_codepoint_t cp = *((hb_codepoint_t *) _key);
|
||||
const Range *range = (Range *) _item;
|
||||
|
||||
if (cp < range->start)
|
||||
return -1;
|
||||
else if (cp <= range->end)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_get_unicode_range_bit:
|
||||
* Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint.
|
||||
**/
|
||||
static unsigned int
|
||||
hb_get_unicode_range_bit (hb_codepoint_t cp)
|
||||
{
|
||||
Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted,
|
||||
sizeof (os2UnicodeRangesSorted) / sizeof(Range),
|
||||
sizeof(Range),
|
||||
_compare_range, nullptr);
|
||||
if (range != NULL)
|
||||
return range->bit;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
#endif /* HB_OT_OS2_UNICODE_RANGES_HH */
|
|
@ -787,6 +787,8 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
|||
_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
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "hb-ot-font.h"
|
||||
#include "hb-ot-layout.h"
|
||||
#include "hb-ot-math.h"
|
||||
#include "hb-ot-base.h"
|
||||
#include "hb-ot-tag.h"
|
||||
#include "hb-ot-shape.h"
|
||||
#include "hb-ot-var.h"
|
||||
|
|
|
@ -136,7 +136,7 @@ _hb_subset_face_data_destroy (void *user_data)
|
|||
{
|
||||
hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
|
||||
|
||||
for (int i = 0; i < data->tables.len; i++)
|
||||
for (unsigned int i = 0; i < data->tables.len; i++)
|
||||
hb_blob_destroy (data->tables[i].blob);
|
||||
|
||||
data->tables.finish ();
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright © 2011 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_VERSION_H
|
||||
#define HB_VERSION_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_VERSION_MAJOR 1
|
||||
#define HB_VERSION_MINOR 7
|
||||
#define HB_VERSION_MICRO 5
|
||||
|
||||
#define HB_VERSION_STRING "1.7.5"
|
||||
|
||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_version (unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *micro);
|
||||
|
||||
HB_EXTERN const char *
|
||||
hb_version_string (void);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_version_atleast (unsigned int major,
|
||||
unsigned int minor,
|
||||
unsigned int micro);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_VERSION_H */
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright © 2018 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Garret Rieger
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-os2-unicode-ranges.hh"
|
||||
|
||||
void
|
||||
test (hb_codepoint_t cp, int bit)
|
||||
{
|
||||
if (OT::hb_get_unicode_range_bit (cp) != bit)
|
||||
{
|
||||
fprintf (stderr, "got incorrect bit (%d) for cp 0x%X. Should have been %d.",
|
||||
OT::hb_get_unicode_range_bit (cp),
|
||||
cp,
|
||||
bit);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_get_unicode_range_bit (void)
|
||||
{
|
||||
test (0x0000, 0);
|
||||
test (0x0042, 0);
|
||||
test (0x007F, 0);
|
||||
test (0x0080, 1);
|
||||
|
||||
test (0x30A0, 50);
|
||||
test (0x30B1, 50);
|
||||
test (0x30FF, 50);
|
||||
|
||||
test (0x10FFFD, 90);
|
||||
|
||||
test (0x30000, -1);
|
||||
test (0x110000, -1);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
test_get_unicode_range_bit ();
|
||||
return 0;
|
||||
}
|
|
@ -121,15 +121,16 @@ test_set_basic (void)
|
|||
hb_set_destroy (s);
|
||||
}
|
||||
|
||||
static inline void
|
||||
print_set (hb_set_t *s)
|
||||
{
|
||||
hb_codepoint_t next;
|
||||
printf ("{");
|
||||
for (next = HB_SET_VALUE_INVALID; hb_set_next (s, &next); )
|
||||
printf ("%d, ", next);
|
||||
printf ("}\n");
|
||||
}
|
||||
|
||||
// static inline void
|
||||
// print_set (hb_set_t *s)
|
||||
// {
|
||||
// hb_codepoint_t next;
|
||||
// printf ("{");
|
||||
// for (next = HB_SET_VALUE_INVALID; hb_set_next (s, &next); )
|
||||
// printf ("%d, ", next);
|
||||
// printf ("}\n");
|
||||
// }
|
||||
|
||||
static void
|
||||
test_set_algebra (void)
|
||||
|
|
|
@ -31,14 +31,30 @@
|
|||
|
||||
/* Unit tests for hb-subset-glyf.h */
|
||||
|
||||
static void check_maxp_num_glyphs (hb_face_t *face, uint16_t expected_num_glyphs)
|
||||
static void check_maxp_field (uint8_t *raw_maxp, unsigned int offset, uint16_t expected_value)
|
||||
{
|
||||
uint16_t actual_value = (raw_maxp[offset] << 8) + raw_maxp[offset + 1];
|
||||
g_assert_cmpuint(expected_value, ==, actual_value);
|
||||
}
|
||||
|
||||
static void check_maxp_num_glyphs (hb_face_t *face, uint16_t expected_num_glyphs, bool hints)
|
||||
{
|
||||
hb_blob_t *maxp_blob = hb_face_reference_table (face, HB_TAG ('m','a','x', 'p'));
|
||||
|
||||
unsigned int maxp_len;
|
||||
uint8_t *raw_maxp = (uint8_t *) hb_blob_get_data(maxp_blob, &maxp_len);
|
||||
uint16_t num_glyphs = (raw_maxp[4] << 8) + raw_maxp[5];
|
||||
g_assert_cmpuint(expected_num_glyphs, ==, num_glyphs);
|
||||
|
||||
check_maxp_field (raw_maxp, 4, expected_num_glyphs); // numGlyphs
|
||||
if (!hints)
|
||||
{
|
||||
check_maxp_field (raw_maxp, 14, 1); // maxZones
|
||||
check_maxp_field (raw_maxp, 16, 0); // maxTwilightPoints
|
||||
check_maxp_field (raw_maxp, 18, 0); // maxStorage
|
||||
check_maxp_field (raw_maxp, 20, 0); // maxFunctionDefs
|
||||
check_maxp_field (raw_maxp, 22, 0); // maxInstructionDefs
|
||||
check_maxp_field (raw_maxp, 24, 0); // maxStackElements
|
||||
check_maxp_field (raw_maxp, 26, 0); // maxSizeOfInstructions
|
||||
}
|
||||
|
||||
hb_blob_destroy (maxp_blob);
|
||||
}
|
||||
|
@ -57,7 +73,7 @@ test_subset_glyf (void)
|
|||
|
||||
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
|
||||
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
|
||||
check_maxp_num_glyphs(face_abc_subset, 3);
|
||||
check_maxp_num_glyphs(face_abc_subset, 3, true);
|
||||
|
||||
hb_face_destroy (face_abc_subset);
|
||||
hb_face_destroy (face_abc);
|
||||
|
@ -77,7 +93,7 @@ test_subset_glyf_with_components (void)
|
|||
|
||||
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
|
||||
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('l','o','c', 'a'));
|
||||
check_maxp_num_glyphs(face_generated_subset, 4);
|
||||
check_maxp_num_glyphs(face_generated_subset, 4, true);
|
||||
|
||||
hb_face_destroy (face_generated_subset);
|
||||
hb_face_destroy (face_subset);
|
||||
|
@ -98,7 +114,7 @@ test_subset_glyf_noop (void)
|
|||
|
||||
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
|
||||
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('l','o','c', 'a'));
|
||||
check_maxp_num_glyphs(face_abc_subset, 4);
|
||||
check_maxp_num_glyphs(face_abc_subset, 4, true);
|
||||
|
||||
hb_face_destroy (face_abc_subset);
|
||||
hb_face_destroy (face_abc);
|
||||
|
@ -120,7 +136,7 @@ test_subset_glyf_strip_hints_simple (void)
|
|||
|
||||
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
|
||||
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
|
||||
check_maxp_num_glyphs(face_abc_subset, 3);
|
||||
check_maxp_num_glyphs(face_abc_subset, 3, false);
|
||||
|
||||
hb_face_destroy (face_abc_subset);
|
||||
hb_face_destroy (face_abc);
|
||||
|
|
|
@ -8,6 +8,7 @@ SUBDIRS =
|
|||
EXTRA_DIST = \
|
||||
$(TESTS) \
|
||||
expected/basics \
|
||||
expected/full-font \
|
||||
fonts \
|
||||
profiles \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
TESTS = \
|
||||
tests/basics.tests \
|
||||
tests/full-font.tests \
|
||||
$(NULL)
|
||||
|
||||
XFAIL_TESTS = \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
--no-hinting
|
|
@ -3,6 +3,11 @@ Roboto-Regular.abc.ttf
|
|||
|
||||
PROFILES:
|
||||
default.txt
|
||||
drop-hints.txt
|
||||
|
||||
SUBSETS:
|
||||
abc
|
||||
b
|
||||
c
|
||||
ac
|
||||
a
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
FONTS:
|
||||
Roboto-Regular.ttf
|
||||
|
||||
PROFILES:
|
||||
default.txt
|
||||
drop-hints.txt
|
||||
|
||||
SUBSETS:
|
||||
abc
|
||||
Ǽ!A bc
|
||||
|
|
@ -15,12 +15,17 @@ def usage():
|
|||
print "Usage: generate-expected-outputs.py <test suite file> ..."
|
||||
|
||||
|
||||
def generate_expected_output(input_file, unicodes, output_path):
|
||||
check_call(["fonttools", "subset",
|
||||
input_file,
|
||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
|
||||
"--unicodes=%s" % unicodes,
|
||||
"--output-file=%s" % output_path])
|
||||
def generate_expected_output(input_file, unicodes, profile_flags, output_path):
|
||||
args = ["fonttools", "subset", input_file]
|
||||
args.extend(profile_flags)
|
||||
args.extend(["--notdef-outline",
|
||||
"--name-IDs=*",
|
||||
"--name-languages=*",
|
||||
"--name-legacy",
|
||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
|
||||
"--unicodes=%s" % unicodes,
|
||||
"--output-file=%s" % output_path])
|
||||
check_call(args)
|
||||
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
@ -37,6 +42,6 @@ for path in args:
|
|||
unicodes = test.unicodes()
|
||||
font_name = test.get_font_name()
|
||||
print "Creating subset %s/%s" % (output_directory, font_name)
|
||||
generate_expected_output(test.font_path, unicodes,
|
||||
os.path.join(output_directory,
|
||||
font_name))
|
||||
generate_expected_output(test.font_path, unicodes, test.get_profile_flags(),
|
||||
os.path.join(output_directory,
|
||||
font_name))
|
||||
|
|
|
@ -44,6 +44,7 @@ def run_test(test):
|
|||
"--font-file=" + test.font_path,
|
||||
"--output-file=" + out_file,
|
||||
"--unicodes=%s" % test.unicodes()]
|
||||
cli_args.extend (test.get_profile_flags())
|
||||
print (' '.join(cli_args))
|
||||
_, return_code = cmd(cli_args)
|
||||
|
||||
|
@ -78,7 +79,7 @@ def run_ttx(file):
|
|||
|
||||
def strip_check_sum (ttx_string):
|
||||
return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
|
||||
'checkSumAdjustment value="0x00000000"',
|
||||
'checkSumAdjustment value="0x00000000"',
|
||||
ttx_string, count=1)
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import io
|
||||
import os
|
||||
|
||||
# A single test in a subset test suite. Identifies a font
|
||||
|
@ -13,15 +14,19 @@ class Test:
|
|||
def unicodes(self):
|
||||
return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
|
||||
|
||||
def get_profile_flags(self):
|
||||
with io.open(self.profile_path, mode="r", encoding="utf-8") as f:
|
||||
return f.read().splitlines();
|
||||
|
||||
def get_font_name(self):
|
||||
font_base_name = os.path.basename(self.font_path)
|
||||
font_base_name_parts = os.path.splitext(font_base_name)
|
||||
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
|
||||
|
||||
return "%s.%s.%s%s" % (font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.unicodes(),
|
||||
font_base_name_parts[1])
|
||||
profile_name,
|
||||
self.unicodes(),
|
||||
font_base_name_parts[1])
|
||||
|
||||
# A group of tests to perform on the subsetter. Each test
|
||||
# Identifies a font a subsetting profile, and a subset to be cut.
|
||||
|
|
|
@ -454,7 +454,7 @@ struct font_options_t : option_group_t
|
|||
default_font_size = default_font_size_;
|
||||
x_ppem = 0;
|
||||
y_ppem = 0;
|
||||
ptem = .0;
|
||||
ptem = 0.;
|
||||
subpixel_bits = subpixel_bits_;
|
||||
font_file = nullptr;
|
||||
face_index = 0;
|
||||
|
|
Loading…
Reference in New Issue