mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 02:17:34 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
372
gfx/harfbuzz/src/Makefile.am
Normal file
372
gfx/harfbuzz/src/Makefile.am
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS =
|
||||
DIST_SUBDIRS =
|
||||
BUILT_SOURCES =
|
||||
EXTRA_DIST =
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
MAINTAINERCLEANFILES =
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
|
||||
|
||||
# The following warning options are useful for debugging: -Wpadded
|
||||
#AM_CXXFLAGS =
|
||||
|
||||
# Convenience targets:
|
||||
lib: $(BUILT_SOURCES) libharfbuzz.la
|
||||
fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la
|
||||
|
||||
lib_LTLIBRARIES = libharfbuzz.la
|
||||
|
||||
include Makefile.sources
|
||||
|
||||
HBCFLAGS =
|
||||
HBLIBS =
|
||||
HBNONPCLIBS =
|
||||
HBDEPS =
|
||||
HBSOURCES = $(HB_BASE_sources)
|
||||
HBHEADERS = $(HB_BASE_headers)
|
||||
HBNODISTHEADERS = $(HB_NODIST_headers)
|
||||
|
||||
if HAVE_OT
|
||||
HBSOURCES += $(HB_OT_sources)
|
||||
HBHEADERS += $(HB_OT_headers)
|
||||
endif
|
||||
|
||||
if HAVE_FALLBACK
|
||||
HBSOURCES += $(HB_FALLBACK_sources)
|
||||
endif
|
||||
|
||||
if HAVE_PTHREAD
|
||||
HBCFLAGS += $(PTHREAD_CFLAGS)
|
||||
HBNONPCLIBS += $(PTHREAD_LIBS)
|
||||
endif
|
||||
|
||||
if HAVE_GLIB
|
||||
HBCFLAGS += $(GLIB_CFLAGS)
|
||||
HBLIBS += $(GLIB_LIBS)
|
||||
HBDEPS += $(GLIB_DEPS)
|
||||
HBSOURCES += $(HB_GLIB_sources)
|
||||
HBHEADERS += $(HB_GLIB_headers)
|
||||
endif
|
||||
|
||||
if HAVE_FREETYPE
|
||||
HBCFLAGS += $(FREETYPE_CFLAGS)
|
||||
HBLIBS += $(FREETYPE_LIBS)
|
||||
# XXX
|
||||
# The following creates a recursive dependency on FreeType if FreeType is
|
||||
# built with HarfBuzz support enabled. Newer pkg-config handles that just
|
||||
# fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes. Remove
|
||||
# in a year or two, or otherwise work around it...
|
||||
#HBDEPS += $(FREETYPE_DEPS)
|
||||
HBSOURCES += $(HB_FT_sources)
|
||||
HBHEADERS += $(HB_FT_headers)
|
||||
endif
|
||||
|
||||
if HAVE_GRAPHITE2
|
||||
HBCFLAGS += $(GRAPHITE2_CFLAGS)
|
||||
HBLIBS += $(GRAPHITE2_LIBS)
|
||||
HBDEPS += $(GRAPHITE2_DEPS)
|
||||
HBSOURCES += $(HB_GRAPHITE2_sources)
|
||||
HBHEADERS += $(HB_GRAPHITE2_headers)
|
||||
endif
|
||||
|
||||
if HAVE_UNISCRIBE
|
||||
HBCFLAGS += $(UNISCRIBE_CFLAGS)
|
||||
HBNONPCLIBS += $(UNISCRIBE_LIBS)
|
||||
HBSOURCES += $(HB_UNISCRIBE_sources)
|
||||
HBHEADERS += $(HB_UNISCRIBE_headers)
|
||||
endif
|
||||
|
||||
if HAVE_DIRECTWRITE
|
||||
HBCFLAGS += $(DIRECTWRITE_CXXFLAGS)
|
||||
HBNONPCLIBS += $(DIRECTWRITE_LIBS)
|
||||
HBSOURCES += $(HB_DIRECTWRITE_sources)
|
||||
HBHEADERS += $(HB_DIRECTWRITE_headers)
|
||||
endif
|
||||
|
||||
if HAVE_CORETEXT
|
||||
HBCFLAGS += $(CORETEXT_CFLAGS)
|
||||
HBNONPCLIBS += $(CORETEXT_LIBS)
|
||||
HBSOURCES += $(HB_CORETEXT_sources)
|
||||
HBHEADERS += $(HB_CORETEXT_headers)
|
||||
endif
|
||||
|
||||
if HAVE_UCDN
|
||||
SUBDIRS += hb-ucdn
|
||||
HBCFLAGS += -I$(srcdir)/hb-ucdn
|
||||
HBLIBS += hb-ucdn/libhb-ucdn.la
|
||||
HBSOURCES += $(HB_UCDN_sources)
|
||||
endif
|
||||
DIST_SUBDIRS += hb-ucdn
|
||||
|
||||
|
||||
# Put the library together
|
||||
|
||||
HBLIBS += $(HBNONPCLIBS)
|
||||
|
||||
if OS_WIN32
|
||||
export_symbols = -export-symbols harfbuzz.def
|
||||
harfbuzz_def_dependency = harfbuzz.def
|
||||
libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS)
|
||||
else
|
||||
# Use a C linker for GCC, not C++; Don't link to libstdc++
|
||||
if HAVE_GCC
|
||||
libharfbuzz_la_LINK = $(LINK) $(libharfbuzz_la_LDFLAGS)
|
||||
else
|
||||
libharfbuzz_la_LINK = $(CXXLINK) $(libharfbuzz_la_LDFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS)
|
||||
libharfbuzz_la_CPPFLAGS = $(HBCFLAGS)
|
||||
libharfbuzz_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) $(export_symbols) -no-undefined
|
||||
libharfbuzz_la_LIBADD = $(HBLIBS)
|
||||
EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
|
||||
pkginclude_HEADERS = $(HBHEADERS)
|
||||
nodist_pkginclude_HEADERS = $(HBNODISTHEADERS)
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = harfbuzz.pc
|
||||
EXTRA_DIST += harfbuzz.pc.in
|
||||
|
||||
FUZZING_CPPFLAGS= \
|
||||
-DHB_NDEBUG \
|
||||
-DHB_MAX_NESTING_LEVEL=3 \
|
||||
-DHB_SANITIZE_MAX_EDITS=3 \
|
||||
-DHB_BUFFER_MAX_EXPANSION_FACTOR=3 \
|
||||
-DHB_BUFFER_MAX_LEN_MIN=8 \
|
||||
-DHB_BUFFER_MAX_LEN_DEFAULT=128 \
|
||||
$(NULL)
|
||||
EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la
|
||||
libharfbuzz_fuzzing_la_LINK = $(libharfbuzz_la_LINK)
|
||||
libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES)
|
||||
libharfbuzz_fuzzing_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) $(FUZZING_CPPFLAGS)
|
||||
libharfbuzz_fuzzing_la_LDFLAGS = $(libharfbuzz_la_LDFLAGS)
|
||||
libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD)
|
||||
EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES)
|
||||
CLEANFILES += libharfbuzz-fuzzing.la
|
||||
|
||||
if HAVE_ICU
|
||||
if HAVE_ICU_BUILTIN
|
||||
HBCFLAGS += $(ICU_CFLAGS)
|
||||
HBLIBS += $(ICU_LIBS)
|
||||
HBSOURCES += $(HB_ICU_sources)
|
||||
HBHEADERS += $(HB_ICU_headers)
|
||||
else
|
||||
lib_LTLIBRARIES += libharfbuzz-icu.la
|
||||
libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
|
||||
libharfbuzz_icu_la_CPPFLAGS = $(ICU_CFLAGS)
|
||||
libharfbuzz_icu_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined
|
||||
libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la
|
||||
pkginclude_HEADERS += $(HB_ICU_headers)
|
||||
pkgconfig_DATA += harfbuzz-icu.pc
|
||||
endif
|
||||
endif
|
||||
EXTRA_DIST += harfbuzz-icu.pc.in
|
||||
|
||||
if HAVE_GOBJECT
|
||||
lib_LTLIBRARIES += libharfbuzz-gobject.la
|
||||
libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_sources)
|
||||
nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources)
|
||||
libharfbuzz_gobject_la_CPPFLAGS = $(GOBJECT_CFLAGS)
|
||||
libharfbuzz_gobject_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined
|
||||
libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la
|
||||
pkginclude_HEADERS += $(HB_GOBJECT_headers)
|
||||
nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers)
|
||||
pkgconfig_DATA += harfbuzz-gobject.pc
|
||||
|
||||
BUILT_SOURCES += \
|
||||
$(HB_GOBJECT_ENUM_sources) \
|
||||
$(HB_GOBJECT_ENUM_headers) \
|
||||
$(NULL)
|
||||
DISTCLEANFILES += \
|
||||
$(HB_GOBJECT_ENUM_sources) \
|
||||
$(HB_GOBJECT_ENUM_headers) \
|
||||
$(NULL)
|
||||
hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS)
|
||||
$(AM_V_GEN) $(GLIB_MKENUMS) \
|
||||
--identifier-prefix hb_ --symbol-prefix hb_gobject \
|
||||
--template $^ | \
|
||||
sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
|
||||
|| ($(RM) "$@"; false)
|
||||
endif
|
||||
EXTRA_DIST += \
|
||||
harfbuzz-gobject.pc.in \
|
||||
hb-gobject-enums.cc.tmpl \
|
||||
hb-gobject-enums.h.tmpl \
|
||||
$(NULL)
|
||||
|
||||
|
||||
%.pc: %.pc.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN) \
|
||||
$(SED) -e 's@%prefix%@$(prefix)@g' \
|
||||
-e 's@%exec_prefix%@$(exec_prefix)@g' \
|
||||
-e 's@%libdir%@$(libdir)@g' \
|
||||
-e 's@%includedir%@$(includedir)@g' \
|
||||
-e 's@%libs_private%@$(HBNONPCLIBS)@g' \
|
||||
-e 's@%requires_private%@$(HBDEPS)@g' \
|
||||
-e 's@%VERSION%@$(VERSION)@g' \
|
||||
"$<" > "$@" \
|
||||
|| ($(RM) "$@"; false)
|
||||
|
||||
CLEANFILES += $(pkgconfig_DATA)
|
||||
|
||||
|
||||
CLEANFILES += harfbuzz.def
|
||||
harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS)
|
||||
$(AM_V_GEN) (echo EXPORTS; \
|
||||
(cat $^ || echo 'hb_ERROR ()' ) | \
|
||||
$(EGREP) '^hb_.* \(' | \
|
||||
sed -e 's/ (.*//' | \
|
||||
LANG=C sort; \
|
||||
echo LIBRARY libharfbuzz-0.dll; \
|
||||
) >"$@"
|
||||
@ ! grep -q hb_ERROR "$@" \
|
||||
|| ($(RM) "$@"; false)
|
||||
|
||||
|
||||
GENERATORS = \
|
||||
gen-arabic-table.py \
|
||||
gen-indic-table.py \
|
||||
gen-use-table.py \
|
||||
$(NULL)
|
||||
EXTRA_DIST += $(GENERATORS)
|
||||
|
||||
unicode-tables: arabic-table indic-table use-table
|
||||
|
||||
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \
|
||||
|| ($(RM) hb-ot-shape-complex-arabic-table.hh; false)
|
||||
|
||||
indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \
|
||||
|| ($(RM) hb-ot-shape-complex-indic-table.cc; false)
|
||||
|
||||
use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \
|
||||
|| ($(RM) hb-ot-shape-complex-use-table.cc; false)
|
||||
|
||||
built-sources: $(BUILT_SOURCES)
|
||||
|
||||
.PHONY: unicode-tables arabic-table indic-table use-table built-sources
|
||||
|
||||
RAGEL_GENERATED = \
|
||||
$(srcdir)/hb-buffer-deserialize-json.hh \
|
||||
$(srcdir)/hb-buffer-deserialize-text.hh \
|
||||
$(srcdir)/hb-ot-shape-complex-indic-machine.hh \
|
||||
$(srcdir)/hb-ot-shape-complex-myanmar-machine.hh \
|
||||
$(srcdir)/hb-ot-shape-complex-use-machine.hh \
|
||||
$(NULL)
|
||||
BUILT_SOURCES += $(RAGEL_GENERATED)
|
||||
EXTRA_DIST += \
|
||||
hb-buffer-deserialize-json.rl \
|
||||
hb-buffer-deserialize-text.rl \
|
||||
hb-ot-shape-complex-indic-machine.rl \
|
||||
hb-ot-shape-complex-myanmar-machine.rl \
|
||||
hb-ot-shape-complex-use-machine.rl \
|
||||
$(NULL)
|
||||
MAINTAINERCLEANFILES += $(RAGEL_GENERATED)
|
||||
$(srcdir)/%.hh: $(srcdir)/%.rl
|
||||
$(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \
|
||||
|| ($(RM) "$@"; false)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
main \
|
||||
test \
|
||||
test-buffer-serialize \
|
||||
test-size-params \
|
||||
test-would-substitute \
|
||||
$(NULL)
|
||||
bin_PROGRAMS =
|
||||
|
||||
main_SOURCES = main.cc
|
||||
main_CPPFLAGS = $(HBCFLAGS)
|
||||
main_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_SOURCES = test.cc
|
||||
test_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
|
||||
test_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
|
||||
|
||||
test_would_substitute_SOURCES = test-would-substitute.cc
|
||||
test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
|
||||
test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
|
||||
|
||||
test_size_params_SOURCES = test-size-params.cc
|
||||
test_size_params_CPPFLAGS = $(HBCFLAGS)
|
||||
test_size_params_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_buffer_serialize_SOURCES = test-buffer-serialize.cc
|
||||
test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
|
||||
test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
dist_check_SCRIPTS = \
|
||||
check-c-linkage-decls.sh \
|
||||
check-defs.sh \
|
||||
check-header-guards.sh \
|
||||
check-includes.sh \
|
||||
check-libstdc++.sh \
|
||||
check-static-inits.sh \
|
||||
check-symbols.sh \
|
||||
$(NULL)
|
||||
|
||||
check_PROGRAMS = \
|
||||
test-ot-tag \
|
||||
$(NULL)
|
||||
test_ot_tag_SOURCES = hb-ot-tag.cc
|
||||
test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN
|
||||
test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
|
||||
TESTS_ENVIRONMENT = \
|
||||
srcdir="$(srcdir)" \
|
||||
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
|
||||
HBSOURCES="$(HBSOURCES)" \
|
||||
HBHEADERS="$(HBHEADERS) $(HBNODISTHEADERS)" \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS = HarfBuzz-0.0.gir # What does the 0 mean anyway?!
|
||||
INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all
|
||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
|
||||
INTROSPECTION_SCANNER_ENV = CC="$(CC)"
|
||||
|
||||
HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la
|
||||
HarfBuzz_0_0_gir_INCLUDES = GObject-2.0
|
||||
HarfBuzz_0_0_gir_CFLAGS = \
|
||||
$(INCLUDES) \
|
||||
$(HBCFLAGS) \
|
||||
-DHB_H \
|
||||
-DHB_H_IN \
|
||||
-DHB_OT_H \
|
||||
-DHB_OT_H_IN \
|
||||
-DHB_GOBJECT_H \
|
||||
-DHB_GOBJECT_H_IN \
|
||||
-DHB_EXTERN= \
|
||||
$(NULL)
|
||||
HarfBuzz_0_0_gir_LIBS = \
|
||||
libharfbuzz.la \
|
||||
libharfbuzz-gobject.la \
|
||||
$(NULL)
|
||||
HarfBuzz_0_0_gir_FILES = \
|
||||
$(HBHEADERS) \
|
||||
$(HBNODISTHEADERS) \
|
||||
$(HBSOURCES) \
|
||||
$(HB_GOBJECT_ENUM_sources) \
|
||||
$(HB_GOBJECT_ENUM_headers) \
|
||||
$(HB_GOBJECT_sources) \
|
||||
$(HB_GOBJECT_STRUCTS_headers) \
|
||||
$(NULL)
|
||||
|
||||
girdir = $(datadir)/gir-1.0
|
||||
gir_DATA = $(INTROSPECTION_GIRS)
|
||||
|
||||
typelibdir = $(libdir)/girepository-1.0
|
||||
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
|
||||
|
||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
|
||||
|
||||
endif
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
28
gfx/harfbuzz/src/check-c-linkage-decls.sh
Normal file
28
gfx/harfbuzz/src/check-c-linkage-decls.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
|
||||
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
|
||||
|
||||
|
||||
for x in $HBHEADERS; do
|
||||
test -f $srcdir/$x && x=$srcdir/$x
|
||||
if ! grep -q HB_BEGIN_DECLS "$x" || ! grep -q HB_END_DECLS "$x"; then
|
||||
echo "Ouch, file $x does not have HB_BEGIN_DECLS / HB_END_DECLS, but it should"
|
||||
stat=1
|
||||
fi
|
||||
done
|
||||
for x in $HBSOURCES; do
|
||||
test -f $srcdir/$x && x=$srcdir/$x
|
||||
if grep -q HB_BEGIN_DECLS "$x" || grep -q HB_END_DECLS "$x"; then
|
||||
echo "Ouch, file $x has HB_BEGIN_DECLS / HB_END_DECLS, but it shouldn't"
|
||||
stat=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $stat
|
||||
44
gfx/harfbuzz/src/check-defs.sh
Normal file
44
gfx/harfbuzz/src/check-defs.sh
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
test -z "$MAKE" && MAKE=make
|
||||
stat=0
|
||||
|
||||
if which nm 2>/dev/null >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "check-defs.sh: 'nm' not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
defs="harfbuzz.def"
|
||||
$MAKE $defs > /dev/null
|
||||
tested=false
|
||||
for def in $defs; do
|
||||
lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'`
|
||||
so=.libs/lib${lib}.so
|
||||
|
||||
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| llvm_' | cut -d' ' -f3`"
|
||||
|
||||
if test -f "$so"; then
|
||||
|
||||
echo "Checking that $so has the same symbol list as $def"
|
||||
{
|
||||
echo EXPORTS
|
||||
echo "$EXPORTED_SYMBOLS"
|
||||
# cheat: copy the last line from the def file!
|
||||
tail -n1 "$def"
|
||||
} | diff "$def" - >&2 || stat=1
|
||||
|
||||
tested=true
|
||||
fi
|
||||
done
|
||||
if ! $tested; then
|
||||
echo "check-defs.sh: libharfbuzz shared library not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
exit $stat
|
||||
24
gfx/harfbuzz/src/check-header-guards.sh
Normal file
24
gfx/harfbuzz/src/check-header-guards.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
|
||||
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'`
|
||||
|
||||
for x in $HBHEADERS $HBSOURCES; do
|
||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||
echo "$x" | grep -q '[^h]$' && continue;
|
||||
xx=`echo "$x" | sed 's@.*/@@'`
|
||||
tag=`echo "$xx" | tr 'a-z.-' 'A-Z_'`
|
||||
lines=`grep -w "$tag" "$x" | wc -l | sed 's/[ ]*//g'`
|
||||
if test "x$lines" != x3; then
|
||||
echo "Ouch, header file $x does not have correct preprocessor guards"
|
||||
stat=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $stat
|
||||
44
gfx/harfbuzz/src/check-includes.sh
Normal file
44
gfx/harfbuzz/src/check-includes.sh
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
|
||||
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'`
|
||||
|
||||
|
||||
echo 'Checking that public header files #include "hb-common.h" or "hb.h" first (or none)'
|
||||
|
||||
for x in $HBHEADERS; do
|
||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||
grep '#.*\<include\>' "$x" /dev/null | head -n 1
|
||||
done |
|
||||
grep -v '"hb-common[.]h"' |
|
||||
grep -v '"hb[.]h"' |
|
||||
grep -v 'hb-common[.]h:' |
|
||||
grep -v 'hb[.]h:' |
|
||||
grep . >&2 && stat=1
|
||||
|
||||
|
||||
echo 'Checking that source files #include "hb-*private.hh" first (or none)'
|
||||
|
||||
for x in $HBSOURCES; do
|
||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||
grep '#.*\<include\>' "$x" /dev/null | grep -v 'include _' | head -n 1
|
||||
done |
|
||||
grep -v '"hb-.*private[.]hh"' |
|
||||
grep -v 'hb-private[.]hh:' |
|
||||
grep . >&2 && stat=1
|
||||
|
||||
|
||||
echo 'Checking that there is no #include <hb.*.h>'
|
||||
for x in $HBHEADERS $HBSOURCES; do
|
||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||
grep '#.*\<include\>.*<.*hb' "$x" /dev/null >&2 && stat=1
|
||||
done
|
||||
|
||||
|
||||
exit $stat
|
||||
34
gfx/harfbuzz/src/check-libstdc++.sh
Normal file
34
gfx/harfbuzz/src/check-libstdc++.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
|
||||
if which ldd 2>/dev/null >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "check-libstdc++.sh: 'ldd' not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
tested=false
|
||||
for suffix in so dylib; do
|
||||
so=.libs/libharfbuzz.$suffix
|
||||
if ! test -f "$so"; then continue; fi
|
||||
|
||||
echo "Checking that we are not linking to libstdc++ or libc++"
|
||||
if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then
|
||||
echo "Ouch, linked to libstdc++ or libc++"
|
||||
stat=1
|
||||
fi
|
||||
tested=true
|
||||
done
|
||||
if ! $tested; then
|
||||
echo "check-libstdc++.sh: libharfbuzz shared library not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
exit $stat
|
||||
39
gfx/harfbuzz/src/check-static-inits.sh
Normal file
39
gfx/harfbuzz/src/check-static-inits.sh
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
|
||||
if which objdump 2>/dev/null >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "check-static-inits.sh: 'objdump' not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
OBJS=.libs/*.o
|
||||
if test "x`echo $OBJS`" = "x$OBJS" 2>/dev/null >/dev/null; then
|
||||
echo "check-static-inits.sh: object files not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
echo "Checking that no object file has static initializers"
|
||||
for obj in $OBJS; do
|
||||
if objdump -t "$obj" | grep '[.][cd]tors' | grep -v '\<00*\>'; then
|
||||
echo "Ouch, $obj has static initializers/finalizers"
|
||||
stat=1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
|
||||
for obj in $OBJS; do
|
||||
if objdump -t "$obj" | grep '__cxa_'; then
|
||||
echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
|
||||
stat=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $stat
|
||||
43
gfx/harfbuzz/src/check-symbols.sh
Normal file
43
gfx/harfbuzz/src/check-symbols.sh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/sh
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
stat=0
|
||||
|
||||
|
||||
if which nm 2>/dev/null >/dev/null; then
|
||||
:
|
||||
else
|
||||
echo "check-symbols.sh: 'nm' not found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
echo "Checking that we are not exposing internal symbols"
|
||||
tested=false
|
||||
for suffix in so dylib; do
|
||||
so=.libs/libharfbuzz.$suffix
|
||||
if ! test -f "$so"; then continue; fi
|
||||
|
||||
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| ___gcov_flush\>\| llvm_\| _llvm_' | cut -d' ' -f3`"
|
||||
|
||||
prefix=`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
|
||||
|
||||
# On mac, C symbols are prefixed with _
|
||||
if test $suffix = dylib; then prefix="_$prefix"; fi
|
||||
|
||||
echo "Processing $so"
|
||||
if echo "$EXPORTED_SYMBOLS" | grep -v "^${prefix}_"; then
|
||||
echo "Ouch, internal symbols exposed"
|
||||
stat=1
|
||||
fi
|
||||
|
||||
tested=true
|
||||
done
|
||||
if ! $tested; then
|
||||
echo "check-symbols.sh: no shared library found; skipping test"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
exit $stat
|
||||
269
gfx/harfbuzz/src/gen-arabic-table.py
Normal file
269
gfx/harfbuzz/src/gen-arabic-table.py
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
if len (sys.argv) != 4:
|
||||
print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
|
||||
sys.exit (1)
|
||||
|
||||
files = [file (x) for x in sys.argv[1:]]
|
||||
|
||||
headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]]
|
||||
headers.append (["UnicodeData.txt does not have a header."])
|
||||
while files[0].readline ().find ('##################') < 0:
|
||||
pass
|
||||
|
||||
blocks = {}
|
||||
def read_blocks(f):
|
||||
global blocks
|
||||
for line in f:
|
||||
|
||||
j = line.find ('#')
|
||||
if j >= 0:
|
||||
line = line[:j]
|
||||
|
||||
fields = [x.strip () for x in line.split (';')]
|
||||
if len (fields) == 1:
|
||||
continue
|
||||
|
||||
uu = fields[0].split ('..')
|
||||
start = int (uu[0], 16)
|
||||
if len (uu) == 1:
|
||||
end = start
|
||||
else:
|
||||
end = int (uu[1], 16)
|
||||
|
||||
t = fields[1]
|
||||
|
||||
for u in range (start, end + 1):
|
||||
blocks[u] = t
|
||||
|
||||
def print_joining_table(f):
|
||||
|
||||
values = {}
|
||||
for line in f:
|
||||
|
||||
if line[0] == '#':
|
||||
continue
|
||||
|
||||
fields = [x.strip () for x in line.split (';')]
|
||||
if len (fields) == 1:
|
||||
continue
|
||||
|
||||
u = int (fields[0], 16)
|
||||
|
||||
if fields[3] in ["ALAPH", "DALATH RISH"]:
|
||||
value = "JOINING_GROUP_" + fields[3].replace(' ', '_')
|
||||
else:
|
||||
value = "JOINING_TYPE_" + fields[2]
|
||||
values[u] = value
|
||||
|
||||
short_value = {}
|
||||
for value in set([v for v in values.values()] + ['JOINING_TYPE_X']):
|
||||
short = ''.join(x[0] for x in value.split('_')[2:])
|
||||
assert short not in short_value.values()
|
||||
short_value[value] = short
|
||||
|
||||
print
|
||||
for value,short in short_value.items():
|
||||
print "#define %s %s" % (short, value)
|
||||
|
||||
uu = sorted(values.keys())
|
||||
num = len(values)
|
||||
all_blocks = set([blocks[u] for u in uu])
|
||||
|
||||
last = -100000
|
||||
ranges = []
|
||||
for u in uu:
|
||||
if u - last <= 1+16*5:
|
||||
ranges[-1][-1] = u
|
||||
else:
|
||||
ranges.append([u,u])
|
||||
last = u
|
||||
|
||||
print
|
||||
print "static const uint8_t joining_table[] ="
|
||||
print "{"
|
||||
last_block = None
|
||||
offset = 0
|
||||
for start,end in ranges:
|
||||
|
||||
print
|
||||
print "#define joining_offset_0x%04xu %d" % (start, offset)
|
||||
|
||||
for u in range(start, end+1):
|
||||
|
||||
block = blocks.get(u, last_block)
|
||||
value = values.get(u, "JOINING_TYPE_X")
|
||||
|
||||
if block != last_block or u == start:
|
||||
if u != start:
|
||||
print
|
||||
if block in all_blocks:
|
||||
print "\n /* %s */" % block
|
||||
else:
|
||||
print "\n /* FILLER */"
|
||||
last_block = block
|
||||
if u % 32 != 0:
|
||||
print
|
||||
print " /* %04X */" % (u//32*32), " " * (u % 32),
|
||||
|
||||
if u % 32 == 0:
|
||||
print
|
||||
print " /* %04X */ " % u,
|
||||
sys.stdout.write("%s," % short_value[value])
|
||||
print
|
||||
|
||||
offset += end - start + 1
|
||||
print
|
||||
occupancy = num * 100. / offset
|
||||
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
|
||||
print
|
||||
|
||||
page_bits = 12;
|
||||
print
|
||||
print "static unsigned int"
|
||||
print "joining_type (hb_codepoint_t u)"
|
||||
print "{"
|
||||
print " switch (u >> %d)" % page_bits
|
||||
print " {"
|
||||
pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]])
|
||||
for p in sorted(pages):
|
||||
print " case 0x%0Xu:" % p
|
||||
for (start,end) in ranges:
|
||||
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||
offset = "joining_offset_0x%04xu" % start
|
||||
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
|
||||
print " break;"
|
||||
print ""
|
||||
print " default:"
|
||||
print " break;"
|
||||
print " }"
|
||||
print " return X;"
|
||||
print "}"
|
||||
print
|
||||
for value,short in short_value.items():
|
||||
print "#undef %s" % (short)
|
||||
print
|
||||
|
||||
def print_shaping_table(f):
|
||||
|
||||
shapes = {}
|
||||
ligatures = {}
|
||||
names = {}
|
||||
for line in f:
|
||||
|
||||
fields = [x.strip () for x in line.split (';')]
|
||||
if fields[5][0:1] != '<':
|
||||
continue
|
||||
|
||||
items = fields[5].split (' ')
|
||||
shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:])
|
||||
|
||||
if not shape in ['initial', 'medial', 'isolated', 'final']:
|
||||
continue
|
||||
|
||||
c = int (fields[0], 16)
|
||||
if len (items) != 1:
|
||||
# We only care about lam-alef ligatures
|
||||
if len (items) != 2 or items[0] != 0x0644 or items[1] not in [0x0622, 0x0623, 0x0625, 0x0627]:
|
||||
continue
|
||||
|
||||
# Save ligature
|
||||
names[c] = fields[1]
|
||||
if items not in ligatures:
|
||||
ligatures[items] = {}
|
||||
ligatures[items][shape] = c
|
||||
pass
|
||||
else:
|
||||
# Save shape
|
||||
if items[0] not in names:
|
||||
names[items[0]] = fields[1]
|
||||
else:
|
||||
names[items[0]] = os.path.commonprefix ([names[items[0]], fields[1]]).strip ()
|
||||
if items[0] not in shapes:
|
||||
shapes[items[0]] = {}
|
||||
shapes[items[0]][shape] = c
|
||||
|
||||
print
|
||||
print "static const uint16_t shaping_table[][4] ="
|
||||
print "{"
|
||||
|
||||
keys = shapes.keys ()
|
||||
min_u, max_u = min (keys), max (keys)
|
||||
for u in range (min_u, max_u + 1):
|
||||
s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
|
||||
for shape in ['initial', 'medial', 'final', 'isolated']]
|
||||
value = ', '.join ("0x%04Xu" % c for c in s)
|
||||
print " {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
|
||||
|
||||
print "};"
|
||||
print
|
||||
print "#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u
|
||||
print "#define SHAPING_TABLE_LAST 0x%04Xu" % max_u
|
||||
print
|
||||
|
||||
ligas = {}
|
||||
for pair in ligatures.keys ():
|
||||
for shape in ligatures[pair]:
|
||||
c = ligatures[pair][shape]
|
||||
if shape == 'isolated':
|
||||
liga = (shapes[pair[0]]['initial'], shapes[pair[1]]['final'])
|
||||
elif shape == 'final':
|
||||
liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
|
||||
else:
|
||||
raise Exception ("Unexpected shape", shape)
|
||||
if liga[0] not in ligas:
|
||||
ligas[liga[0]] = []
|
||||
ligas[liga[0]].append ((liga[1], c))
|
||||
max_i = max (len (ligas[l]) for l in ligas)
|
||||
print
|
||||
print "static const struct ligature_set_t {"
|
||||
print " uint16_t first;"
|
||||
print " struct ligature_pairs_t {"
|
||||
print " uint16_t second;"
|
||||
print " uint16_t ligature;"
|
||||
print " } ligatures[%d];" % max_i
|
||||
print "} ligature_table[] ="
|
||||
print "{"
|
||||
keys = ligas.keys ()
|
||||
keys.sort ()
|
||||
for first in keys:
|
||||
|
||||
print " { 0x%04Xu, {" % (first)
|
||||
for liga in ligas[first]:
|
||||
print " { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])
|
||||
print " }},"
|
||||
|
||||
print "};"
|
||||
print
|
||||
|
||||
|
||||
|
||||
print "/* == Start of generated table == */"
|
||||
print "/*"
|
||||
print " * The following table is generated by running:"
|
||||
print " *"
|
||||
print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
|
||||
print " *"
|
||||
print " * on files with these headers:"
|
||||
print " *"
|
||||
for h in headers:
|
||||
for l in h:
|
||||
print " * %s" % (l.strip())
|
||||
print " */"
|
||||
print
|
||||
print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
|
||||
print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
|
||||
print
|
||||
|
||||
read_blocks (files[2])
|
||||
print_joining_table (files[0])
|
||||
print_shaping_table (files[1])
|
||||
|
||||
print
|
||||
print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */"
|
||||
print
|
||||
print "/* == End of generated table == */"
|
||||
|
||||
260
gfx/harfbuzz/src/gen-indic-table.py
Normal file
260
gfx/harfbuzz/src/gen-indic-table.py
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
if len (sys.argv) != 4:
|
||||
print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
|
||||
sys.exit (1)
|
||||
|
||||
ALLOWED_SINGLES = [0x00A0, 0x25CC]
|
||||
ALLOWED_BLOCKS = [
|
||||
'Basic Latin',
|
||||
'Latin-1 Supplement',
|
||||
'Devanagari',
|
||||
'Bengali',
|
||||
'Gurmukhi',
|
||||
'Gujarati',
|
||||
'Oriya',
|
||||
'Tamil',
|
||||
'Telugu',
|
||||
'Kannada',
|
||||
'Malayalam',
|
||||
'Sinhala',
|
||||
'Myanmar',
|
||||
'Khmer',
|
||||
'Vedic Extensions',
|
||||
'General Punctuation',
|
||||
'Superscripts and Subscripts',
|
||||
'Devanagari Extended',
|
||||
'Myanmar Extended-B',
|
||||
'Myanmar Extended-A',
|
||||
]
|
||||
|
||||
files = [file (x) for x in sys.argv[1:]]
|
||||
|
||||
headers = [[f.readline () for i in range (2)] for f in files]
|
||||
|
||||
data = [{} for f in files]
|
||||
values = [{} for f in files]
|
||||
for i, f in enumerate (files):
|
||||
for line in f:
|
||||
|
||||
j = line.find ('#')
|
||||
if j >= 0:
|
||||
line = line[:j]
|
||||
|
||||
fields = [x.strip () for x in line.split (';')]
|
||||
if len (fields) == 1:
|
||||
continue
|
||||
|
||||
uu = fields[0].split ('..')
|
||||
start = int (uu[0], 16)
|
||||
if len (uu) == 1:
|
||||
end = start
|
||||
else:
|
||||
end = int (uu[1], 16)
|
||||
|
||||
t = fields[1]
|
||||
|
||||
for u in range (start, end + 1):
|
||||
data[i][u] = t
|
||||
values[i][t] = values[i].get (t, 0) + end - start + 1
|
||||
|
||||
# Merge data into one dict:
|
||||
defaults = ('Other', 'Not_Applicable', 'No_Block')
|
||||
for i,v in enumerate (defaults):
|
||||
values[i][v] = values[i].get (v, 0) + 1
|
||||
combined = {}
|
||||
for i,d in enumerate (data):
|
||||
for u,v in d.items ():
|
||||
if i == 2 and not u in combined:
|
||||
continue
|
||||
if not u in combined:
|
||||
combined[u] = list (defaults)
|
||||
combined[u][i] = v
|
||||
combined = {k:v for k,v in combined.items() if k in ALLOWED_SINGLES or v[2] in ALLOWED_BLOCKS}
|
||||
data = combined
|
||||
del combined
|
||||
num = len (data)
|
||||
|
||||
for u in [0x17CD, 0x17CE, 0x17CF, 0x17D0, 0x17D3]:
|
||||
if data[u][0] == 'Other':
|
||||
data[u][0] = "Vowel_Dependent"
|
||||
|
||||
# Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out
|
||||
singles = {}
|
||||
for u in ALLOWED_SINGLES:
|
||||
singles[u] = data[u]
|
||||
del data[u]
|
||||
|
||||
print "/* == Start of generated table == */"
|
||||
print "/*"
|
||||
print " * The following table is generated by running:"
|
||||
print " *"
|
||||
print " * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
|
||||
print " *"
|
||||
print " * on files with these headers:"
|
||||
print " *"
|
||||
for h in headers:
|
||||
for l in h:
|
||||
print " * %s" % (l.strip())
|
||||
print " */"
|
||||
print
|
||||
print '#include "hb-ot-shape-complex-indic-private.hh"'
|
||||
print
|
||||
|
||||
# Shorten values
|
||||
short = [{
|
||||
"Bindu": 'Bi',
|
||||
"Cantillation_Mark": 'Ca',
|
||||
"Joiner": 'ZWJ',
|
||||
"Non_Joiner": 'ZWNJ',
|
||||
"Number": 'Nd',
|
||||
"Visarga": 'Vs',
|
||||
"Vowel": 'Vo',
|
||||
"Vowel_Dependent": 'M',
|
||||
"Consonant_Prefixed": 'CPrf',
|
||||
"Other": 'x',
|
||||
},{
|
||||
"Not_Applicable": 'x',
|
||||
}]
|
||||
all_shorts = [{},{}]
|
||||
|
||||
# Add some of the values, to make them more readable, and to avoid duplicates
|
||||
|
||||
|
||||
for i in range (2):
|
||||
for v,s in short[i].items ():
|
||||
all_shorts[i][s] = v
|
||||
|
||||
what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
|
||||
what_short = ["ISC", "IMC"]
|
||||
for i in range (2):
|
||||
print
|
||||
vv = values[i].keys ()
|
||||
vv.sort ()
|
||||
for v in vv:
|
||||
v_no_and = v.replace ('_And_', '_')
|
||||
if v in short[i]:
|
||||
s = short[i][v]
|
||||
else:
|
||||
s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')])
|
||||
if s in all_shorts[i]:
|
||||
raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
|
||||
all_shorts[i][s] = v
|
||||
short[i][v] = s
|
||||
print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \
|
||||
(what_short[i], s, what[i], v.upper (), \
|
||||
' '* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \
|
||||
values[i][v], v)
|
||||
print
|
||||
print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)"
|
||||
print
|
||||
print
|
||||
|
||||
total = 0
|
||||
used = 0
|
||||
last_block = None
|
||||
def print_block (block, start, end, data):
|
||||
global total, used, last_block
|
||||
if block and block != last_block:
|
||||
print
|
||||
print
|
||||
print " /* %s */" % block
|
||||
num = 0
|
||||
assert start % 8 == 0
|
||||
assert (end+1) % 8 == 0
|
||||
for u in range (start, end+1):
|
||||
if u % 8 == 0:
|
||||
print
|
||||
print " /* %04X */" % u,
|
||||
if u in data:
|
||||
num += 1
|
||||
d = data.get (u, defaults)
|
||||
sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])))
|
||||
|
||||
total += end - start + 1
|
||||
used += num
|
||||
if block:
|
||||
last_block = block
|
||||
|
||||
uu = data.keys ()
|
||||
uu.sort ()
|
||||
|
||||
last = -100000
|
||||
num = 0
|
||||
offset = 0
|
||||
starts = []
|
||||
ends = []
|
||||
print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {"
|
||||
for u in uu:
|
||||
if u <= last:
|
||||
continue
|
||||
block = data[u][2]
|
||||
|
||||
start = u//8*8
|
||||
end = start+1
|
||||
while end in uu and block == data[end][2]:
|
||||
end += 1
|
||||
end = (end-1)//8*8 + 7
|
||||
|
||||
if start != last + 1:
|
||||
if start - last <= 1+16*3:
|
||||
print_block (None, last+1, start-1, data)
|
||||
last = start-1
|
||||
else:
|
||||
if last >= 0:
|
||||
ends.append (last + 1)
|
||||
offset += ends[-1] - starts[-1]
|
||||
print
|
||||
print
|
||||
print "#define indic_offset_0x%04xu %d" % (start, offset)
|
||||
starts.append (start)
|
||||
|
||||
print_block (block, start, end, data)
|
||||
last = end
|
||||
ends.append (last + 1)
|
||||
offset += ends[-1] - starts[-1]
|
||||
print
|
||||
print
|
||||
occupancy = used * 100. / total
|
||||
page_bits = 12
|
||||
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
|
||||
print
|
||||
print "INDIC_TABLE_ELEMENT_TYPE"
|
||||
print "hb_indic_get_categories (hb_codepoint_t u)"
|
||||
print "{"
|
||||
print " switch (u >> %d)" % page_bits
|
||||
print " {"
|
||||
pages = set([u>>page_bits for u in starts+ends+singles.keys()])
|
||||
for p in sorted(pages):
|
||||
print " case 0x%0Xu:" % p
|
||||
for (start,end) in zip (starts, ends):
|
||||
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||
offset = "indic_offset_0x%04xu" % start
|
||||
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
|
||||
for u,d in singles.items ():
|
||||
if p != u>>page_bits: continue
|
||||
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
|
||||
print " break;"
|
||||
print ""
|
||||
print " default:"
|
||||
print " break;"
|
||||
print " }"
|
||||
print " return _(x,x);"
|
||||
print "}"
|
||||
print
|
||||
print "#undef _"
|
||||
for i in range (2):
|
||||
print
|
||||
vv = values[i].keys ()
|
||||
vv.sort ()
|
||||
for v in vv:
|
||||
print "#undef %s_%s" % \
|
||||
(what_short[i], short[i][v])
|
||||
print
|
||||
print "/* == End of generated table == */"
|
||||
|
||||
# Maintain at least 30% occupancy in the table */
|
||||
if occupancy < 30:
|
||||
raise Exception ("Table too sparse, please investigate: ", occupancy)
|
||||
477
gfx/harfbuzz/src/gen-use-table.py
Normal file
477
gfx/harfbuzz/src/gen-use-table.py
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
if len (sys.argv) != 5:
|
||||
print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt"
|
||||
sys.exit (1)
|
||||
|
||||
BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
|
||||
|
||||
files = [file (x) for x in sys.argv[1:]]
|
||||
|
||||
headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2]
|
||||
headers.append (["UnicodeData.txt does not have a header."])
|
||||
|
||||
data = [{} for f in files]
|
||||
values = [{} for f in files]
|
||||
for i, f in enumerate (files):
|
||||
for line in f:
|
||||
|
||||
j = line.find ('#')
|
||||
if j >= 0:
|
||||
line = line[:j]
|
||||
|
||||
fields = [x.strip () for x in line.split (';')]
|
||||
if len (fields) == 1:
|
||||
continue
|
||||
|
||||
uu = fields[0].split ('..')
|
||||
start = int (uu[0], 16)
|
||||
if len (uu) == 1:
|
||||
end = start
|
||||
else:
|
||||
end = int (uu[1], 16)
|
||||
|
||||
t = fields[1 if i != 2 else 2]
|
||||
|
||||
for u in range (start, end + 1):
|
||||
data[i][u] = t
|
||||
values[i][t] = values[i].get (t, 0) + end - start + 1
|
||||
|
||||
defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block')
|
||||
|
||||
# TODO Characters that are not in Unicode Indic files, but used in USE
|
||||
data[0][0x034F] = defaults[0]
|
||||
data[0][0x2060] = defaults[0]
|
||||
for u in range (0xFE00, 0xFE0F + 1):
|
||||
data[0][u] = defaults[0]
|
||||
|
||||
# Merge data into one dict:
|
||||
for i,v in enumerate (defaults):
|
||||
values[i][v] = values[i].get (v, 0) + 1
|
||||
combined = {}
|
||||
for i,d in enumerate (data):
|
||||
for u,v in d.items ():
|
||||
if i >= 2 and not u in combined:
|
||||
continue
|
||||
if not u in combined:
|
||||
combined[u] = list (defaults)
|
||||
combined[u][i] = v
|
||||
combined = {k:v for k,v in combined.items() if v[3] not in BLACKLISTED_BLOCKS}
|
||||
data = combined
|
||||
del combined
|
||||
num = len (data)
|
||||
|
||||
|
||||
property_names = [
|
||||
# General_Category
|
||||
'Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc',
|
||||
'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po',
|
||||
'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',
|
||||
# Indic_Syllabic_Category
|
||||
'Other',
|
||||
'Bindu',
|
||||
'Visarga',
|
||||
'Avagraha',
|
||||
'Nukta',
|
||||
'Virama',
|
||||
'Pure_Killer',
|
||||
'Invisible_Stacker',
|
||||
'Vowel_Independent',
|
||||
'Vowel_Dependent',
|
||||
'Vowel',
|
||||
'Consonant_Placeholder',
|
||||
'Consonant',
|
||||
'Consonant_Dead',
|
||||
'Consonant_With_Stacker',
|
||||
'Consonant_Prefixed',
|
||||
'Consonant_Preceding_Repha',
|
||||
'Consonant_Succeeding_Repha',
|
||||
'Consonant_Subjoined',
|
||||
'Consonant_Medial',
|
||||
'Consonant_Final',
|
||||
'Consonant_Head_Letter',
|
||||
'Modifying_Letter',
|
||||
'Tone_Letter',
|
||||
'Tone_Mark',
|
||||
'Gemination_Mark',
|
||||
'Cantillation_Mark',
|
||||
'Register_Shifter',
|
||||
'Syllable_Modifier',
|
||||
'Consonant_Killer',
|
||||
'Non_Joiner',
|
||||
'Joiner',
|
||||
'Number_Joiner',
|
||||
'Number',
|
||||
'Brahmi_Joining_Number',
|
||||
# Indic_Positional_Category
|
||||
'Not_Applicable',
|
||||
'Right',
|
||||
'Left',
|
||||
'Visual_Order_Left',
|
||||
'Left_And_Right',
|
||||
'Top',
|
||||
'Bottom',
|
||||
'Top_And_Bottom',
|
||||
'Top_And_Right',
|
||||
'Top_And_Left',
|
||||
'Top_And_Left_And_Right',
|
||||
'Bottom_And_Right',
|
||||
'Top_And_Bottom_And_Right',
|
||||
'Overstruck',
|
||||
]
|
||||
|
||||
class PropertyValue(object):
|
||||
def __init__(self, name_):
|
||||
self.name = name_
|
||||
def __str__(self):
|
||||
return self.name
|
||||
def __eq__(self, other):
|
||||
return self.name == (other if isinstance(other, basestring) else other.name)
|
||||
def __ne__(self, other):
|
||||
return not (self == other)
|
||||
|
||||
property_values = {}
|
||||
|
||||
for name in property_names:
|
||||
value = PropertyValue(name)
|
||||
assert value not in property_values
|
||||
assert value not in globals()
|
||||
property_values[name] = value
|
||||
globals().update(property_values)
|
||||
|
||||
|
||||
def is_BASE(U, UISC, UGC):
|
||||
return (UISC in [Number, Consonant, Consonant_Head_Letter,
|
||||
#SPEC-DRAFT Consonant_Placeholder,
|
||||
Tone_Letter,
|
||||
Vowel_Independent #SPEC-DRAFT
|
||||
] or
|
||||
(UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial,
|
||||
Consonant_Subjoined, Vowel, Vowel_Dependent]))
|
||||
def is_BASE_IND(U, UISC, UGC):
|
||||
#SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
|
||||
return (UISC in [Consonant_Dead, Modifying_Letter] or
|
||||
(UGC == Po and not U in [0x104E, 0x2022]) or
|
||||
False # SPEC-DRAFT-OUTDATED! U == 0x002D
|
||||
)
|
||||
def is_BASE_NUM(U, UISC, UGC):
|
||||
return UISC == Brahmi_Joining_Number
|
||||
def is_BASE_OTHER(U, UISC, UGC):
|
||||
if UISC == Consonant_Placeholder: return True #SPEC-DRAFT
|
||||
#SPEC-DRAFT return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
|
||||
return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE]
|
||||
def is_CGJ(U, UISC, UGC):
|
||||
return U == 0x034F
|
||||
def is_CONS_FINAL(U, UISC, UGC):
|
||||
return ((UISC == Consonant_Final and UGC != Lo) or
|
||||
UISC == Consonant_Succeeding_Repha)
|
||||
def is_CONS_FINAL_MOD(U, UISC, UGC):
|
||||
#SPEC-DRAFT return UISC in [Consonant_Final_Modifier, Syllable_Modifier]
|
||||
return UISC == Syllable_Modifier
|
||||
def is_CONS_MED(U, UISC, UGC):
|
||||
return UISC == Consonant_Medial and UGC != Lo
|
||||
def is_CONS_MOD(U, UISC, UGC):
|
||||
return UISC in [Nukta, Gemination_Mark, Consonant_Killer]
|
||||
def is_CONS_SUB(U, UISC, UGC):
|
||||
#SPEC-DRAFT return UISC == Consonant_Subjoined
|
||||
return UISC == Consonant_Subjoined and UGC != Lo
|
||||
def is_HALANT(U, UISC, UGC):
|
||||
return UISC in [Virama, Invisible_Stacker]
|
||||
def is_HALANT_NUM(U, UISC, UGC):
|
||||
return UISC == Number_Joiner
|
||||
def is_ZWNJ(U, UISC, UGC):
|
||||
return UISC == Non_Joiner
|
||||
def is_ZWJ(U, UISC, UGC):
|
||||
return UISC == Joiner
|
||||
def is_Word_Joiner(U, UISC, UGC):
|
||||
return U == 0x2060
|
||||
def is_OTHER(U, UISC, UGC):
|
||||
#SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters
|
||||
return (UISC == Other
|
||||
and not is_SYM_MOD(U, UISC, UGC)
|
||||
and not is_CGJ(U, UISC, UGC)
|
||||
and not is_Word_Joiner(U, UISC, UGC)
|
||||
and not is_VARIATION_SELECTOR(U, UISC, UGC)
|
||||
)
|
||||
def is_Reserved(U, UISC, UGC):
|
||||
return UGC == 'Cn'
|
||||
def is_REPHA(U, UISC, UGC):
|
||||
#return UISC == Consonant_Preceding_Repha
|
||||
#SPEC-OUTDATED hack to categorize Consonant_With_Stacker and Consonant_Prefixed
|
||||
return UISC in [Consonant_Preceding_Repha, Consonant_With_Stacker, Consonant_Prefixed]
|
||||
def is_SYM(U, UISC, UGC):
|
||||
if U == 0x25CC: return False #SPEC-DRAFT
|
||||
#SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter
|
||||
return UGC in [So, Sc]
|
||||
def is_SYM_MOD(U, UISC, UGC):
|
||||
return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
|
||||
def is_VARIATION_SELECTOR(U, UISC, UGC):
|
||||
return 0xFE00 <= U <= 0xFE0F
|
||||
def is_VOWEL(U, UISC, UGC):
|
||||
return (UISC == Pure_Killer or
|
||||
(UGC != Lo and UISC in [Vowel, Vowel_Dependent]))
|
||||
def is_VOWEL_MOD(U, UISC, UGC):
|
||||
return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
|
||||
(UGC != Lo and UISC == Bindu))
|
||||
|
||||
use_mapping = {
|
||||
'B': is_BASE,
|
||||
'IND': is_BASE_IND,
|
||||
'N': is_BASE_NUM,
|
||||
'GB': is_BASE_OTHER,
|
||||
'CGJ': is_CGJ,
|
||||
'F': is_CONS_FINAL,
|
||||
'FM': is_CONS_FINAL_MOD,
|
||||
'M': is_CONS_MED,
|
||||
'CM': is_CONS_MOD,
|
||||
'SUB': is_CONS_SUB,
|
||||
'H': is_HALANT,
|
||||
'HN': is_HALANT_NUM,
|
||||
'ZWNJ': is_ZWNJ,
|
||||
'ZWJ': is_ZWJ,
|
||||
'WJ': is_Word_Joiner,
|
||||
'O': is_OTHER,
|
||||
'Rsv': is_Reserved,
|
||||
'R': is_REPHA,
|
||||
'S': is_SYM,
|
||||
'SM': is_SYM_MOD,
|
||||
'VS': is_VARIATION_SELECTOR,
|
||||
'V': is_VOWEL,
|
||||
'VM': is_VOWEL_MOD,
|
||||
}
|
||||
|
||||
use_positions = {
|
||||
'F': {
|
||||
'Abv': [Top],
|
||||
'Blw': [Bottom],
|
||||
'Pst': [Right],
|
||||
},
|
||||
'M': {
|
||||
'Abv': [Top],
|
||||
'Blw': [Bottom],
|
||||
'Pst': [Right],
|
||||
'Pre': [Left],
|
||||
},
|
||||
'CM': {
|
||||
'Abv': [Top],
|
||||
'Blw': [Bottom],
|
||||
},
|
||||
'V': {
|
||||
'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right],
|
||||
'Blw': [Bottom, Overstruck, Bottom_And_Right],
|
||||
'Pst': [Right],
|
||||
'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right],
|
||||
},
|
||||
'VM': {
|
||||
'Abv': [Top],
|
||||
'Blw': [Bottom, Overstruck],
|
||||
'Pst': [Right],
|
||||
'Pre': [Left],
|
||||
},
|
||||
'SM': {
|
||||
'Abv': [Top],
|
||||
'Blw': [Bottom],
|
||||
},
|
||||
'H': None,
|
||||
'B': None,
|
||||
'FM': None,
|
||||
'SUB': None,
|
||||
}
|
||||
|
||||
def map_to_use(data):
|
||||
out = {}
|
||||
items = use_mapping.items()
|
||||
for U,(UISC,UIPC,UGC,UBlock) in data.items():
|
||||
|
||||
# Resolve Indic_Syllabic_Category
|
||||
|
||||
# TODO: These don't have UISC assigned in Unicode 8.0, but
|
||||
# have UIPC
|
||||
if U == 0x17DD: UISC = Vowel_Dependent
|
||||
if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark
|
||||
|
||||
# TODO: U+1CED should only be allowed after some of
|
||||
# the nasalization marks, maybe only for U+1CE9..U+1CF1.
|
||||
if U == 0x1CED: UISC = Tone_Mark
|
||||
|
||||
evals = [(k, v(U,UISC,UGC)) for k,v in items]
|
||||
values = [k for k,v in evals if v]
|
||||
assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
|
||||
USE = values[0]
|
||||
|
||||
# Resolve Indic_Positional_Category
|
||||
|
||||
# TODO: Not in Unicode 8.0 yet, but in spec.
|
||||
if U == 0x1B6C: UIPC = Bottom
|
||||
|
||||
# TODO: These should die, but have UIPC in Unicode 8.0
|
||||
if U in [0x953, 0x954]: UIPC = Not_Applicable
|
||||
|
||||
# TODO: In USE's override list but not in Unicode 8.0
|
||||
if U == 0x103C: UIPC = Left
|
||||
|
||||
# TODO: These are not in USE's override list that we have, nor are they in Unicode 8.0
|
||||
if 0xA926 <= U <= 0xA92A: UIPC = Top
|
||||
if U == 0x111CA: UIPC = Bottom
|
||||
if U == 0x11300: UIPC = Top
|
||||
if U == 0x1133C: UIPC = Bottom
|
||||
if U == 0x1171E: UIPC = Left # Correct?!
|
||||
if 0x1CF2 <= U <= 0x1CF3: UIPC = Right
|
||||
if 0x1CF8 <= U <= 0x1CF9: UIPC = Top
|
||||
|
||||
assert (UIPC in [Not_Applicable, Visual_Order_Left] or
|
||||
USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC)
|
||||
|
||||
pos_mapping = use_positions.get(USE, None)
|
||||
if pos_mapping:
|
||||
values = [k for k,v in pos_mapping.items() if v and UIPC in v]
|
||||
assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC, values)
|
||||
USE = USE + values[0]
|
||||
|
||||
out[U] = (USE, UBlock)
|
||||
return out
|
||||
|
||||
defaults = ('O', 'No_Block')
|
||||
data = map_to_use(data)
|
||||
|
||||
# Remove the outliers
|
||||
singles = {}
|
||||
for u in [0x034F, 0x25CC, 0x1107F]:
|
||||
singles[u] = data[u]
|
||||
del data[u]
|
||||
|
||||
print "/* == Start of generated table == */"
|
||||
print "/*"
|
||||
print " * The following table is generated by running:"
|
||||
print " *"
|
||||
print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt"
|
||||
print " *"
|
||||
print " * on files with these headers:"
|
||||
print " *"
|
||||
for h in headers:
|
||||
for l in h:
|
||||
print " * %s" % (l.strip())
|
||||
print " */"
|
||||
print
|
||||
print '#include "hb-ot-shape-complex-use-private.hh"'
|
||||
print
|
||||
|
||||
total = 0
|
||||
used = 0
|
||||
last_block = None
|
||||
def print_block (block, start, end, data):
|
||||
global total, used, last_block
|
||||
if block and block != last_block:
|
||||
print
|
||||
print
|
||||
print " /* %s */" % block
|
||||
if start % 16:
|
||||
print ' ' * (20 + (start % 16 * 6)),
|
||||
num = 0
|
||||
assert start % 8 == 0
|
||||
assert (end+1) % 8 == 0
|
||||
for u in range (start, end+1):
|
||||
if u % 16 == 0:
|
||||
print
|
||||
print " /* %04X */" % u,
|
||||
if u in data:
|
||||
num += 1
|
||||
d = data.get (u, defaults)
|
||||
sys.stdout.write ("%6s," % d[0])
|
||||
|
||||
total += end - start + 1
|
||||
used += num
|
||||
if block:
|
||||
last_block = block
|
||||
|
||||
uu = data.keys ()
|
||||
uu.sort ()
|
||||
|
||||
last = -100000
|
||||
num = 0
|
||||
offset = 0
|
||||
starts = []
|
||||
ends = []
|
||||
for k,v in sorted(use_mapping.items()):
|
||||
if k in use_positions and use_positions[k]: continue
|
||||
print "#define %s USE_%s /* %s */" % (k, k, v.__name__[3:])
|
||||
for k,v in sorted(use_positions.items()):
|
||||
if not v: continue
|
||||
for suf in v.keys():
|
||||
tag = k + suf
|
||||
print "#define %s USE_%s" % (tag, tag)
|
||||
print ""
|
||||
print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {"
|
||||
for u in uu:
|
||||
if u <= last:
|
||||
continue
|
||||
block = data[u][1]
|
||||
|
||||
start = u//8*8
|
||||
end = start+1
|
||||
while end in uu and block == data[end][1]:
|
||||
end += 1
|
||||
end = (end-1)//8*8 + 7
|
||||
|
||||
if start != last + 1:
|
||||
if start - last <= 1+16*3:
|
||||
print_block (None, last+1, start-1, data)
|
||||
last = start-1
|
||||
else:
|
||||
if last >= 0:
|
||||
ends.append (last + 1)
|
||||
offset += ends[-1] - starts[-1]
|
||||
print
|
||||
print
|
||||
print "#define use_offset_0x%04xu %d" % (start, offset)
|
||||
starts.append (start)
|
||||
|
||||
print_block (block, start, end, data)
|
||||
last = end
|
||||
ends.append (last + 1)
|
||||
offset += ends[-1] - starts[-1]
|
||||
print
|
||||
print
|
||||
occupancy = used * 100. / total
|
||||
page_bits = 12
|
||||
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
|
||||
print
|
||||
print "USE_TABLE_ELEMENT_TYPE"
|
||||
print "hb_use_get_categories (hb_codepoint_t u)"
|
||||
print "{"
|
||||
print " switch (u >> %d)" % page_bits
|
||||
print " {"
|
||||
pages = set([u>>page_bits for u in starts+ends+singles.keys()])
|
||||
for p in sorted(pages):
|
||||
print " case 0x%0Xu:" % p
|
||||
for (start,end) in zip (starts, ends):
|
||||
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||
offset = "use_offset_0x%04xu" % start
|
||||
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
|
||||
for u,d in singles.items ():
|
||||
if p != u>>page_bits: continue
|
||||
print " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0])
|
||||
print " break;"
|
||||
print ""
|
||||
print " default:"
|
||||
print " break;"
|
||||
print " }"
|
||||
print " return USE_O;"
|
||||
print "}"
|
||||
print
|
||||
for k in sorted(use_mapping.keys()):
|
||||
if k in use_positions and use_positions[k]: continue
|
||||
print "#undef %s" % k
|
||||
for k,v in sorted(use_positions.items()):
|
||||
if not v: continue
|
||||
for suf in v.keys():
|
||||
tag = k + suf
|
||||
print "#undef %s" % tag
|
||||
print
|
||||
print "/* == End of generated table == */"
|
||||
|
||||
# Maintain at least 50% occupancy in the table */
|
||||
if occupancy < 50:
|
||||
raise Exception ("Table too sparse, please investigate: ", occupancy)
|
||||
12
gfx/harfbuzz/src/harfbuzz-gobject.pc.in
Normal file
12
gfx/harfbuzz/src/harfbuzz-gobject.pc.in
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
prefix=%prefix%
|
||||
exec_prefix=%exec_prefix%
|
||||
libdir=%libdir%
|
||||
includedir=%includedir%
|
||||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library GObject integration
|
||||
Version: %VERSION%
|
||||
|
||||
Requires: harfbuzz gobject-2.0 glib-2.0
|
||||
Libs: -L${libdir} -lharfbuzz-gobject
|
||||
Cflags: -I${includedir}/harfbuzz
|
||||
13
gfx/harfbuzz/src/harfbuzz-icu.pc
Normal file
13
gfx/harfbuzz/src/harfbuzz-icu.pc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
prefix=/usr/local
|
||||
exec_prefix=/usr/local
|
||||
libdir=/usr/local/lib
|
||||
includedir=/usr/local/include
|
||||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library ICU integration
|
||||
Version: 1.4.1
|
||||
|
||||
Requires: harfbuzz
|
||||
Requires.private: icu-uc
|
||||
Libs: -L${libdir} -lharfbuzz-icu
|
||||
Cflags: -I${includedir}/harfbuzz
|
||||
13
gfx/harfbuzz/src/harfbuzz-icu.pc.in
Normal file
13
gfx/harfbuzz/src/harfbuzz-icu.pc.in
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
prefix=%prefix%
|
||||
exec_prefix=%exec_prefix%
|
||||
libdir=%libdir%
|
||||
includedir=%includedir%
|
||||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library ICU integration
|
||||
Version: %VERSION%
|
||||
|
||||
Requires: harfbuzz
|
||||
Requires.private: icu-uc
|
||||
Libs: -L${libdir} -lharfbuzz-icu
|
||||
Cflags: -I${includedir}/harfbuzz
|
||||
13
gfx/harfbuzz/src/harfbuzz.pc
Normal file
13
gfx/harfbuzz/src/harfbuzz.pc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
prefix=/usr/local
|
||||
exec_prefix=/usr/local
|
||||
libdir=/usr/local/lib
|
||||
includedir=/usr/local/include
|
||||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library
|
||||
Version: 1.4.1
|
||||
|
||||
Libs: -L${libdir} -lharfbuzz
|
||||
Libs.private:
|
||||
Requires.private: glib-2.0 >= 2.19.1
|
||||
Cflags: -I${includedir}/harfbuzz
|
||||
13
gfx/harfbuzz/src/harfbuzz.pc.in
Normal file
13
gfx/harfbuzz/src/harfbuzz.pc.in
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
prefix=%prefix%
|
||||
exec_prefix=%exec_prefix%
|
||||
libdir=%libdir%
|
||||
includedir=%includedir%
|
||||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library
|
||||
Version: %VERSION%
|
||||
|
||||
Libs: -L${libdir} -lharfbuzz
|
||||
Libs.private: %libs_private%
|
||||
Requires.private: %requires_private%
|
||||
Cflags: -I${includedir}/harfbuzz
|
||||
189
gfx/harfbuzz/src/hb-atomic-private.hh
Normal file
189
gfx/harfbuzz/src/hb-atomic-private.hh
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_ATOMIC_PRIVATE_HH
|
||||
#define HB_ATOMIC_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* atomic_int */
|
||||
|
||||
/* We need external help for these */
|
||||
|
||||
#if defined(hb_atomic_int_impl_add) \
|
||||
&& defined(hb_atomic_ptr_impl_get) \
|
||||
&& defined(hb_atomic_ptr_impl_cmpexch)
|
||||
|
||||
/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* MinGW has a convoluted history of supporting MemoryBarrier
|
||||
* properly. As such, define a function to wrap the whole
|
||||
* thing. */
|
||||
static inline void _HBMemoryBarrier (void) {
|
||||
#if !defined(MemoryBarrier)
|
||||
long dummy = 0;
|
||||
InterlockedExchange (&dummy, 1);
|
||||
#else
|
||||
MemoryBarrier ();
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef LONG hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||
|
||||
#include <libkern/OSAtomic.h>
|
||||
#ifdef __MAC_OS_X_MIN_REQUIRED
|
||||
#include <AvailabilityMacros.h>
|
||||
#elif defined(__IPHONE_OS_MIN_REQUIRED)
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef int32_t hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P))
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#else
|
||||
#if __ppc64__ || __x86_64__ || __aarch64__
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#else
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
|
||||
|
||||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
|
||||
typedef unsigned int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
|
||||
|
||||
#include <builtins.h>
|
||||
|
||||
|
||||
static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) {
|
||||
__lwsync();
|
||||
int result = __fetch_and_add(AI, V);
|
||||
__isync();
|
||||
return result;
|
||||
}
|
||||
static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) {
|
||||
__sync();
|
||||
int result = __compare_and_swaplp (P, &O, N);
|
||||
__sync();
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
|
||||
typedef volatile int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
|
||||
|
||||
|
||||
#else /* HB_NO_MT */
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)}
|
||||
|
||||
struct hb_atomic_int_t
|
||||
{
|
||||
hb_atomic_int_impl_t v;
|
||||
|
||||
inline void set_unsafe (int v_) { v = v_; }
|
||||
inline int get_unsafe (void) const { return v; }
|
||||
inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); }
|
||||
inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); }
|
||||
};
|
||||
|
||||
|
||||
#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
|
||||
|
||||
|
||||
#endif /* HB_ATOMIC_PRIVATE_HH */
|
||||
478
gfx/harfbuzz/src/hb-blob.cc
Normal file
478
gfx/harfbuzz/src/hb-blob.cc
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <sys/mman.h>
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_BLOB
|
||||
#define HB_DEBUG_BLOB (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_blob_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
bool immutable;
|
||||
|
||||
const char *data;
|
||||
unsigned int length;
|
||||
hb_memory_mode_t mode;
|
||||
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
};
|
||||
|
||||
|
||||
static bool _try_writable (hb_blob_t *blob);
|
||||
|
||||
static void
|
||||
_hb_blob_destroy_user_data (hb_blob_t *blob)
|
||||
{
|
||||
if (blob->destroy) {
|
||||
blob->destroy (blob->user_data);
|
||||
blob->user_data = NULL;
|
||||
blob->destroy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_create: (skip)
|
||||
* @data: Pointer to blob data.
|
||||
* @length: Length of @data in bytes.
|
||||
* @mode: Memory mode for @data.
|
||||
* @user_data: Data parameter to pass to @destroy.
|
||||
* @destroy: Callback to call when @data is not needed anymore.
|
||||
*
|
||||
* Creates a new "blob" object wrapping @data. The @mode parameter is used
|
||||
* to negotiate ownership and lifecycle of @data.
|
||||
*
|
||||
* Return value: New blob, or the empty blob if something failed or if @length is
|
||||
* zero. Destroy with hb_blob_destroy().
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_blob_create (const char *data,
|
||||
unsigned int length,
|
||||
hb_memory_mode_t mode,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (!length ||
|
||||
length >= 1u << 31 ||
|
||||
!(blob = hb_object_create<hb_blob_t> ())) {
|
||||
if (destroy)
|
||||
destroy (user_data);
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
|
||||
blob->data = data;
|
||||
blob->length = length;
|
||||
blob->mode = mode;
|
||||
|
||||
blob->user_data = user_data;
|
||||
blob->destroy = destroy;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
|
||||
blob->mode = HB_MEMORY_MODE_READONLY;
|
||||
if (!_try_writable (blob)) {
|
||||
hb_blob_destroy (blob);
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_create_sub_blob:
|
||||
* @parent: Parent blob.
|
||||
* @offset: Start offset of sub-blob within @parent, in bytes.
|
||||
* @length: Length of sub-blob.
|
||||
*
|
||||
* Returns a blob that represents a range of bytes in @parent. The new
|
||||
* blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
|
||||
* will never modify data in the parent blob. The parent data is not
|
||||
* expected to be modified, and will result in undefined behavior if it
|
||||
* is.
|
||||
*
|
||||
* Makes @parent immutable.
|
||||
*
|
||||
* Return value: New blob, or the empty blob if something failed or if
|
||||
* @length is zero or @offset is beyond the end of @parent's data. Destroy
|
||||
* with hb_blob_destroy().
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_blob_create_sub_blob (hb_blob_t *parent,
|
||||
unsigned int offset,
|
||||
unsigned int length)
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (!length || offset >= parent->length)
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
hb_blob_make_immutable (parent);
|
||||
|
||||
blob = hb_blob_create (parent->data + offset,
|
||||
MIN (length, parent->length - offset),
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
hb_blob_reference (parent),
|
||||
(hb_destroy_func_t) hb_blob_destroy);
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_get_empty:
|
||||
*
|
||||
* Returns the singleton empty blob.
|
||||
*
|
||||
* See TODO:link object types for more information.
|
||||
*
|
||||
* Return value: (transfer full): the empty blob.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_blob_get_empty (void)
|
||||
{
|
||||
static const hb_blob_t _hb_blob_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
true, /* immutable */
|
||||
|
||||
NULL, /* data */
|
||||
0, /* length */
|
||||
HB_MEMORY_MODE_READONLY, /* mode */
|
||||
|
||||
NULL, /* user_data */
|
||||
NULL /* destroy */
|
||||
};
|
||||
|
||||
return const_cast<hb_blob_t *> (&_hb_blob_nil);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_reference: (skip)
|
||||
* @blob: a blob.
|
||||
*
|
||||
* Increases the reference count on @blob.
|
||||
*
|
||||
* See TODO:link object types for more information.
|
||||
*
|
||||
* Return value: @blob.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_blob_reference (hb_blob_t *blob)
|
||||
{
|
||||
return hb_object_reference (blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_destroy: (skip)
|
||||
* @blob: a blob.
|
||||
*
|
||||
* Descreases the reference count on @blob, and if it reaches zero, destroys
|
||||
* @blob, freeing all memory, possibly calling the destroy-callback the blob
|
||||
* was created for if it has not been called already.
|
||||
*
|
||||
* See TODO:link object types for more information.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_blob_destroy (hb_blob_t *blob)
|
||||
{
|
||||
if (!hb_object_destroy (blob)) return;
|
||||
|
||||
_hb_blob_destroy_user_data (blob);
|
||||
|
||||
free (blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_set_user_data: (skip)
|
||||
* @blob: a blob.
|
||||
* @key: key for data to set.
|
||||
* @data: data to set.
|
||||
* @destroy: callback to call when @data is not needed anymore.
|
||||
* @replace: whether to replace an existing data with the same key.
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_blob_set_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (blob, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_get_user_data: (skip)
|
||||
* @blob: a blob.
|
||||
* @key: key for data to get.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void *
|
||||
hb_blob_get_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (blob, key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_blob_make_immutable:
|
||||
* @blob: a blob.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_blob_make_immutable (hb_blob_t *blob)
|
||||
{
|
||||
if (hb_object_is_inert (blob))
|
||||
return;
|
||||
|
||||
blob->immutable = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_is_immutable:
|
||||
* @blob: a blob.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: TODO
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_blob_is_immutable (hb_blob_t *blob)
|
||||
{
|
||||
return blob->immutable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_blob_get_length:
|
||||
* @blob: a blob.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: the length of blob data in bytes.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
unsigned int
|
||||
hb_blob_get_length (hb_blob_t *blob)
|
||||
{
|
||||
return blob->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_get_data:
|
||||
* @blob: a blob.
|
||||
* @length: (out):
|
||||
*
|
||||
*
|
||||
*
|
||||
* Returns: (transfer none) (array length=length):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
const char *
|
||||
hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
|
||||
{
|
||||
if (length)
|
||||
*length = blob->length;
|
||||
|
||||
return blob->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_get_data_writable:
|
||||
* @blob: a blob.
|
||||
* @length: (out): output length of the writable data.
|
||||
*
|
||||
* Tries to make blob data writable (possibly copying it) and
|
||||
* return pointer to data.
|
||||
*
|
||||
* Fails if blob has been made immutable, or if memory allocation
|
||||
* fails.
|
||||
*
|
||||
* Returns: (transfer none) (array length=length): Writable blob data,
|
||||
* or %NULL if failed.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
char *
|
||||
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
|
||||
{
|
||||
if (!_try_writable (blob)) {
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length)
|
||||
*length = blob->length;
|
||||
|
||||
return const_cast<char *> (blob->data);
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_try_make_writable_inplace_unix (hb_blob_t *blob)
|
||||
{
|
||||
#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
|
||||
uintptr_t pagesize = -1, mask, length;
|
||||
const char *addr;
|
||||
|
||||
#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
|
||||
pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
|
||||
#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
|
||||
pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
|
||||
#elif defined(HAVE_GETPAGESIZE)
|
||||
pagesize = (uintptr_t) getpagesize ();
|
||||
#endif
|
||||
|
||||
if ((uintptr_t) -1L == pagesize) {
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
|
||||
return false;
|
||||
}
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
|
||||
|
||||
mask = ~(pagesize-1);
|
||||
addr = (const char *) (((uintptr_t) blob->data) & mask);
|
||||
length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
|
||||
DEBUG_MSG_FUNC (BLOB, blob,
|
||||
"calling mprotect on [%p..%p] (%lu bytes)",
|
||||
addr, addr+length, (unsigned long) length);
|
||||
if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
blob->mode = HB_MEMORY_MODE_WRITABLE;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob,
|
||||
"successfully made [%p..%p] (%lu bytes) writable\n",
|
||||
addr, addr+length, (unsigned long) length);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
_try_writable_inplace (hb_blob_t *blob)
|
||||
{
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
|
||||
|
||||
if (_try_make_writable_inplace_unix (blob))
|
||||
return true;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
|
||||
|
||||
/* Failed to make writable inplace, mark that */
|
||||
blob->mode = HB_MEMORY_MODE_READONLY;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
_try_writable (hb_blob_t *blob)
|
||||
{
|
||||
if (blob->immutable)
|
||||
return false;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_WRITABLE)
|
||||
return true;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
|
||||
return true;
|
||||
|
||||
if (blob->mode == HB_MEMORY_MODE_WRITABLE)
|
||||
return true;
|
||||
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
|
||||
|
||||
char *new_data;
|
||||
|
||||
new_data = (char *) malloc (blob->length);
|
||||
if (unlikely (!new_data))
|
||||
return false;
|
||||
|
||||
DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
|
||||
|
||||
memcpy (new_data, blob->data, blob->length);
|
||||
_hb_blob_destroy_user_data (blob);
|
||||
blob->mode = HB_MEMORY_MODE_WRITABLE;
|
||||
blob->data = new_data;
|
||||
blob->user_data = new_data;
|
||||
blob->destroy = free;
|
||||
|
||||
return true;
|
||||
}
|
||||
126
gfx/harfbuzz/src/hb-blob.h
Normal file
126
gfx/harfbuzz/src/hb-blob.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_BLOB_H
|
||||
#define HB_BLOB_H
|
||||
|
||||
#include "hb-common.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Note re various memory-modes:
|
||||
*
|
||||
* - In no case shall the HarfBuzz client modify memory
|
||||
* that is passed to HarfBuzz in a blob. If there is
|
||||
* any such possibility, MODE_DUPLICATE should be used
|
||||
* such that HarfBuzz makes a copy immediately,
|
||||
*
|
||||
* - Use MODE_READONLY otherse, unless you really really
|
||||
* really know what you are doing,
|
||||
*
|
||||
* - MODE_WRITABLE is appropriate if you really made a
|
||||
* copy of data solely for the purpose of passing to
|
||||
* HarfBuzz and doing that just once (no reuse!),
|
||||
*
|
||||
* - If the font is mmap()ed, it's ok to use
|
||||
* READONLY_MAY_MAKE_WRITABLE, however, using that mode
|
||||
* correctly is very tricky. Use MODE_READONLY instead.
|
||||
*/
|
||||
typedef enum {
|
||||
HB_MEMORY_MODE_DUPLICATE,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
|
||||
} hb_memory_mode_t;
|
||||
|
||||
typedef struct hb_blob_t hb_blob_t;
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_blob_create (const char *data,
|
||||
unsigned int length,
|
||||
hb_memory_mode_t mode,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* Always creates with MEMORY_MODE_READONLY.
|
||||
* Even if the parent blob is writable, we don't
|
||||
* want the user of the sub-blob to be able to
|
||||
* modify the parent data as that data may be
|
||||
* shared among multiple sub-blobs.
|
||||
*/
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_blob_create_sub_blob (hb_blob_t *parent,
|
||||
unsigned int offset,
|
||||
unsigned int length);
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_blob_get_empty (void);
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_blob_reference (hb_blob_t *blob);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_blob_destroy (hb_blob_t *blob);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_blob_set_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_blob_get_user_data (hb_blob_t *blob,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_blob_make_immutable (hb_blob_t *blob);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_blob_is_immutable (hb_blob_t *blob);
|
||||
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_blob_get_length (hb_blob_t *blob);
|
||||
|
||||
HB_EXTERN const char *
|
||||
hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
|
||||
|
||||
HB_EXTERN char *
|
||||
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_BLOB_H */
|
||||
643
gfx/harfbuzz/src/hb-buffer-deserialize-json.hh
Normal file
643
gfx/harfbuzz/src/hb-buffer-deserialize-json.hh
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
|
||||
#line 1 "hb-buffer-deserialize-json.rl"
|
||||
/*
|
||||
* Copyright © 2013 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_BUFFER_DESERIALIZE_JSON_HH
|
||||
#define HB_BUFFER_DESERIALIZE_JSON_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-json.hh"
|
||||
static const unsigned char _deserialize_json_trans_keys[] = {
|
||||
0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
|
||||
48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
||||
9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
|
||||
120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
|
||||
9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
|
||||
65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_json_key_spans[] = {
|
||||
0, 115, 26, 7, 2, 1, 50, 49,
|
||||
10, 117, 117, 117, 1, 50, 49, 10,
|
||||
117, 117, 1, 1, 50, 49, 117, 117,
|
||||
2, 1, 50, 49, 10, 117, 117, 1,
|
||||
50, 49, 10, 117, 117, 1, 50, 49,
|
||||
58, 89, 117, 117, 85, 115, 0
|
||||
};
|
||||
|
||||
static const short _deserialize_json_index_offsets[] = {
|
||||
0, 0, 116, 143, 151, 154, 156, 207,
|
||||
257, 268, 386, 504, 622, 624, 675, 725,
|
||||
736, 854, 972, 974, 976, 1027, 1077, 1195,
|
||||
1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
|
||||
1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
|
||||
2119, 2178, 2268, 2386, 2504, 2590, 2706
|
||||
};
|
||||
|
||||
static const char _deserialize_json_indicies[] = {
|
||||
0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 2, 1, 3, 3, 3,
|
||||
3, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 3, 1, 4, 1,
|
||||
5, 1, 6, 7, 1, 1, 8, 1,
|
||||
9, 10, 1, 11, 1, 11, 11, 11,
|
||||
11, 11, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 11, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 12, 1,
|
||||
12, 12, 12, 12, 12, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 12,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 13, 1, 1, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 1, 16, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 1, 18, 18, 18,
|
||||
18, 18, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 18, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
19, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 20, 1, 21, 21, 21, 21, 21,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 21, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 3, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 22,
|
||||
1, 18, 18, 18, 18, 18, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
18, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 19, 1, 1, 1,
|
||||
17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 20, 1, 23,
|
||||
1, 23, 23, 23, 23, 23, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
23, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 24, 1, 24, 24, 24, 24,
|
||||
24, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 24, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
25, 1, 1, 26, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 1, 28, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29,
|
||||
1, 30, 30, 30, 30, 30, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
30, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 31, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 32, 1, 30,
|
||||
30, 30, 30, 30, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 30, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 31, 1, 1, 1, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 32, 1, 33, 1, 34,
|
||||
1, 34, 34, 34, 34, 34, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
34, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 35, 1, 35, 35, 35, 35,
|
||||
35, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 35, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 36, 37, 37, 37, 37,
|
||||
37, 37, 37, 37, 37, 1, 38, 38,
|
||||
38, 38, 38, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 38, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 39, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 40, 1, 38, 38, 38, 38,
|
||||
38, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 38, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 39,
|
||||
1, 1, 1, 41, 41, 41, 41, 41,
|
||||
41, 41, 41, 41, 41, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
40, 1, 42, 43, 1, 44, 1, 44,
|
||||
44, 44, 44, 44, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 44, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
45, 1, 45, 45, 45, 45, 45, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 45, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 46, 1,
|
||||
1, 47, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 1, 49, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 1, 51,
|
||||
51, 51, 51, 51, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 51, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 52, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 53, 1, 51, 51, 51,
|
||||
51, 51, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 51, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
52, 1, 1, 1, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 53, 1, 54, 1, 54, 54, 54,
|
||||
54, 54, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 54, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 55, 1,
|
||||
55, 55, 55, 55, 55, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 55,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 56, 1, 1, 57,
|
||||
58, 58, 58, 58, 58, 58, 58, 58,
|
||||
58, 1, 59, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 1, 61, 61, 61,
|
||||
61, 61, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 61, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
62, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 63, 1, 61, 61, 61, 61, 61,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 61, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 62, 1,
|
||||
1, 1, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 63,
|
||||
1, 64, 1, 64, 64, 64, 64, 64,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 64, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 65, 1, 65, 65,
|
||||
65, 65, 65, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 65, 1, 66,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 67, 68, 68,
|
||||
68, 68, 68, 68, 68, 68, 68, 1,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 1, 1, 1, 1, 1, 1,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 69, 69, 69, 69, 69, 69,
|
||||
69, 69, 1, 70, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 71, 71,
|
||||
1, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 1, 1, 1, 1, 1,
|
||||
1, 1, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 1, 1, 1, 1,
|
||||
71, 1, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 71, 71, 71, 71,
|
||||
71, 71, 71, 71, 1, 72, 72, 72,
|
||||
72, 72, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 72, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
73, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 74, 1, 72, 72, 72, 72, 72,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 72, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 73, 1,
|
||||
1, 1, 75, 75, 75, 75, 75, 75,
|
||||
75, 75, 75, 75, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 74,
|
||||
1, 76, 76, 76, 76, 76, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
76, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 77, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 78, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 1, 1, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_json_trans_targs[] = {
|
||||
1, 0, 2, 2, 3, 4, 18, 24,
|
||||
37, 5, 12, 6, 7, 8, 9, 11,
|
||||
9, 11, 10, 2, 44, 10, 44, 13,
|
||||
14, 15, 16, 17, 16, 17, 10, 2,
|
||||
44, 19, 20, 21, 22, 23, 10, 2,
|
||||
44, 23, 25, 31, 26, 27, 28, 29,
|
||||
30, 29, 30, 10, 2, 44, 32, 33,
|
||||
34, 35, 36, 35, 36, 10, 2, 44,
|
||||
38, 39, 40, 42, 43, 41, 10, 41,
|
||||
10, 2, 44, 43, 44, 45, 46
|
||||
};
|
||||
|
||||
static const char _deserialize_json_trans_actions[] = {
|
||||
0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 2, 2, 2,
|
||||
0, 0, 3, 3, 4, 0, 5, 0,
|
||||
0, 2, 2, 2, 0, 0, 6, 6,
|
||||
7, 0, 0, 0, 2, 2, 8, 8,
|
||||
9, 0, 0, 0, 0, 0, 2, 2,
|
||||
2, 0, 0, 10, 10, 11, 0, 0,
|
||||
2, 2, 2, 0, 0, 12, 12, 13,
|
||||
0, 0, 0, 2, 2, 2, 14, 0,
|
||||
15, 15, 16, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const int deserialize_json_start = 1;
|
||||
static const int deserialize_json_first_final = 44;
|
||||
static const int deserialize_json_error = 0;
|
||||
|
||||
static const int deserialize_json_en_main = 1;
|
||||
|
||||
|
||||
#line 97 "hb-buffer-deserialize-json.rl"
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? ',' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 466 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
cs = deserialize_json_start;
|
||||
}
|
||||
|
||||
#line 471 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _deserialize_json_trans_keys + (cs<<1);
|
||||
_inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs];
|
||||
|
||||
_slen = _deserialize_json_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _deserialize_json_trans_targs[_trans];
|
||||
|
||||
if ( _deserialize_json_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _deserialize_json_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 38 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
#line 51 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
#line 55 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
#line 62 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||
break;
|
||||
case 8:
|
||||
#line 63 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
break;
|
||||
case 10:
|
||||
#line 64 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
break;
|
||||
case 12:
|
||||
#line 65 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
break;
|
||||
case 3:
|
||||
#line 66 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
break;
|
||||
case 6:
|
||||
#line 67 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
break;
|
||||
case 16:
|
||||
#line 62 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 63 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
#line 65 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
#line 66 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
#line 67 "hb-buffer-deserialize-json.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 624 "hb-buffer-deserialize-json.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 125 "hb-buffer-deserialize-json.rl"
|
||||
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
|
||||
132
gfx/harfbuzz/src/hb-buffer-deserialize-json.rl
Normal file
132
gfx/harfbuzz/src/hb-buffer-deserialize-json.rl
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright © 2013 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_BUFFER_DESERIALIZE_JSON_HH
|
||||
#define HB_BUFFER_DESERIALIZE_JSON_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
%%{
|
||||
|
||||
machine deserialize_json;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
|
||||
action clear_item {
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
|
||||
action add_item {
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
|
||||
action tok {
|
||||
tok = p;
|
||||
}
|
||||
|
||||
action parse_glyph {
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
|
||||
action parse_gid { if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||
action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
|
||||
unum = '0' | [1-9] digit*;
|
||||
num = '-'? unum;
|
||||
|
||||
comma = space* ',' space*;
|
||||
colon = space* ':' space*;
|
||||
|
||||
glyph_id = unum;
|
||||
glyph_name = alpha (alnum|'_'|'.'|'-')*;
|
||||
|
||||
glyph_string = '"' (glyph_name >tok %parse_glyph) '"';
|
||||
glyph_number = (glyph_id >tok %parse_gid);
|
||||
|
||||
glyph = "\"g\"" colon (glyph_string | glyph_number);
|
||||
cluster = "\"cl\"" colon (unum >tok %parse_cluster);
|
||||
xoffset = "\"dx\"" colon (num >tok %parse_x_offset);
|
||||
yoffset = "\"dy\"" colon (num >tok %parse_y_offset);
|
||||
xadvance= "\"ax\"" colon (num >tok %parse_x_advance);
|
||||
yadvance= "\"ay\"" colon (num >tok %parse_y_advance);
|
||||
|
||||
element = glyph | cluster | xoffset | yoffset | xadvance | yadvance;
|
||||
item =
|
||||
( '{' space* element (comma element)* space* '}')
|
||||
>clear_item
|
||||
@add_item
|
||||
;
|
||||
|
||||
main := space* item (comma item)* space* (','|']')?;
|
||||
|
||||
}%%
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? ',' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
%%{
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
|
||||
571
gfx/harfbuzz/src/hb-buffer-deserialize-text.hh
Normal file
571
gfx/harfbuzz/src/hb-buffer-deserialize-text.hh
Normal file
|
|
@ -0,0 +1,571 @@
|
|||
|
||||
#line 1 "hb-buffer-deserialize-text.rl"
|
||||
/*
|
||||
* Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_HH
|
||||
#define HB_BUFFER_DESERIALIZE_TEXT_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-text.hh"
|
||||
static const unsigned char _deserialize_text_trans_keys[] = {
|
||||
0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
|
||||
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
|
||||
9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
|
||||
9u, 124u, 9u, 124u, 9u, 124u, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_key_spans[] = {
|
||||
0, 114, 13, 10, 13, 10, 10, 13,
|
||||
10, 1, 13, 10, 14, 116, 116, 0,
|
||||
114, 116, 116, 116, 116, 116, 116, 116,
|
||||
116, 116, 116
|
||||
};
|
||||
|
||||
static const short _deserialize_text_index_offsets[] = {
|
||||
0, 0, 115, 129, 140, 154, 165, 176,
|
||||
190, 201, 203, 217, 228, 243, 360, 477,
|
||||
478, 593, 710, 827, 944, 1061, 1178, 1295,
|
||||
1412, 1529, 1646
|
||||
};
|
||||
|
||||
static const char _deserialize_text_indicies[] = {
|
||||
0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 1, 1, 1, 1, 1,
|
||||
1, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 1, 5, 1, 1, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 1, 8, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 1, 10, 1, 1,
|
||||
11, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 1, 13, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 1, 15, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16,
|
||||
1, 17, 1, 1, 18, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 1, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 1, 22, 1, 23, 1, 1, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 1, 26, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 1, 22, 1, 1,
|
||||
1, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 1, 28, 28, 28, 28,
|
||||
28, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 28, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 29, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
30, 1, 1, 31, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
32, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 33,
|
||||
1, 34, 34, 34, 34, 34, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
34, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 35, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 36, 1, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
1, 1, 1, 1, 1, 1, 1, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 1, 1, 1, 1, 1, 1, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 1, 28, 28, 28, 28, 28, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 28, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 29, 1, 1, 1,
|
||||
1, 37, 37, 37, 37, 37, 37, 37,
|
||||
37, 37, 37, 1, 1, 1, 30, 1,
|
||||
1, 31, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 32, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 33, 1, 38,
|
||||
38, 38, 38, 38, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 38, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 39, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 40, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 41, 1, 42, 42, 42, 42,
|
||||
42, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 42, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
43, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 44,
|
||||
1, 42, 42, 42, 42, 42, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
42, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 43, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 44, 1, 38, 38,
|
||||
38, 38, 38, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 38, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 39, 1, 1, 1, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 40, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 41, 1, 45, 45, 45, 45, 45,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 45, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 46, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 47, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 48,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 49, 1,
|
||||
50, 50, 50, 50, 50, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 50,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 51, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 52, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 53, 1, 50, 50, 50,
|
||||
50, 50, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 50, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 51,
|
||||
1, 1, 1, 1, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 52, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
53, 1, 45, 45, 45, 45, 45, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 45, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 46, 1, 1, 1,
|
||||
1, 54, 54, 54, 54, 54, 54, 54,
|
||||
54, 54, 54, 1, 1, 1, 1, 1,
|
||||
1, 47, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 48, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 49, 1, 28,
|
||||
28, 28, 28, 28, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 28, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 29, 1, 55, 55, 1, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
1, 1, 1, 30, 1, 1, 31, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 1, 1, 32, 1, 55, 1, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 55, 55, 55, 55, 55, 55, 55,
|
||||
55, 1, 33, 1, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_trans_targs[] = {
|
||||
1, 0, 13, 17, 26, 3, 18, 21,
|
||||
18, 21, 5, 19, 20, 19, 20, 22,
|
||||
25, 8, 9, 12, 9, 12, 10, 11,
|
||||
23, 24, 23, 24, 14, 2, 6, 7,
|
||||
15, 16, 14, 15, 16, 17, 14, 4,
|
||||
15, 16, 14, 15, 16, 14, 2, 7,
|
||||
15, 16, 14, 2, 15, 16, 25, 26
|
||||
};
|
||||
|
||||
static const char _deserialize_text_trans_actions[] = {
|
||||
0, 0, 1, 1, 1, 2, 2, 2,
|
||||
0, 0, 2, 2, 2, 0, 0, 2,
|
||||
2, 2, 2, 2, 0, 0, 3, 2,
|
||||
2, 2, 0, 0, 4, 5, 5, 5,
|
||||
4, 4, 0, 0, 0, 0, 6, 7,
|
||||
6, 6, 8, 8, 8, 9, 10, 10,
|
||||
9, 9, 11, 12, 11, 11, 0, 0
|
||||
};
|
||||
|
||||
static const char _deserialize_text_eof_actions[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 4, 0, 0,
|
||||
0, 4, 6, 8, 8, 6, 9, 11,
|
||||
11, 9, 4
|
||||
};
|
||||
|
||||
static const int deserialize_text_start = 1;
|
||||
static const int deserialize_text_first_final = 13;
|
||||
static const int deserialize_text_error = 0;
|
||||
|
||||
static const int deserialize_text_en_main = 1;
|
||||
|
||||
|
||||
#line 91 "hb-buffer-deserialize-text.rl"
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? '|' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *eof = pe, *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 343 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
cs = deserialize_text_start;
|
||||
}
|
||||
|
||||
#line 348 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _deserialize_text_trans_keys + (cs<<1);
|
||||
_inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
|
||||
|
||||
_slen = _deserialize_text_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _deserialize_text_trans_targs[_trans];
|
||||
|
||||
if ( _deserialize_text_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _deserialize_text_trans_actions[_trans] ) {
|
||||
case 2:
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
break;
|
||||
case 3:
|
||||
#line 63 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
break;
|
||||
case 12:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
break;
|
||||
case 7:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
break;
|
||||
case 1:
|
||||
#line 38 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
#line 66 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 480 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
if ( p == eof )
|
||||
{
|
||||
switch ( _deserialize_text_eof_actions[cs] ) {
|
||||
case 4:
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
#line 62 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
#line 64 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
#line 65 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
#line 66 "hb-buffer-deserialize-text.rl"
|
||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 557 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
}
|
||||
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 119 "hb-buffer-deserialize-text.rl"
|
||||
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
|
||||
126
gfx/harfbuzz/src/hb-buffer-deserialize-text.rl
Normal file
126
gfx/harfbuzz/src/hb-buffer-deserialize-text.rl
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright © 2013 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_BUFFER_DESERIALIZE_TEXT_HH
|
||||
#define HB_BUFFER_DESERIALIZE_TEXT_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
%%{
|
||||
|
||||
machine deserialize_text;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
|
||||
action clear_item {
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
|
||||
action add_item {
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
return false;
|
||||
buffer->pos[buffer->len - 1] = pos;
|
||||
*end_ptr = p;
|
||||
}
|
||||
|
||||
action tok {
|
||||
tok = p;
|
||||
}
|
||||
|
||||
action parse_glyph {
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
|
||||
action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||
action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||
action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||
action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||
action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||
|
||||
unum = '0' | [1-9] digit*;
|
||||
num = '-'? unum;
|
||||
|
||||
glyph_id = unum;
|
||||
glyph_name = alpha (alnum|'_'|'.'|'-')*;
|
||||
|
||||
glyph = (glyph_id | glyph_name) >tok %parse_glyph;
|
||||
cluster = '=' (unum >tok %parse_cluster);
|
||||
offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset );
|
||||
advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?;
|
||||
item =
|
||||
(
|
||||
glyph
|
||||
cluster?
|
||||
offsets?
|
||||
advances?
|
||||
)
|
||||
>clear_item
|
||||
%add_item
|
||||
;
|
||||
|
||||
main := space* item (space* '|' space* item)* space* ('|'|']')?;
|
||||
|
||||
}%%
|
||||
|
||||
static hb_bool_t
|
||||
_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
unsigned int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font)
|
||||
{
|
||||
const char *p = buf, *pe = buf + buf_len;
|
||||
|
||||
/* Ensure we have positions. */
|
||||
(void) hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
if (p < pe && *p == (buffer->len ? '|' : '['))
|
||||
{
|
||||
*end_ptr = ++p;
|
||||
}
|
||||
|
||||
const char *eof = pe, *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
%%{
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
*end_ptr = p;
|
||||
|
||||
return p == pe && *(p-1) != ']';
|
||||
}
|
||||
|
||||
#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
|
||||
296
gfx/harfbuzz/src/hb-buffer-private.hh
Normal file
296
gfx/harfbuzz/src/hb-buffer-private.hh
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
* Copyright © 2004,2007,2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_BUFFER_PRIVATE_HH
|
||||
#define HB_BUFFER_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
|
||||
#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR
|
||||
#define HB_BUFFER_MAX_EXPANSION_FACTOR 32
|
||||
#endif
|
||||
#ifndef HB_BUFFER_MAX_LEN_MIN
|
||||
#define HB_BUFFER_MAX_LEN_MIN 8192
|
||||
#endif
|
||||
#ifndef HB_BUFFER_MAX_LEN_DEFAULT
|
||||
#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
|
||||
#endif
|
||||
|
||||
ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
|
||||
ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
|
||||
|
||||
HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
|
||||
HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
|
||||
|
||||
enum hb_buffer_scratch_flags_t {
|
||||
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
|
||||
/* Reserved for complex shapers' internal use. */
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u,
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u,
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u,
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t);
|
||||
|
||||
|
||||
/*
|
||||
* hb_buffer_t
|
||||
*/
|
||||
|
||||
struct hb_buffer_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
/* Information about how the text in the buffer should be treated */
|
||||
hb_unicode_funcs_t *unicode; /* Unicode functions */
|
||||
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
||||
hb_buffer_cluster_level_t cluster_level;
|
||||
hb_codepoint_t replacement; /* U+FFFD or something else. */
|
||||
hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */
|
||||
unsigned int max_len; /* Maximum allowed len. */
|
||||
|
||||
/* Buffer contents */
|
||||
hb_buffer_content_type_t content_type;
|
||||
hb_segment_properties_t props; /* Script, language, direction */
|
||||
|
||||
bool in_error; /* Allocation failed */
|
||||
bool have_output; /* Whether we have an output buffer going on */
|
||||
bool have_positions; /* Whether we have positions */
|
||||
|
||||
unsigned int idx; /* Cursor into ->info and ->pos arrays */
|
||||
unsigned int len; /* Length of ->info and ->pos arrays */
|
||||
unsigned int out_len; /* Length of ->out array if have_output */
|
||||
|
||||
unsigned int allocated; /* Length of allocated arrays */
|
||||
hb_glyph_info_t *info;
|
||||
hb_glyph_info_t *out_info;
|
||||
hb_glyph_position_t *pos;
|
||||
|
||||
inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
|
||||
inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
|
||||
|
||||
inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
|
||||
inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
|
||||
|
||||
inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
|
||||
inline bool has_separate_output (void) const { return info != out_info; }
|
||||
|
||||
unsigned int serial;
|
||||
|
||||
/* Text before / after the main buffer contents.
|
||||
* Always in Unicode, and ordered outward.
|
||||
* Index 0 is for "pre-context", 1 for "post-context". */
|
||||
static const unsigned int CONTEXT_LENGTH = 5;
|
||||
hb_codepoint_t context[2][CONTEXT_LENGTH];
|
||||
unsigned int context_len[2];
|
||||
|
||||
/* Debugging API */
|
||||
hb_buffer_message_func_t message_func;
|
||||
void *message_data;
|
||||
hb_destroy_func_t message_destroy;
|
||||
|
||||
/* Internal debugging. */
|
||||
/* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
|
||||
#ifndef HB_NDEBUG
|
||||
uint8_t allocated_var_bits;
|
||||
#endif
|
||||
inline void allocate_var (unsigned int start, unsigned int count)
|
||||
{
|
||||
#ifndef HB_NDEBUG
|
||||
unsigned int end = start + count;
|
||||
assert (end <= 8);
|
||||
unsigned int bits = (1u<<end) - (1u<<start);
|
||||
assert (0 == (allocated_var_bits & bits));
|
||||
allocated_var_bits |= bits;
|
||||
#endif
|
||||
}
|
||||
inline void deallocate_var (unsigned int start, unsigned int count)
|
||||
{
|
||||
#ifndef HB_NDEBUG
|
||||
unsigned int end = start + count;
|
||||
assert (end <= 8);
|
||||
unsigned int bits = (1u<<end) - (1u<<start);
|
||||
assert (bits == (allocated_var_bits & bits));
|
||||
allocated_var_bits &= ~bits;
|
||||
#endif
|
||||
}
|
||||
inline void assert_var (unsigned int start, unsigned int count)
|
||||
{
|
||||
#ifndef HB_NDEBUG
|
||||
unsigned int end = start + count;
|
||||
assert (end <= 8);
|
||||
unsigned int bits = (1u<<end) - (1u<<start);
|
||||
assert (bits == (allocated_var_bits & bits));
|
||||
#endif
|
||||
}
|
||||
inline void deallocate_var_all (void)
|
||||
{
|
||||
#ifndef HB_NDEBUG
|
||||
allocated_var_bits = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
HB_INTERNAL void reset (void);
|
||||
HB_INTERNAL void clear (void);
|
||||
|
||||
inline unsigned int backtrack_len (void) const
|
||||
{ return have_output? out_len : idx; }
|
||||
inline unsigned int lookahead_len (void) const
|
||||
{ return len - idx; }
|
||||
inline unsigned int next_serial (void) { return serial++; }
|
||||
|
||||
HB_INTERNAL void add (hb_codepoint_t codepoint,
|
||||
unsigned int cluster);
|
||||
HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
|
||||
|
||||
HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
|
||||
HB_INTERNAL void reverse (void);
|
||||
HB_INTERNAL void reverse_clusters (void);
|
||||
HB_INTERNAL void guess_segment_properties (void);
|
||||
|
||||
HB_INTERNAL void swap_buffers (void);
|
||||
HB_INTERNAL void remove_output (void);
|
||||
HB_INTERNAL void clear_output (void);
|
||||
HB_INTERNAL void clear_positions (void);
|
||||
|
||||
HB_INTERNAL void replace_glyphs (unsigned int num_in,
|
||||
unsigned int num_out,
|
||||
const hb_codepoint_t *glyph_data);
|
||||
|
||||
HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
|
||||
/* Makes a copy of the glyph at idx to output and replace glyph_index */
|
||||
HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
|
||||
HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
|
||||
/* Copies glyph at idx to output but doesn't advance idx */
|
||||
HB_INTERNAL void copy_glyph (void);
|
||||
HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
|
||||
/* Copies glyph at idx to output and advance idx.
|
||||
* If there's no output, just advance idx. */
|
||||
inline void
|
||||
next_glyph (void)
|
||||
{
|
||||
if (have_output)
|
||||
{
|
||||
if (unlikely (out_info != info || out_len != idx)) {
|
||||
if (unlikely (!make_room_for (1, 1))) return;
|
||||
out_info[out_len] = info[idx];
|
||||
}
|
||||
out_len++;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* Advance idx without copying to output. */
|
||||
inline void skip_glyph (void) { idx++; }
|
||||
|
||||
inline void reset_masks (hb_mask_t mask)
|
||||
{
|
||||
for (unsigned int j = 0; j < len; j++)
|
||||
info[j].mask = mask;
|
||||
}
|
||||
inline void add_masks (hb_mask_t mask)
|
||||
{
|
||||
for (unsigned int j = 0; j < len; j++)
|
||||
info[j].mask |= mask;
|
||||
}
|
||||
HB_INTERNAL void set_masks (hb_mask_t value,
|
||||
hb_mask_t mask,
|
||||
unsigned int cluster_start,
|
||||
unsigned int cluster_end);
|
||||
|
||||
HB_INTERNAL void merge_clusters (unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
if (end - start < 2)
|
||||
return;
|
||||
merge_clusters_impl (start, end);
|
||||
}
|
||||
HB_INTERNAL void merge_clusters_impl (unsigned int start,
|
||||
unsigned int end);
|
||||
HB_INTERNAL void merge_out_clusters (unsigned int start,
|
||||
unsigned int end);
|
||||
/* Merge clusters for deleting current glyph, and skip it. */
|
||||
HB_INTERNAL void delete_glyph (void);
|
||||
|
||||
/* Internal methods */
|
||||
HB_INTERNAL bool enlarge (unsigned int size);
|
||||
|
||||
inline bool ensure (unsigned int size)
|
||||
{ return likely (!size || size < allocated) ? true : enlarge (size); }
|
||||
|
||||
inline bool ensure_inplace (unsigned int size)
|
||||
{ return likely (!size || size < allocated); }
|
||||
|
||||
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
|
||||
HB_INTERNAL bool shift_forward (unsigned int count);
|
||||
|
||||
typedef long scratch_buffer_t;
|
||||
HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
|
||||
|
||||
inline void clear_context (unsigned int side) { context_len[side] = 0; }
|
||||
|
||||
HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
|
||||
|
||||
inline bool messaging (void) { return unlikely (message_func); }
|
||||
inline bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
|
||||
{
|
||||
if (!messaging ())
|
||||
return true;
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
bool ret = message_impl (font, fmt, ap);
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
|
||||
};
|
||||
|
||||
|
||||
#define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
|
||||
b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
|
||||
sizeof (b->info[0].var))
|
||||
#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ())
|
||||
#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ())
|
||||
#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ())
|
||||
|
||||
|
||||
#endif /* HB_BUFFER_PRIVATE_HH */
|
||||
454
gfx/harfbuzz/src/hb-buffer-serialize.cc
Normal file
454
gfx/harfbuzz/src/hb-buffer-serialize.cc
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Copyright © 2012,2013 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
|
||||
*/
|
||||
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
static const char *serialize_formats[] = {
|
||||
"text",
|
||||
"json",
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_list_formats:
|
||||
*
|
||||
* Returns a list of supported buffer serialization formats.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A string array of buffer serialization formats. Should not be freed.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
const char **
|
||||
hb_buffer_serialize_list_formats (void)
|
||||
{
|
||||
return serialize_formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_format_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t): a string to parse
|
||||
* @len: length of @str, or -1 if string is %NULL terminated
|
||||
*
|
||||
* Parses a string into an #hb_buffer_serialize_format_t. Does not check if
|
||||
* @str is a valid buffer serialization format, use
|
||||
* hb_buffer_serialize_list_formats() to get the list of supported formats.
|
||||
*
|
||||
* Return value:
|
||||
* The parsed #hb_buffer_serialize_format_t.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
hb_buffer_serialize_format_t
|
||||
hb_buffer_serialize_format_from_string (const char *str, int len)
|
||||
{
|
||||
/* Upper-case it. */
|
||||
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020u);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_format_to_string:
|
||||
* @format: an #hb_buffer_serialize_format_t to convert.
|
||||
*
|
||||
* Converts @format to the string corresponding it, or %NULL if it is not a valid
|
||||
* #hb_buffer_serialize_format_t.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A %NULL terminated string corresponding to @format. Should not be freed.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
const char *
|
||||
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
|
||||
NULL : hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
*buf_consumed = 0;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
char b[1024];
|
||||
char *p = b;
|
||||
|
||||
/* In the following code, we know b is large enough that no overflow can happen. */
|
||||
|
||||
#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
|
||||
|
||||
if (i)
|
||||
*p++ = ',';
|
||||
|
||||
*p++ = '{';
|
||||
|
||||
APPEND ("\"g\":");
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
|
||||
{
|
||||
char g[128];
|
||||
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
|
||||
*p++ = '"';
|
||||
for (char *q = g; *q; q++) {
|
||||
if (*q == '"')
|
||||
*p++ = '\\';
|
||||
*p++ = *q;
|
||||
}
|
||||
*p++ = '"';
|
||||
}
|
||||
else
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
|
||||
}
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
|
||||
{
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
|
||||
pos[i].x_offset, pos[i].y_offset);
|
||||
p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
|
||||
pos[i].x_advance, pos[i].y_advance);
|
||||
}
|
||||
|
||||
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
|
||||
{
|
||||
hb_glyph_extents_t extents;
|
||||
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
|
||||
extents.x_bearing, extents.y_bearing));
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
|
||||
extents.width, extents.height));
|
||||
}
|
||||
|
||||
*p++ = '}';
|
||||
|
||||
unsigned int l = p - b;
|
||||
if (buf_size > l)
|
||||
{
|
||||
memcpy (buf, b, l);
|
||||
buf += l;
|
||||
buf_size -= l;
|
||||
*buf_consumed += l;
|
||||
*buf = '\0';
|
||||
} else
|
||||
return i - start;
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
|
||||
NULL : hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
|
||||
*buf_consumed = 0;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
char b[1024];
|
||||
char *p = b;
|
||||
|
||||
/* In the following code, we know b is large enough that no overflow can happen. */
|
||||
|
||||
if (i)
|
||||
*p++ = '|';
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
|
||||
{
|
||||
hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
|
||||
p += strlen (p);
|
||||
}
|
||||
else
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
|
||||
}
|
||||
|
||||
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
|
||||
{
|
||||
if (pos[i].x_offset || pos[i].y_offset)
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset));
|
||||
|
||||
*p++ = '+';
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
|
||||
if (pos[i].y_advance)
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
|
||||
}
|
||||
|
||||
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
|
||||
{
|
||||
hb_glyph_extents_t extents;
|
||||
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
|
||||
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
|
||||
}
|
||||
|
||||
unsigned int l = p - b;
|
||||
if (buf_size > l)
|
||||
{
|
||||
memcpy (buf, b, l);
|
||||
buf += l;
|
||||
buf_size -= l;
|
||||
*buf_consumed += l;
|
||||
*buf = '\0';
|
||||
} else
|
||||
return i - start;
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_glyphs:
|
||||
* @buffer: an #hb_buffer_t buffer.
|
||||
* @start: the first item in @buffer to serialize.
|
||||
* @end: the last item in @buffer to serialize.
|
||||
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
|
||||
* write serialized buffer into.
|
||||
* @buf_size: the size of @buf.
|
||||
* @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
|
||||
* @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
|
||||
* read glyph names and extents. If %NULL, and empty font will be used.
|
||||
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
|
||||
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
|
||||
* to serialize.
|
||||
*
|
||||
* Serializes @buffer into a textual representation of its glyph content,
|
||||
* useful for showing the contents of the buffer, for example during debugging.
|
||||
* There are currently two supported serialization formats:
|
||||
*
|
||||
* ## text
|
||||
* A human-readable, plain text format.
|
||||
* The serialized glyphs will look something like:
|
||||
*
|
||||
* ```
|
||||
* [uni0651=0@518,0+0|uni0628=0+1897]
|
||||
* ```
|
||||
* - The serialized glyphs are delimited with `[` and `]`.
|
||||
* - Glyphs are separated with `|`
|
||||
* - Each glyph starts with glyph name, or glyph index if
|
||||
* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then,
|
||||
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster.
|
||||
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:
|
||||
* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,
|
||||
* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,
|
||||
* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the
|
||||
* #hb_glyph_extents_t in the format
|
||||
* `<x_bearing,y_bearing,width,height>`
|
||||
*
|
||||
* ## json
|
||||
* TODO.
|
||||
*
|
||||
* Return value:
|
||||
* The number of serialized items.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
unsigned int
|
||||
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_format_t format,
|
||||
hb_buffer_serialize_flags_t flags)
|
||||
{
|
||||
assert (start <= end && end <= buffer->len);
|
||||
|
||||
unsigned int sconsumed;
|
||||
if (!buf_consumed)
|
||||
buf_consumed = &sconsumed;
|
||||
*buf_consumed = 0;
|
||||
|
||||
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
|
||||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (!buffer->have_positions)
|
||||
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
|
||||
|
||||
if (unlikely (start == end))
|
||||
return 0;
|
||||
|
||||
if (!font)
|
||||
font = hb_font_get_empty ();
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
|
||||
return _hb_buffer_serialize_glyphs_text (buffer, start, end,
|
||||
buf, buf_size, buf_consumed,
|
||||
font, flags);
|
||||
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
|
||||
return _hb_buffer_serialize_glyphs_json (buffer, start, end,
|
||||
buf, buf_size, buf_consumed,
|
||||
font, flags);
|
||||
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
parse_uint (const char *pp, const char *end, uint32_t *pv)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
||||
strncpy (buf, pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
uint32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_int (const char *pp, const char *end, int32_t *pv)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
||||
strncpy (buf, pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
int32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "hb-buffer-deserialize-json.hh"
|
||||
#include "hb-buffer-deserialize-text.hh"
|
||||
|
||||
/**
|
||||
* hb_buffer_deserialize_glyphs:
|
||||
* @buffer: an #hb_buffer_t buffer.
|
||||
* @buf: (array length=buf_len):
|
||||
* @buf_len:
|
||||
* @end_ptr: (out):
|
||||
* @font:
|
||||
* @format:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
int buf_len, /* -1 means nul-terminated */
|
||||
const char **end_ptr, /* May be NULL */
|
||||
hb_font_t *font, /* May be NULL */
|
||||
hb_buffer_serialize_format_t format)
|
||||
{
|
||||
const char *end;
|
||||
if (!end_ptr)
|
||||
end_ptr = &end;
|
||||
*end_ptr = buf;
|
||||
|
||||
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
|
||||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (buf_len == -1)
|
||||
buf_len = strlen (buf);
|
||||
|
||||
if (!buf_len)
|
||||
{
|
||||
*end_ptr = buf;
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
|
||||
|
||||
if (!font)
|
||||
font = hb_font_get_empty ();
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
|
||||
return _hb_buffer_deserialize_glyphs_text (buffer,
|
||||
buf, buf_len, end_ptr,
|
||||
font);
|
||||
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
|
||||
return _hb_buffer_deserialize_glyphs_json (buffer,
|
||||
buf, buf_len, end_ptr,
|
||||
font);
|
||||
|
||||
default:
|
||||
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
1818
gfx/harfbuzz/src/hb-buffer.cc
Normal file
1818
gfx/harfbuzz/src/hb-buffer.cc
Normal file
File diff suppressed because it is too large
Load diff
472
gfx/harfbuzz/src/hb-buffer.h
Normal file
472
gfx/harfbuzz/src/hb-buffer.h
Normal file
|
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
* Copyright © 2004,2007,2009 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Owen Taylor, Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_BUFFER_H
|
||||
#define HB_BUFFER_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-font.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* hb_glyph_info_t:
|
||||
* @codepoint: either a Unicode code point (before shaping) or a glyph index
|
||||
* (after shaping).
|
||||
* @mask:
|
||||
* @cluster: the index of the character in the original text that corresponds
|
||||
* to this #hb_glyph_info_t, or whatever the client passes to
|
||||
* hb_buffer_add(). More than one #hb_glyph_info_t can have the same
|
||||
* @cluster value, if they resulted from the same character (e.g. one
|
||||
* to many glyph substitution), and when more than one character gets
|
||||
* merged in the same glyph (e.g. many to one glyph substitution) the
|
||||
* #hb_glyph_info_t will have the smallest cluster value of them.
|
||||
* By default some characters are merged into the same cluster
|
||||
* (e.g. combining marks have the same cluster as their bases)
|
||||
* even if they are separate glyphs, hb_buffer_set_cluster_level()
|
||||
* allow selecting more fine-grained cluster handling.
|
||||
*
|
||||
* The #hb_glyph_info_t is the structure that holds information about the
|
||||
* glyphs and their relation to input text.
|
||||
*
|
||||
*/
|
||||
typedef struct hb_glyph_info_t {
|
||||
hb_codepoint_t codepoint;
|
||||
hb_mask_t mask;
|
||||
uint32_t cluster;
|
||||
|
||||
/*< private >*/
|
||||
hb_var_int_t var1;
|
||||
hb_var_int_t var2;
|
||||
} hb_glyph_info_t;
|
||||
|
||||
/**
|
||||
* hb_glyph_position_t:
|
||||
* @x_advance: how much the line advances after drawing this glyph when setting
|
||||
* text in horizontal direction.
|
||||
* @y_advance: how much the line advances after drawing this glyph when setting
|
||||
* text in vertical direction.
|
||||
* @x_offset: how much the glyph moves on the X-axis before drawing it, this
|
||||
* should not affect how much the line advances.
|
||||
* @y_offset: how much the glyph moves on the Y-axis before drawing it, this
|
||||
* should not affect how much the line advances.
|
||||
*
|
||||
* The #hb_glyph_position_t is the structure that holds the positions of the
|
||||
* glyph in both horizontal and vertical directions. All positions in
|
||||
* #hb_glyph_position_t are relative to the current point.
|
||||
*
|
||||
*/
|
||||
typedef struct hb_glyph_position_t {
|
||||
hb_position_t x_advance;
|
||||
hb_position_t y_advance;
|
||||
hb_position_t x_offset;
|
||||
hb_position_t y_offset;
|
||||
|
||||
/*< private >*/
|
||||
hb_var_int_t var;
|
||||
} hb_glyph_position_t;
|
||||
|
||||
/**
|
||||
* hb_segment_properties_t:
|
||||
* @direction: the #hb_direction_t of the buffer, see hb_buffer_set_direction().
|
||||
* @script: the #hb_script_t of the buffer, see hb_buffer_set_script().
|
||||
* @language: the #hb_language_t of the buffer, see hb_buffer_set_language().
|
||||
*
|
||||
* The structure that holds various text properties of an #hb_buffer_t. Can be
|
||||
* set and retrieved using hb_buffer_set_segment_properties() and
|
||||
* hb_buffer_get_segment_properties(), respectively.
|
||||
*/
|
||||
typedef struct hb_segment_properties_t {
|
||||
hb_direction_t direction;
|
||||
hb_script_t script;
|
||||
hb_language_t language;
|
||||
/*< private >*/
|
||||
void *reserved1;
|
||||
void *reserved2;
|
||||
} hb_segment_properties_t;
|
||||
|
||||
#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
|
||||
HB_SCRIPT_INVALID, \
|
||||
HB_LANGUAGE_INVALID, \
|
||||
NULL, \
|
||||
NULL}
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_segment_properties_equal (const hb_segment_properties_t *a,
|
||||
const hb_segment_properties_t *b);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_segment_properties_hash (const hb_segment_properties_t *p);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* hb_buffer_t:
|
||||
*
|
||||
* The main structure holding the input text and its properties before shaping,
|
||||
* and output glyphs and their information after shaping.
|
||||
*/
|
||||
|
||||
typedef struct hb_buffer_t hb_buffer_t;
|
||||
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_create (void);
|
||||
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_get_empty (void);
|
||||
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_reference (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_destroy (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_buffer_get_user_data (hb_buffer_t *buffer,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
/**
|
||||
* hb_buffer_content_type_t:
|
||||
* @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer.
|
||||
* @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping).
|
||||
* @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping).
|
||||
*/
|
||||
typedef enum {
|
||||
HB_BUFFER_CONTENT_TYPE_INVALID = 0,
|
||||
HB_BUFFER_CONTENT_TYPE_UNICODE,
|
||||
HB_BUFFER_CONTENT_TYPE_GLYPHS
|
||||
} hb_buffer_content_type_t;
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_content_type (hb_buffer_t *buffer,
|
||||
hb_buffer_content_type_t content_type);
|
||||
|
||||
HB_EXTERN hb_buffer_content_type_t
|
||||
hb_buffer_get_content_type (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
|
||||
hb_unicode_funcs_t *unicode_funcs);
|
||||
|
||||
HB_EXTERN hb_unicode_funcs_t *
|
||||
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_direction (hb_buffer_t *buffer,
|
||||
hb_direction_t direction);
|
||||
|
||||
HB_EXTERN hb_direction_t
|
||||
hb_buffer_get_direction (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_script (hb_buffer_t *buffer,
|
||||
hb_script_t script);
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_buffer_get_script (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_language (hb_buffer_t *buffer,
|
||||
hb_language_t language);
|
||||
|
||||
|
||||
HB_EXTERN hb_language_t
|
||||
hb_buffer_get_language (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
|
||||
const hb_segment_properties_t *props);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
|
||||
hb_segment_properties_t *props);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/**
|
||||
* hb_buffer_flags_t:
|
||||
* @HB_BUFFER_FLAG_DEFAULT: the default buffer flag.
|
||||
* @HB_BUFFER_FLAG_BOT: flag indicating that special handling of the beginning
|
||||
* of text paragraph can be applied to this buffer. Should usually
|
||||
* be set, unless you are passing to the buffer only part
|
||||
* of the text without the full context.
|
||||
* @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text
|
||||
* paragraph can be applied to this buffer, similar to
|
||||
* @HB_BUFFER_FLAG_EOT.
|
||||
* @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES:
|
||||
* flag indication that character with Default_Ignorable
|
||||
* Unicode property should use the corresponding glyph
|
||||
* from the font, instead of hiding them (currently done
|
||||
* by replacing them with the space glyph and zeroing the
|
||||
* advance width.)
|
||||
*
|
||||
* Since: 0.9.20
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
HB_BUFFER_FLAG_DEFAULT = 0x00000000u,
|
||||
HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
|
||||
HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
|
||||
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
|
||||
} hb_buffer_flags_t;
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_flags (hb_buffer_t *buffer,
|
||||
hb_buffer_flags_t flags);
|
||||
|
||||
HB_EXTERN hb_buffer_flags_t
|
||||
hb_buffer_get_flags (hb_buffer_t *buffer);
|
||||
|
||||
/*
|
||||
* Since: 0.9.42
|
||||
*/
|
||||
typedef enum {
|
||||
HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0,
|
||||
HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1,
|
||||
HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2,
|
||||
HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES
|
||||
} hb_buffer_cluster_level_t;
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_cluster_level (hb_buffer_t *buffer,
|
||||
hb_buffer_cluster_level_t cluster_level);
|
||||
|
||||
HB_EXTERN hb_buffer_cluster_level_t
|
||||
hb_buffer_get_cluster_level (hb_buffer_t *buffer);
|
||||
|
||||
/**
|
||||
* HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT:
|
||||
*
|
||||
* The default code point for replacing invalid characters in a given encoding.
|
||||
* Set to U+FFFD REPLACEMENT CHARACTER.
|
||||
*
|
||||
* Since: 0.9.31
|
||||
*/
|
||||
#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
|
||||
hb_codepoint_t replacement);
|
||||
|
||||
HB_EXTERN hb_codepoint_t
|
||||
hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reset (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_clear_contents (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_buffer_pre_allocate (hb_buffer_t *buffer,
|
||||
unsigned int size);
|
||||
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_buffer_allocation_successful (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reverse (hb_buffer_t *buffer);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reverse_range (hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/* Filling the buffer in */
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add (hb_buffer_t *buffer,
|
||||
hb_codepoint_t codepoint,
|
||||
unsigned int cluster);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add_utf8 (hb_buffer_t *buffer,
|
||||
const char *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add_utf16 (hb_buffer_t *buffer,
|
||||
const uint16_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
||||
const uint32_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add_latin1 (hb_buffer_t *buffer,
|
||||
const uint8_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
||||
const hb_codepoint_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
int item_length);
|
||||
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_buffer_set_length (hb_buffer_t *buffer,
|
||||
unsigned int length);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_buffer_get_length (hb_buffer_t *buffer);
|
||||
|
||||
/* Getting glyphs out of the buffer */
|
||||
|
||||
HB_EXTERN hb_glyph_info_t *
|
||||
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
|
||||
unsigned int *length);
|
||||
|
||||
HB_EXTERN hb_glyph_position_t *
|
||||
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
|
||||
unsigned int *length);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
/*
|
||||
* Serialize
|
||||
*/
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_flags_t:
|
||||
* @HB_BUFFER_SERIALIZE_FLAG_DEFAULT: serialize glyph names, clusters and positions.
|
||||
* @HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS: do not serialize glyph cluster.
|
||||
* @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information.
|
||||
* @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name.
|
||||
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents.
|
||||
*
|
||||
* Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
|
||||
*
|
||||
* Since: 0.9.20
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u,
|
||||
HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u
|
||||
} hb_buffer_serialize_flags_t;
|
||||
|
||||
/**
|
||||
* hb_buffer_serialize_format_t:
|
||||
* @HB_BUFFER_SERIALIZE_FORMAT_TEXT: a human-readable, plain text format.
|
||||
* @HB_BUFFER_SERIALIZE_FORMAT_JSON: a machine-readable JSON format.
|
||||
* @HB_BUFFER_SERIALIZE_FORMAT_INVALID: invalid format.
|
||||
*
|
||||
* The buffer serialization and de-serialization format used in
|
||||
* hb_buffer_serialize_glyphs() and hb_buffer_deserialize_glyphs().
|
||||
*
|
||||
* Since: 0.9.2
|
||||
*/
|
||||
typedef enum {
|
||||
HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'),
|
||||
HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'),
|
||||
HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE
|
||||
} hb_buffer_serialize_format_t;
|
||||
|
||||
HB_EXTERN hb_buffer_serialize_format_t
|
||||
hb_buffer_serialize_format_from_string (const char *str, int len);
|
||||
|
||||
HB_EXTERN const char *
|
||||
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
|
||||
|
||||
HB_EXTERN const char **
|
||||
hb_buffer_serialize_list_formats (void);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
char *buf,
|
||||
unsigned int buf_size,
|
||||
unsigned int *buf_consumed,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_format_t format,
|
||||
hb_buffer_serialize_flags_t flags);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
|
||||
const char *buf,
|
||||
int buf_len,
|
||||
const char **end_ptr,
|
||||
hb_font_t *font,
|
||||
hb_buffer_serialize_format_t format);
|
||||
|
||||
|
||||
/*
|
||||
* Debugging.
|
||||
*/
|
||||
|
||||
typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer,
|
||||
hb_font_t *font,
|
||||
const char *message,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_set_message_func (hb_buffer_t *buffer,
|
||||
hb_buffer_message_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_BUFFER_H */
|
||||
74
gfx/harfbuzz/src/hb-cache-private.hh
Normal file
74
gfx/harfbuzz/src/hb-cache-private.hh
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright © 2012 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_CACHE_PRIVATE_HH
|
||||
#define HB_CACHE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* Implements a lock-free cache for int->int functions. */
|
||||
|
||||
template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
|
||||
struct hb_cache_t
|
||||
{
|
||||
ASSERT_STATIC (key_bits >= cache_bits);
|
||||
ASSERT_STATIC (key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int));
|
||||
|
||||
inline void clear (void)
|
||||
{
|
||||
memset (values, 255, sizeof (values));
|
||||
}
|
||||
|
||||
inline bool get (unsigned int key, unsigned int *value)
|
||||
{
|
||||
unsigned int k = key & ((1u<<cache_bits)-1);
|
||||
unsigned int v = values[k];
|
||||
if ((v >> value_bits) != (key >> cache_bits))
|
||||
return false;
|
||||
*value = v & ((1u<<value_bits)-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool set (unsigned int key, unsigned int value)
|
||||
{
|
||||
if (unlikely ((key >> key_bits) || (value >> value_bits)))
|
||||
return false; /* Overflows */
|
||||
unsigned int k = key & ((1u<<cache_bits)-1);
|
||||
unsigned int v = ((key>>cache_bits)<<value_bits) | value;
|
||||
values[k] = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int values[1u<<cache_bits];
|
||||
};
|
||||
|
||||
typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
|
||||
typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
|
||||
|
||||
|
||||
#endif /* HB_CACHE_PRIVATE_HH */
|
||||
607
gfx/harfbuzz/src/hb-common.cc
Normal file
607
gfx/harfbuzz/src/hb-common.cc
Normal file
|
|
@ -0,0 +1,607 @@
|
|||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-mutex-private.hh"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
/* hb_options_t */
|
||||
|
||||
hb_options_union_t _hb_options;
|
||||
|
||||
void
|
||||
_hb_options_init (void)
|
||||
{
|
||||
hb_options_union_t u;
|
||||
u.i = 0;
|
||||
u.opts.initialized = 1;
|
||||
|
||||
char *c = getenv ("HB_OPTIONS");
|
||||
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
|
||||
|
||||
/* This is idempotent and threadsafe. */
|
||||
_hb_options = u;
|
||||
}
|
||||
|
||||
|
||||
/* hb_tag_t */
|
||||
|
||||
/**
|
||||
* hb_tag_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_tag_t
|
||||
hb_tag_from_string (const char *str, int len)
|
||||
{
|
||||
char tag[4];
|
||||
unsigned int i;
|
||||
|
||||
if (!str || !len || !*str)
|
||||
return HB_TAG_NONE;
|
||||
|
||||
if (len < 0 || len > 4)
|
||||
len = 4;
|
||||
for (i = 0; i < (unsigned) len && str[i]; i++)
|
||||
tag[i] = str[i];
|
||||
for (; i < 4; i++)
|
||||
tag[i] = ' ';
|
||||
|
||||
return HB_TAG_CHAR4 (tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_tag_to_string:
|
||||
* @tag:
|
||||
* @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.5
|
||||
**/
|
||||
void
|
||||
hb_tag_to_string (hb_tag_t tag, char *buf)
|
||||
{
|
||||
buf[0] = (char) (uint8_t) (tag >> 24);
|
||||
buf[1] = (char) (uint8_t) (tag >> 16);
|
||||
buf[2] = (char) (uint8_t) (tag >> 8);
|
||||
buf[3] = (char) (uint8_t) (tag >> 0);
|
||||
}
|
||||
|
||||
|
||||
/* hb_direction_t */
|
||||
|
||||
const char direction_strings[][4] = {
|
||||
"ltr",
|
||||
"rtl",
|
||||
"ttb",
|
||||
"btt"
|
||||
};
|
||||
|
||||
/**
|
||||
* hb_direction_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_direction_t
|
||||
hb_direction_from_string (const char *str, int len)
|
||||
{
|
||||
if (unlikely (!str || !len || !*str))
|
||||
return HB_DIRECTION_INVALID;
|
||||
|
||||
/* Lets match loosely: just match the first letter, such that
|
||||
* all of "ltr", "left-to-right", etc work!
|
||||
*/
|
||||
char c = TOLOWER (str[0]);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++)
|
||||
if (c == direction_strings[i][0])
|
||||
return (hb_direction_t) (HB_DIRECTION_LTR + i);
|
||||
|
||||
return HB_DIRECTION_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_direction_to_string:
|
||||
* @direction:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
const char *
|
||||
hb_direction_to_string (hb_direction_t direction)
|
||||
{
|
||||
if (likely ((unsigned int) (direction - HB_DIRECTION_LTR)
|
||||
< ARRAY_LENGTH (direction_strings)))
|
||||
return direction_strings[direction - HB_DIRECTION_LTR];
|
||||
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
|
||||
/* hb_language_t */
|
||||
|
||||
struct hb_language_impl_t {
|
||||
const char s[1];
|
||||
};
|
||||
|
||||
static const char canon_map[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
|
||||
'-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
|
||||
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static bool
|
||||
lang_equal (hb_language_t v1,
|
||||
const void *v2)
|
||||
{
|
||||
const unsigned char *p1 = (const unsigned char *) v1;
|
||||
const unsigned char *p2 = (const unsigned char *) v2;
|
||||
|
||||
while (*p1 && *p1 == canon_map[*p2])
|
||||
p1++, p2++;
|
||||
|
||||
return *p1 == canon_map[*p2];
|
||||
}
|
||||
|
||||
#if 0
|
||||
static unsigned int
|
||||
lang_hash (const void *key)
|
||||
{
|
||||
const unsigned char *p = key;
|
||||
unsigned int h = 0;
|
||||
while (canon_map[*p])
|
||||
{
|
||||
h = (h << 5) - h + canon_map[*p];
|
||||
p++;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_language_item_t {
|
||||
|
||||
struct hb_language_item_t *next;
|
||||
hb_language_t lang;
|
||||
|
||||
inline bool operator == (const char *s) const {
|
||||
return lang_equal (lang, s);
|
||||
}
|
||||
|
||||
inline hb_language_item_t & operator = (const char *s) {
|
||||
lang = (hb_language_t) strdup (s);
|
||||
for (unsigned char *p = (unsigned char *) lang; *p; p++)
|
||||
*p = canon_map[*p];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void finish (void) { free ((void *) lang); }
|
||||
};
|
||||
|
||||
|
||||
/* Thread-safe lock-free language list */
|
||||
|
||||
static hb_language_item_t *langs;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_langs (void)
|
||||
{
|
||||
while (langs) {
|
||||
hb_language_item_t *next = langs->next;
|
||||
langs->finish ();
|
||||
free (langs);
|
||||
langs = next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static hb_language_item_t *
|
||||
lang_find_or_insert (const char *key)
|
||||
{
|
||||
retry:
|
||||
hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
|
||||
|
||||
for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
|
||||
if (*lang == key)
|
||||
return lang;
|
||||
|
||||
/* Not found; allocate one. */
|
||||
hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
|
||||
if (unlikely (!lang))
|
||||
return NULL;
|
||||
lang->next = first_lang;
|
||||
*lang = key;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
|
||||
lang->finish ();
|
||||
free (lang);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
if (!first_lang)
|
||||
atexit (free_langs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_language_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t): a string representing
|
||||
* ISO 639 language code
|
||||
* @len: length of the @str, or -1 if it is %NULL-terminated.
|
||||
*
|
||||
* Converts @str representing an ISO 639 language code to the corresponding
|
||||
* #hb_language_t.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* The #hb_language_t corresponding to the ISO 639 language code.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_language_t
|
||||
hb_language_from_string (const char *str, int len)
|
||||
{
|
||||
if (!str || !len || !*str)
|
||||
return HB_LANGUAGE_INVALID;
|
||||
|
||||
hb_language_item_t *item = NULL;
|
||||
if (len >= 0)
|
||||
{
|
||||
/* NUL-terminate it. */
|
||||
char strbuf[64];
|
||||
len = MIN (len, (int) sizeof (strbuf) - 1);
|
||||
memcpy (strbuf, str, len);
|
||||
strbuf[len] = '\0';
|
||||
item = lang_find_or_insert (strbuf);
|
||||
}
|
||||
else
|
||||
item = lang_find_or_insert (str);
|
||||
|
||||
return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_language_to_string:
|
||||
* @language: an #hb_language_t to convert.
|
||||
*
|
||||
* See hb_language_from_string().
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* A %NULL-terminated string representing the @language. Must not be freed by
|
||||
* the caller.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
const char *
|
||||
hb_language_to_string (hb_language_t language)
|
||||
{
|
||||
/* This is actually NULL-safe! */
|
||||
return language->s;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_language_get_default:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_language_t
|
||||
hb_language_get_default (void)
|
||||
{
|
||||
static hb_language_t default_language = HB_LANGUAGE_INVALID;
|
||||
|
||||
hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
|
||||
if (unlikely (language == HB_LANGUAGE_INVALID)) {
|
||||
language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
|
||||
(void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
|
||||
}
|
||||
|
||||
return default_language;
|
||||
}
|
||||
|
||||
|
||||
/* hb_script_t */
|
||||
|
||||
/**
|
||||
* hb_script_from_iso15924_tag:
|
||||
* @tag: an #hb_tag_t representing an ISO 15924 tag.
|
||||
*
|
||||
* Converts an ISO 15924 script tag to a corresponding #hb_script_t.
|
||||
*
|
||||
* Return value:
|
||||
* An #hb_script_t corresponding to the ISO 15924 tag.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_script_t
|
||||
hb_script_from_iso15924_tag (hb_tag_t tag)
|
||||
{
|
||||
if (unlikely (tag == HB_TAG_NONE))
|
||||
return HB_SCRIPT_INVALID;
|
||||
|
||||
/* Be lenient, adjust case (one capital letter followed by three small letters) */
|
||||
tag = (tag & 0xDFDFDFDFu) | 0x00202020u;
|
||||
|
||||
switch (tag) {
|
||||
|
||||
/* These graduated from the 'Q' private-area codes, but
|
||||
* the old code is still aliased by Unicode, and the Qaai
|
||||
* one in use by ICU. */
|
||||
case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
|
||||
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
|
||||
|
||||
/* Script variants from http://unicode.org/iso15924/ */
|
||||
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
|
||||
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
|
||||
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
|
||||
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
|
||||
case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
|
||||
case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
|
||||
}
|
||||
|
||||
/* If it looks right, just use the tag as a script */
|
||||
if (((uint32_t) tag & 0xE0E0E0E0u) == 0x40606060u)
|
||||
return (hb_script_t) tag;
|
||||
|
||||
/* Otherwise, return unknown */
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_script_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t): a string representing an
|
||||
* ISO 15924 tag.
|
||||
* @len: length of the @str, or -1 if it is %NULL-terminated.
|
||||
*
|
||||
* Converts a string @str representing an ISO 15924 script tag to a
|
||||
* corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
|
||||
* hb_script_from_iso15924_tag().
|
||||
*
|
||||
* Return value:
|
||||
* An #hb_script_t corresponding to the ISO 15924 tag.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_script_t
|
||||
hb_script_from_string (const char *str, int len)
|
||||
{
|
||||
return hb_script_from_iso15924_tag (hb_tag_from_string (str, len));
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_script_to_iso15924_tag:
|
||||
* @script: an #hb_script_ to convert.
|
||||
*
|
||||
* See hb_script_from_iso15924_tag().
|
||||
*
|
||||
* Return value:
|
||||
* An #hb_tag_t representing an ISO 15924 script tag.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_tag_t
|
||||
hb_script_to_iso15924_tag (hb_script_t script)
|
||||
{
|
||||
return (hb_tag_t) script;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_script_get_horizontal_direction:
|
||||
* @script:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_direction_t
|
||||
hb_script_get_horizontal_direction (hb_script_t script)
|
||||
{
|
||||
/* http://goo.gl/x9ilM */
|
||||
switch ((hb_tag_t) script)
|
||||
{
|
||||
/* Unicode-1.1 additions */
|
||||
case HB_SCRIPT_ARABIC:
|
||||
case HB_SCRIPT_HEBREW:
|
||||
|
||||
/* Unicode-3.0 additions */
|
||||
case HB_SCRIPT_SYRIAC:
|
||||
case HB_SCRIPT_THAANA:
|
||||
|
||||
/* Unicode-4.0 additions */
|
||||
case HB_SCRIPT_CYPRIOT:
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_KHAROSHTHI:
|
||||
|
||||
/* Unicode-5.0 additions */
|
||||
case HB_SCRIPT_PHOENICIAN:
|
||||
case HB_SCRIPT_NKO:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
case HB_SCRIPT_LYDIAN:
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
case HB_SCRIPT_AVESTAN:
|
||||
case HB_SCRIPT_IMPERIAL_ARAMAIC:
|
||||
case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
|
||||
case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
|
||||
case HB_SCRIPT_OLD_SOUTH_ARABIAN:
|
||||
case HB_SCRIPT_OLD_TURKIC:
|
||||
case HB_SCRIPT_SAMARITAN:
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
case HB_SCRIPT_MANDAIC:
|
||||
|
||||
/* Unicode-6.1 additions */
|
||||
case HB_SCRIPT_MEROITIC_CURSIVE:
|
||||
case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
|
||||
|
||||
/* Unicode-7.0 additions */
|
||||
case HB_SCRIPT_MANICHAEAN:
|
||||
case HB_SCRIPT_MENDE_KIKAKUI:
|
||||
case HB_SCRIPT_NABATAEAN:
|
||||
case HB_SCRIPT_OLD_NORTH_ARABIAN:
|
||||
case HB_SCRIPT_PALMYRENE:
|
||||
case HB_SCRIPT_PSALTER_PAHLAVI:
|
||||
|
||||
/* Unicode-8.0 additions */
|
||||
case HB_SCRIPT_OLD_HUNGARIAN:
|
||||
|
||||
/* Unicode-9.0 additions */
|
||||
case HB_SCRIPT_ADLAM:
|
||||
|
||||
return HB_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
return HB_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
|
||||
/* hb_user_data_array_t */
|
||||
|
||||
bool
|
||||
hb_user_data_array_t::set (hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
if (replace) {
|
||||
if (!data && !destroy) {
|
||||
items.remove (key, lock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
hb_user_data_item_t item = {key, data, destroy};
|
||||
bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
hb_user_data_array_t::get (hb_user_data_key_t *key)
|
||||
{
|
||||
hb_user_data_item_t item = {NULL, NULL, NULL};
|
||||
|
||||
return items.find (key, &item, lock) ? item.data : NULL;
|
||||
}
|
||||
|
||||
|
||||
/* hb_version */
|
||||
|
||||
/**
|
||||
* hb_version:
|
||||
* @major: (out): Library major version component.
|
||||
* @minor: (out): Library minor version component.
|
||||
* @micro: (out): Library micro version component.
|
||||
*
|
||||
* Returns library version as three integer components.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_version (unsigned int *major,
|
||||
unsigned int *minor,
|
||||
unsigned int *micro)
|
||||
{
|
||||
*major = HB_VERSION_MAJOR;
|
||||
*minor = HB_VERSION_MINOR;
|
||||
*micro = HB_VERSION_MICRO;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_version_string:
|
||||
*
|
||||
* Returns library version as a string with three components.
|
||||
*
|
||||
* Return value: library version string.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
const char *
|
||||
hb_version_string (void)
|
||||
{
|
||||
return HB_VERSION_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_version_atleast:
|
||||
* @major:
|
||||
* @minor:
|
||||
* @micro:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.30
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_version_atleast (unsigned int major,
|
||||
unsigned int minor,
|
||||
unsigned int micro)
|
||||
{
|
||||
return HB_VERSION_ATLEAST (major, minor, micro);
|
||||
}
|
||||
367
gfx/harfbuzz/src/hb-common.h
Normal file
367
gfx/harfbuzz/src/hb-common.h
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_COMMON_H
|
||||
#define HB_COMMON_H
|
||||
|
||||
#ifndef HB_BEGIN_DECLS
|
||||
# ifdef __cplusplus
|
||||
# define HB_BEGIN_DECLS extern "C" {
|
||||
# define HB_END_DECLS }
|
||||
# else /* !__cplusplus */
|
||||
# define HB_BEGIN_DECLS
|
||||
# define HB_END_DECLS
|
||||
# endif /* !__cplusplus */
|
||||
#endif
|
||||
|
||||
#if !defined (HB_DONT_DEFINE_STDINT)
|
||||
|
||||
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
|
||||
defined (_sgi) || defined (__sun) || defined (sun) || \
|
||||
defined (__digital__) || defined (__HP_cc)
|
||||
# include <inttypes.h>
|
||||
#elif defined (_AIX)
|
||||
# include <sys/inttypes.h>
|
||||
/* VS 2010 (_MSC_VER 1600) has stdint.h */
|
||||
#elif defined (_MSC_VER) && _MSC_VER < 1600
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef int hb_bool_t;
|
||||
|
||||
typedef uint32_t hb_codepoint_t;
|
||||
typedef int32_t hb_position_t;
|
||||
typedef uint32_t hb_mask_t;
|
||||
|
||||
typedef union _hb_var_int_t {
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
uint16_t u16[2];
|
||||
int16_t i16[2];
|
||||
uint8_t u8[4];
|
||||
int8_t i8[4];
|
||||
} hb_var_int_t;
|
||||
|
||||
|
||||
/* hb_tag_t */
|
||||
|
||||
typedef uint32_t hb_tag_t;
|
||||
|
||||
#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
|
||||
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
|
||||
|
||||
#define HB_TAG_NONE HB_TAG(0,0,0,0)
|
||||
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
|
||||
#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
|
||||
|
||||
/* len=-1 means str is NUL-terminated. */
|
||||
HB_EXTERN hb_tag_t
|
||||
hb_tag_from_string (const char *str, int len);
|
||||
|
||||
/* buf should have 4 bytes. */
|
||||
HB_EXTERN void
|
||||
hb_tag_to_string (hb_tag_t tag, char *buf);
|
||||
|
||||
|
||||
/**
|
||||
* hb_direction_t:
|
||||
* @HB_DIRECTION_INVALID: Initial, unset direction.
|
||||
* @HB_DIRECTION_LTR: Text is set horizontally from left to right.
|
||||
* @HB_DIRECTION_RTL: Text is set horizontally from right to left.
|
||||
* @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
|
||||
* @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
|
||||
*/
|
||||
typedef enum {
|
||||
HB_DIRECTION_INVALID = 0,
|
||||
HB_DIRECTION_LTR = 4,
|
||||
HB_DIRECTION_RTL,
|
||||
HB_DIRECTION_TTB,
|
||||
HB_DIRECTION_BTT
|
||||
} hb_direction_t;
|
||||
|
||||
/* len=-1 means str is NUL-terminated */
|
||||
HB_EXTERN hb_direction_t
|
||||
hb_direction_from_string (const char *str, int len);
|
||||
|
||||
HB_EXTERN const char *
|
||||
hb_direction_to_string (hb_direction_t direction);
|
||||
|
||||
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
|
||||
/* Direction must be valid for the following */
|
||||
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
|
||||
#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
|
||||
#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
|
||||
#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
|
||||
#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
|
||||
|
||||
|
||||
/* hb_language_t */
|
||||
|
||||
typedef const struct hb_language_impl_t *hb_language_t;
|
||||
|
||||
HB_EXTERN hb_language_t
|
||||
hb_language_from_string (const char *str, int len);
|
||||
|
||||
HB_EXTERN const char *
|
||||
hb_language_to_string (hb_language_t language);
|
||||
|
||||
#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
|
||||
|
||||
HB_EXTERN hb_language_t
|
||||
hb_language_get_default (void);
|
||||
|
||||
|
||||
/* hb_script_t */
|
||||
|
||||
/* http://unicode.org/iso15924/ */
|
||||
/* http://goo.gl/x9ilM */
|
||||
/* Unicode Character Database property: Script (sc) */
|
||||
typedef enum
|
||||
{
|
||||
/*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'),
|
||||
/*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'),
|
||||
/*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'),
|
||||
|
||||
/*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'),
|
||||
/*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'),
|
||||
/*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'),
|
||||
/*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'),
|
||||
/*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'),
|
||||
/*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'),
|
||||
/*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'),
|
||||
/*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'),
|
||||
/*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'),
|
||||
/*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'),
|
||||
/*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'),
|
||||
/*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'),
|
||||
/*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'),
|
||||
/*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'),
|
||||
/*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'),
|
||||
/*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'),
|
||||
/*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'),
|
||||
/*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'),
|
||||
/*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'),
|
||||
/*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'),
|
||||
/*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'),
|
||||
/*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'),
|
||||
|
||||
/*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
|
||||
|
||||
/*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'),
|
||||
/*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'),
|
||||
/*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'),
|
||||
/*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'),
|
||||
/*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'),
|
||||
/*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'),
|
||||
/*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'),
|
||||
/*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'),
|
||||
/*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'),
|
||||
/*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'),
|
||||
/*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'),
|
||||
/*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'),
|
||||
/*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'),
|
||||
/*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'),
|
||||
|
||||
/*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'),
|
||||
/*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'),
|
||||
/*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'),
|
||||
|
||||
/*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'),
|
||||
/*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'),
|
||||
/*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'),
|
||||
/*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'),
|
||||
|
||||
/*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'),
|
||||
/*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'),
|
||||
/*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'),
|
||||
/*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'),
|
||||
/*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'),
|
||||
/*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'),
|
||||
/*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'),
|
||||
|
||||
/*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'),
|
||||
/*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'),
|
||||
/*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'),
|
||||
/*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'),
|
||||
/*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'),
|
||||
/*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'),
|
||||
/*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'),
|
||||
/*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'),
|
||||
|
||||
/*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'),
|
||||
/*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'),
|
||||
/*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'),
|
||||
/*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'),
|
||||
/*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'),
|
||||
|
||||
/*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'),
|
||||
/*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'),
|
||||
/*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'),
|
||||
/*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'),
|
||||
/*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'),
|
||||
/*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'),
|
||||
/*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'),
|
||||
/*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'),
|
||||
/*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'),
|
||||
/*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'),
|
||||
/*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'),
|
||||
|
||||
/*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'),
|
||||
/*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'),
|
||||
/*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'),
|
||||
/*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'),
|
||||
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'),
|
||||
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'),
|
||||
/*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'),
|
||||
/*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'),
|
||||
/*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'),
|
||||
/*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'),
|
||||
/*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'),
|
||||
/*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'),
|
||||
/*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'),
|
||||
/*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'),
|
||||
/*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'),
|
||||
|
||||
/*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'),
|
||||
/*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'),
|
||||
/*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'),
|
||||
|
||||
/*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'),
|
||||
/*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'),
|
||||
/*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'),
|
||||
/*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'),
|
||||
/*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'),
|
||||
/*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
|
||||
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
|
||||
|
||||
/*
|
||||
* Since: 0.9.30
|
||||
*/
|
||||
/*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
|
||||
/*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
|
||||
/*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
|
||||
/*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'),
|
||||
/*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'),
|
||||
/*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'),
|
||||
/*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'),
|
||||
/*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'),
|
||||
/*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
|
||||
/*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
|
||||
/*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
|
||||
/*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'),
|
||||
/*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
|
||||
/*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
|
||||
/*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
|
||||
/*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
|
||||
/*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
|
||||
/*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
|
||||
/*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'),
|
||||
/*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
|
||||
/*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'),
|
||||
/*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
|
||||
/*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
|
||||
|
||||
/*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'),
|
||||
/*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'),
|
||||
/*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'),
|
||||
/*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'),
|
||||
/*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'),
|
||||
/*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'),
|
||||
|
||||
/*
|
||||
* Since 1.3.0
|
||||
*/
|
||||
/*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'),
|
||||
/*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'),
|
||||
/*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'),
|
||||
/*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'),
|
||||
/*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'),
|
||||
/*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'),
|
||||
|
||||
/* No script set. */
|
||||
HB_SCRIPT_INVALID = HB_TAG_NONE,
|
||||
|
||||
/* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
|
||||
* without risking undefined behavior. Include both a signed and unsigned max,
|
||||
* since technically enums are int, and indeed, hb_script_t ends up being signed.
|
||||
* See this thread for technicalities:
|
||||
*
|
||||
* http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
|
||||
*/
|
||||
_HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/
|
||||
_HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
|
||||
} hb_script_t;
|
||||
|
||||
|
||||
/* Script functions */
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_script_from_iso15924_tag (hb_tag_t tag);
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_script_from_string (const char *str, int len);
|
||||
|
||||
HB_EXTERN hb_tag_t
|
||||
hb_script_to_iso15924_tag (hb_script_t script);
|
||||
|
||||
HB_EXTERN hb_direction_t
|
||||
hb_script_get_horizontal_direction (hb_script_t script);
|
||||
|
||||
|
||||
/* User data */
|
||||
|
||||
typedef struct hb_user_data_key_t {
|
||||
/*< private >*/
|
||||
char unused;
|
||||
} hb_user_data_key_t;
|
||||
|
||||
typedef void (*hb_destroy_func_t) (void *user_data);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_COMMON_H */
|
||||
1310
gfx/harfbuzz/src/hb-coretext.cc
Normal file
1310
gfx/harfbuzz/src/hb-coretext.cc
Normal file
File diff suppressed because it is too large
Load diff
60
gfx/harfbuzz/src/hb-coretext.h
Normal file
60
gfx/harfbuzz/src/hb-coretext.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright © 2012 Mozilla Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Mozilla Author(s): Jonathan Kew
|
||||
*/
|
||||
|
||||
#ifndef HB_CORETEXT_H
|
||||
#define HB_CORETEXT_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
# include <CoreText/CoreText.h>
|
||||
# include <CoreGraphics/CoreGraphics.h>
|
||||
#else
|
||||
# include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
|
||||
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
|
||||
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_coretext_face_create (CGFontRef cg_font);
|
||||
|
||||
|
||||
HB_EXTERN CGFontRef
|
||||
hb_coretext_face_get_cg_font (hb_face_t *face);
|
||||
|
||||
HB_EXTERN CTFontRef
|
||||
hb_coretext_font_get_ct_font (hb_font_t *font);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_CORETEXT_H */
|
||||
61
gfx/harfbuzz/src/hb-deprecated.h
Normal file
61
gfx/harfbuzz/src/hb-deprecated.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright © 2013 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_DEPRECATED_H
|
||||
#define HB_DEPRECATED_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-font.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
#ifndef HB_DISABLE_DEPRECATED
|
||||
|
||||
#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS
|
||||
|
||||
#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT
|
||||
#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
#endif
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_DEPRECATED_H */
|
||||
934
gfx/harfbuzz/src/hb-directwrite.cc
Normal file
934
gfx/harfbuzz/src/hb-directwrite.cc
Normal file
|
|
@ -0,0 +1,934 @@
|
|||
/*
|
||||
* Copyright © 2015-2016 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.
|
||||
*/
|
||||
|
||||
#define HB_SHAPER directwrite
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
#include <DWrite_1.h>
|
||||
|
||||
#include "hb-directwrite.h"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_DIRECTWRITE
|
||||
#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, face)
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, font)
|
||||
|
||||
|
||||
/*
|
||||
* DirectWrite font stream helpers
|
||||
*/
|
||||
|
||||
// This is a font loader which provides only one font (unlike its original design).
|
||||
// For a better implementation which was also source of this
|
||||
// and DWriteFontFileStream, have a look at to NativeFontResourceDWrite.cpp in Mozilla
|
||||
class DWriteFontFileLoader : public IDWriteFontFileLoader
|
||||
{
|
||||
private:
|
||||
IDWriteFontFileStream *mFontFileStream;
|
||||
public:
|
||||
DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) {
|
||||
mFontFileStream = fontFileStream;
|
||||
}
|
||||
|
||||
// IUnknown interface
|
||||
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
|
||||
IFACEMETHOD_(ULONG, AddRef)() { return 1; }
|
||||
IFACEMETHOD_(ULONG, Release)() { return 1; }
|
||||
|
||||
// IDWriteFontFileLoader methods
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey,
|
||||
UINT32 fontFileReferenceKeySize,
|
||||
OUT IDWriteFontFileStream** fontFileStream)
|
||||
{
|
||||
*fontFileStream = mFontFileStream;
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class DWriteFontFileStream : public IDWriteFontFileStream
|
||||
{
|
||||
private:
|
||||
uint8_t *mData;
|
||||
uint32_t mSize;
|
||||
public:
|
||||
DWriteFontFileStream(uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
mData = aData;
|
||||
mSize = aSize;
|
||||
}
|
||||
|
||||
// IUnknown interface
|
||||
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
|
||||
IFACEMETHOD_(ULONG, AddRef)() { return 1; }
|
||||
IFACEMETHOD_(ULONG, Release)() { return 1; }
|
||||
|
||||
// IDWriteFontFileStream methods
|
||||
virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart,
|
||||
UINT64 fileOffset,
|
||||
UINT64 fragmentSize,
|
||||
OUT void** fragmentContext)
|
||||
{
|
||||
// We are required to do bounds checking.
|
||||
if (fileOffset + fragmentSize > mSize) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// truncate the 64 bit fileOffset to size_t sized index into mData
|
||||
size_t index = static_cast<size_t> (fileOffset);
|
||||
|
||||
// We should be alive for the duration of this.
|
||||
*fragmentStart = &mData[index];
|
||||
*fragmentContext = nullptr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext) { }
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize)
|
||||
{
|
||||
*fileSize = mSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_face_data_t {
|
||||
IDWriteFactory *dwriteFactory;
|
||||
IDWriteFontFile *fontFile;
|
||||
IDWriteFontFileStream *fontFileStream;
|
||||
IDWriteFontFileLoader *fontFileLoader;
|
||||
IDWriteFontFace *fontFace;
|
||||
hb_blob_t *faceBlob;
|
||||
};
|
||||
|
||||
hb_directwrite_shaper_face_data_t *
|
||||
_hb_directwrite_shaper_face_data_create(hb_face_t *face)
|
||||
{
|
||||
hb_directwrite_shaper_face_data_t *data =
|
||||
(hb_directwrite_shaper_face_data_t *) malloc (sizeof (hb_directwrite_shaper_face_data_t));
|
||||
if (unlikely (!data))
|
||||
return NULL;
|
||||
|
||||
// TODO: factory and fontFileLoader should be cached separately
|
||||
IDWriteFactory* dwriteFactory;
|
||||
DWriteCreateFactory (
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof (IDWriteFactory),
|
||||
(IUnknown**) &dwriteFactory
|
||||
);
|
||||
|
||||
HRESULT hr;
|
||||
hb_blob_t *blob = hb_face_reference_blob (face);
|
||||
IDWriteFontFileStream *fontFileStream = new DWriteFontFileStream (
|
||||
(uint8_t*) hb_blob_get_data (blob, NULL), hb_blob_get_length (blob));
|
||||
|
||||
IDWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream);
|
||||
dwriteFactory->RegisterFontFileLoader (fontFileLoader);
|
||||
|
||||
IDWriteFontFile *fontFile;
|
||||
uint64_t fontFileKey = 0;
|
||||
hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey),
|
||||
fontFileLoader, &fontFile);
|
||||
|
||||
#define FAIL(...) \
|
||||
HB_STMT_START { \
|
||||
DEBUG_MSG (DIRECTWRITE, NULL, __VA_ARGS__); \
|
||||
return false; \
|
||||
} HB_STMT_END;
|
||||
|
||||
if (FAILED (hr)) {
|
||||
FAIL ("Failed to load font file from data!");
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL isSupported;
|
||||
DWRITE_FONT_FILE_TYPE fileType;
|
||||
DWRITE_FONT_FACE_TYPE faceType;
|
||||
UINT32 numberOfFaces;
|
||||
hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces);
|
||||
if (FAILED (hr) || !isSupported) {
|
||||
FAIL ("Font file is not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef FAIL
|
||||
|
||||
IDWriteFontFace *fontFace;
|
||||
dwriteFactory->CreateFontFace (faceType, 1, &fontFile, 0,
|
||||
DWRITE_FONT_SIMULATIONS_NONE, &fontFace);
|
||||
|
||||
data->dwriteFactory = dwriteFactory;
|
||||
data->fontFile = fontFile;
|
||||
data->fontFileStream = fontFileStream;
|
||||
data->fontFileLoader = fontFileLoader;
|
||||
data->fontFace = fontFace;
|
||||
data->faceBlob = blob;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data)
|
||||
{
|
||||
if (data->fontFace)
|
||||
data->fontFace->Release ();
|
||||
if (data->fontFile)
|
||||
data->fontFile->Release ();
|
||||
if (data->dwriteFactory) {
|
||||
if (data->fontFileLoader)
|
||||
data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader);
|
||||
data->dwriteFactory->Release ();
|
||||
}
|
||||
if (data->fontFileLoader)
|
||||
delete data->fontFileLoader;
|
||||
if (data->fontFileStream)
|
||||
delete data->fontFileStream;
|
||||
if (data->faceBlob)
|
||||
hb_blob_destroy (data->faceBlob);
|
||||
if (data)
|
||||
free (data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_font_data_t {
|
||||
};
|
||||
|
||||
hb_directwrite_shaper_font_data_t *
|
||||
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return NULL;
|
||||
|
||||
hb_directwrite_shaper_font_data_t *data =
|
||||
(hb_directwrite_shaper_font_data_t *) malloc (sizeof (hb_directwrite_shaper_font_data_t));
|
||||
if (unlikely (!data))
|
||||
return NULL;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data)
|
||||
{
|
||||
free (data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_shape_plan_data_t {};
|
||||
|
||||
hb_directwrite_shaper_shape_plan_data_t *
|
||||
_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project
|
||||
// but now is relicensed to MIT for HarfBuzz use
|
||||
class TextAnalysis
|
||||
: public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink
|
||||
{
|
||||
public:
|
||||
|
||||
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
|
||||
IFACEMETHOD_(ULONG, AddRef)() { return 1; }
|
||||
IFACEMETHOD_(ULONG, Release)() { return 1; }
|
||||
|
||||
// A single contiguous run of characters containing the same analysis
|
||||
// results.
|
||||
struct Run
|
||||
{
|
||||
uint32_t mTextStart; // starting text position of this run
|
||||
uint32_t mTextLength; // number of contiguous code units covered
|
||||
uint32_t mGlyphStart; // starting glyph in the glyphs array
|
||||
uint32_t mGlyphCount; // number of glyphs associated with this run of
|
||||
// text
|
||||
DWRITE_SCRIPT_ANALYSIS mScript;
|
||||
uint8_t mBidiLevel;
|
||||
bool mIsSideways;
|
||||
|
||||
inline bool ContainsTextPosition(uint32_t aTextPosition) const
|
||||
{
|
||||
return aTextPosition >= mTextStart
|
||||
&& aTextPosition < mTextStart + mTextLength;
|
||||
}
|
||||
|
||||
Run *nextRun;
|
||||
};
|
||||
|
||||
public:
|
||||
TextAnalysis(const wchar_t* text,
|
||||
uint32_t textLength,
|
||||
const wchar_t* localeName,
|
||||
DWRITE_READING_DIRECTION readingDirection)
|
||||
: mText(text)
|
||||
, mTextLength(textLength)
|
||||
, mLocaleName(localeName)
|
||||
, mReadingDirection(readingDirection)
|
||||
, mCurrentRun(NULL) { };
|
||||
|
||||
~TextAnalysis() {
|
||||
// delete runs, except mRunHead which is part of the TextAnalysis object
|
||||
for (Run *run = mRunHead.nextRun; run;) {
|
||||
Run *origRun = run;
|
||||
run = run->nextRun;
|
||||
free (origRun);
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer,
|
||||
Run **runHead) {
|
||||
// Analyzes the text using the script analyzer and returns
|
||||
// the result as a series of runs.
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Initially start out with one result that covers the entire range.
|
||||
// This result will be subdivided by the analysis processes.
|
||||
mRunHead.mTextStart = 0;
|
||||
mRunHead.mTextLength = mTextLength;
|
||||
mRunHead.mBidiLevel =
|
||||
(mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
|
||||
mRunHead.nextRun = NULL;
|
||||
mCurrentRun = &mRunHead;
|
||||
|
||||
// Call each of the analyzers in sequence, recording their results.
|
||||
if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) {
|
||||
*runHead = &mRunHead;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
// IDWriteTextAnalysisSource implementation
|
||||
|
||||
IFACEMETHODIMP GetTextAtPosition(uint32_t textPosition,
|
||||
OUT wchar_t const** textString,
|
||||
OUT uint32_t* textLength)
|
||||
{
|
||||
if (textPosition >= mTextLength) {
|
||||
// No text at this position, valid query though.
|
||||
*textString = NULL;
|
||||
*textLength = 0;
|
||||
}
|
||||
else {
|
||||
*textString = mText + textPosition;
|
||||
*textLength = mTextLength - textPosition;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GetTextBeforePosition(uint32_t textPosition,
|
||||
OUT wchar_t const** textString,
|
||||
OUT uint32_t* textLength)
|
||||
{
|
||||
if (textPosition == 0 || textPosition > mTextLength) {
|
||||
// Either there is no text before here (== 0), or this
|
||||
// is an invalid position. The query is considered valid thouh.
|
||||
*textString = NULL;
|
||||
*textLength = 0;
|
||||
}
|
||||
else {
|
||||
*textString = mText;
|
||||
*textLength = textPosition;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(DWRITE_READING_DIRECTION)
|
||||
GetParagraphReadingDirection() { return mReadingDirection; }
|
||||
|
||||
IFACEMETHODIMP GetLocaleName(uint32_t textPosition,
|
||||
uint32_t* textLength,
|
||||
wchar_t const** localeName)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP
|
||||
GetNumberSubstitution(uint32_t textPosition,
|
||||
OUT uint32_t* textLength,
|
||||
OUT IDWriteNumberSubstitution** numberSubstitution)
|
||||
{
|
||||
// We do not support number substitution.
|
||||
*numberSubstitution = NULL;
|
||||
*textLength = mTextLength - textPosition;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// IDWriteTextAnalysisSink implementation
|
||||
|
||||
IFACEMETHODIMP
|
||||
SetScriptAnalysis(uint32_t textPosition,
|
||||
uint32_t textLength,
|
||||
DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
|
||||
{
|
||||
SetCurrentRun(textPosition);
|
||||
SplitCurrentRun(textPosition);
|
||||
while (textLength > 0)
|
||||
{
|
||||
Run *run = FetchNextRun(&textLength);
|
||||
run->mScript = *scriptAnalysis;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP
|
||||
SetLineBreakpoints(uint32_t textPosition,
|
||||
uint32_t textLength,
|
||||
const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; }
|
||||
|
||||
IFACEMETHODIMP SetBidiLevel(uint32_t textPosition,
|
||||
uint32_t textLength,
|
||||
uint8_t explicitLevel,
|
||||
uint8_t resolvedLevel) { return S_OK; }
|
||||
|
||||
IFACEMETHODIMP
|
||||
SetNumberSubstitution(uint32_t textPosition,
|
||||
uint32_t textLength,
|
||||
IDWriteNumberSubstitution* numberSubstitution) { return S_OK; }
|
||||
|
||||
protected:
|
||||
Run *FetchNextRun(IN OUT uint32_t* textLength)
|
||||
{
|
||||
// Used by the sink setters, this returns a reference to the next run.
|
||||
// Position and length are adjusted to now point after the current run
|
||||
// being returned.
|
||||
|
||||
Run *origRun = mCurrentRun;
|
||||
// Split the tail if needed (the length remaining is less than the
|
||||
// current run's size).
|
||||
if (*textLength < mCurrentRun->mTextLength)
|
||||
{
|
||||
SplitCurrentRun (mCurrentRun->mTextStart + *textLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just advance the current run.
|
||||
mCurrentRun = mCurrentRun->nextRun;
|
||||
}
|
||||
*textLength -= origRun->mTextLength;
|
||||
|
||||
// Return a reference to the run that was just current.
|
||||
return origRun;
|
||||
}
|
||||
|
||||
void SetCurrentRun(uint32_t textPosition)
|
||||
{
|
||||
// Move the current run to the given position.
|
||||
// Since the analyzers generally return results in a forward manner,
|
||||
// this will usually just return early. If not, find the
|
||||
// corresponding run for the text position.
|
||||
|
||||
if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Run *run = &mRunHead; run; run = run->nextRun) {
|
||||
if (run->ContainsTextPosition (textPosition))
|
||||
{
|
||||
mCurrentRun = run;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//NS_NOTREACHED("We should always be able to find the text position in one \
|
||||
// of our runs");
|
||||
}
|
||||
|
||||
void SplitCurrentRun(uint32_t splitPosition)
|
||||
{
|
||||
if (!mCurrentRun)
|
||||
{
|
||||
//NS_ASSERTION(false, "SplitCurrentRun called without current run.");
|
||||
// Shouldn't be calling this when no current run is set!
|
||||
return;
|
||||
}
|
||||
// Split the current run.
|
||||
if (splitPosition <= mCurrentRun->mTextStart)
|
||||
{
|
||||
// No need to split, already the start of a run
|
||||
// or before it. Usually the first.
|
||||
return;
|
||||
}
|
||||
Run *newRun = (Run*) malloc (sizeof (Run));
|
||||
|
||||
*newRun = *mCurrentRun;
|
||||
|
||||
// Insert the new run in our linked list.
|
||||
newRun->nextRun = mCurrentRun->nextRun;
|
||||
mCurrentRun->nextRun = newRun;
|
||||
|
||||
// Adjust runs' text positions and lengths.
|
||||
uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart;
|
||||
newRun->mTextStart += splitPoint;
|
||||
newRun->mTextLength -= splitPoint;
|
||||
mCurrentRun->mTextLength = splitPoint;
|
||||
mCurrentRun = newRun;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Input
|
||||
// (weak references are fine here, since this class is a transient
|
||||
// stack-based helper that doesn't need to copy data)
|
||||
uint32_t mTextLength;
|
||||
const wchar_t* mText;
|
||||
const wchar_t* mLocaleName;
|
||||
DWRITE_READING_DIRECTION mReadingDirection;
|
||||
|
||||
// Current processing state.
|
||||
Run *mCurrentRun;
|
||||
|
||||
// Output is a list of runs starting here
|
||||
Run mRunHead;
|
||||
};
|
||||
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
{ return (v >> 8) | (v << 8); }
|
||||
static inline uint32_t hb_uint32_swap (const uint32_t v)
|
||||
{ return (hb_uint16_swap(v) << 16) | hb_uint16_swap(v >> 16); }
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
||||
static hb_bool_t
|
||||
_hb_directwrite_shape_full(hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
float lineWidth)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
|
||||
IDWriteFontFace *fontFace = face_data->fontFace;
|
||||
|
||||
IDWriteTextAnalyzer* analyzer;
|
||||
dwriteFactory->CreateTextAnalyzer(&analyzer);
|
||||
|
||||
unsigned int scratch_size;
|
||||
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
#define ALLOCATE_ARRAY(Type, name, len) \
|
||||
Type *name = (Type *) scratch; \
|
||||
{ \
|
||||
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
|
||||
assert (_consumed <= scratch_size); \
|
||||
scratch += _consumed; \
|
||||
scratch_size -= _consumed; \
|
||||
}
|
||||
|
||||
#define utf16_index() var1.u32
|
||||
|
||||
ALLOCATE_ARRAY(wchar_t, textString, buffer->len * 2);
|
||||
|
||||
unsigned int chars_len = 0;
|
||||
for (unsigned int i = 0; i < buffer->len; i++)
|
||||
{
|
||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||
buffer->info[i].utf16_index() = chars_len;
|
||||
if (likely(c <= 0xFFFFu))
|
||||
textString[chars_len++] = c;
|
||||
else if (unlikely(c > 0x10FFFFu))
|
||||
textString[chars_len++] = 0xFFFDu;
|
||||
else {
|
||||
textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
|
||||
textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
ALLOCATE_ARRAY(WORD, log_clusters, chars_len);
|
||||
// if (num_features)
|
||||
{
|
||||
/* Need log_clusters to assign features. */
|
||||
chars_len = 0;
|
||||
for (unsigned int i = 0; i < buffer->len; i++)
|
||||
{
|
||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||
unsigned int cluster = buffer->info[i].cluster;
|
||||
log_clusters[chars_len++] = cluster;
|
||||
if (hb_in_range(c, 0x10000u, 0x10FFFFu))
|
||||
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES
|
||||
|
||||
DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ?
|
||||
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
|
||||
DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
|
||||
|
||||
/*
|
||||
* There's an internal 16-bit limit on some things inside the analyzer,
|
||||
* but we never attempt to shape a word longer than 64K characters
|
||||
* in a single gfxShapedWord, so we cannot exceed that limit.
|
||||
*/
|
||||
uint32_t textLength = buffer->len;
|
||||
|
||||
TextAnalysis analysis(textString, textLength, NULL, readingDirection);
|
||||
TextAnalysis::Run *runHead;
|
||||
HRESULT hr;
|
||||
hr = analysis.GenerateResults(analyzer, &runHead);
|
||||
|
||||
#define FAIL(...) \
|
||||
HB_STMT_START { \
|
||||
DEBUG_MSG (DIRECTWRITE, NULL, __VA_ARGS__); \
|
||||
return false; \
|
||||
} HB_STMT_END;
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to generate results.");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t maxGlyphCount = 3 * textLength / 2 + 16;
|
||||
uint32_t glyphCount;
|
||||
bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
|
||||
|
||||
const wchar_t localeName[20] = {0};
|
||||
if (buffer->props.language != NULL)
|
||||
{
|
||||
mbstowcs ((wchar_t*) localeName,
|
||||
hb_language_to_string (buffer->props.language), 20);
|
||||
}
|
||||
|
||||
DWRITE_TYPOGRAPHIC_FEATURES singleFeatures;
|
||||
singleFeatures.featureCount = num_features;
|
||||
if (num_features)
|
||||
{
|
||||
DWRITE_FONT_FEATURE* dwfeatureArray = (DWRITE_FONT_FEATURE*)
|
||||
malloc (sizeof (DWRITE_FONT_FEATURE) * num_features);
|
||||
for (unsigned int i = 0; i < num_features; ++i)
|
||||
{
|
||||
dwfeatureArray[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
|
||||
hb_uint32_swap (features[i].tag);
|
||||
dwfeatureArray[i].parameter = features[i].value;
|
||||
}
|
||||
singleFeatures.features = dwfeatureArray;
|
||||
}
|
||||
const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures =
|
||||
(const DWRITE_TYPOGRAPHIC_FEATURES*) &singleFeatures;
|
||||
const uint32_t featureRangeLengths[] = { textLength };
|
||||
|
||||
uint16_t* clusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t));
|
||||
DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*)
|
||||
malloc (textLength * sizeof (DWRITE_SHAPING_TEXT_PROPERTIES));
|
||||
retry_getglyphs:
|
||||
uint16_t* glyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t));
|
||||
DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
|
||||
malloc (maxGlyphCount * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES));
|
||||
|
||||
hr = analyzer->GetGlyphs (textString, textLength, fontFace, FALSE,
|
||||
isRightToLeft, &runHead->mScript, localeName, NULL, &dwFeatures,
|
||||
featureRangeLengths, 1, maxGlyphCount, clusterMap, textProperties, glyphIndices,
|
||||
glyphProperties, &glyphCount);
|
||||
|
||||
if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)))
|
||||
{
|
||||
free (glyphIndices);
|
||||
free (glyphProperties);
|
||||
|
||||
maxGlyphCount *= 2;
|
||||
|
||||
goto retry_getglyphs;
|
||||
}
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get glyphs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
float* glyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float));
|
||||
DWRITE_GLYPH_OFFSET* glyphOffsets = (DWRITE_GLYPH_OFFSET*)
|
||||
malloc(maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET));
|
||||
|
||||
/* The -2 in the following is to compensate for possible
|
||||
* alignment needed after the WORD array. sizeof(WORD) == 2. */
|
||||
unsigned int glyphs_size = (scratch_size * sizeof(int) - 2)
|
||||
/ (sizeof(WORD) +
|
||||
sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES) +
|
||||
sizeof(int) +
|
||||
sizeof(DWRITE_GLYPH_OFFSET) +
|
||||
sizeof(uint32_t));
|
||||
ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
|
||||
|
||||
#undef ALLOCATE_ARRAY
|
||||
|
||||
int fontEmSize = font->face->get_upem();
|
||||
if (fontEmSize < 0)
|
||||
fontEmSize = -fontEmSize;
|
||||
|
||||
if (fontEmSize < 0)
|
||||
fontEmSize = -fontEmSize;
|
||||
double x_mult = (double) font->x_scale / fontEmSize;
|
||||
double y_mult = (double) font->y_scale / fontEmSize;
|
||||
|
||||
hr = analyzer->GetGlyphPlacements (textString,
|
||||
clusterMap, textProperties, textLength, glyphIndices,
|
||||
glyphProperties, glyphCount, fontFace, fontEmSize,
|
||||
FALSE, isRightToLeft, &runHead->mScript, localeName,
|
||||
&dwFeatures, featureRangeLengths, 1,
|
||||
glyphAdvances, glyphOffsets);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get glyph placements.");
|
||||
return false;
|
||||
}
|
||||
|
||||
IDWriteTextAnalyzer1* analyzer1;
|
||||
analyzer->QueryInterface (&analyzer1);
|
||||
|
||||
if (analyzer1 && lineWidth)
|
||||
{
|
||||
|
||||
DWRITE_JUSTIFICATION_OPPORTUNITY* justificationOpportunities =
|
||||
(DWRITE_JUSTIFICATION_OPPORTUNITY*)
|
||||
malloc (maxGlyphCount * sizeof (DWRITE_JUSTIFICATION_OPPORTUNITY));
|
||||
hr = analyzer1->GetJustificationOpportunities (fontFace, fontEmSize,
|
||||
runHead->mScript, textLength, glyphCount, textString, clusterMap,
|
||||
glyphProperties, justificationOpportunities);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get justification opportunities.");
|
||||
return false;
|
||||
}
|
||||
|
||||
float* justifiedGlyphAdvances =
|
||||
(float*) malloc (maxGlyphCount * sizeof (float));
|
||||
DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*)
|
||||
malloc (glyphCount * sizeof (DWRITE_GLYPH_OFFSET));
|
||||
hr = analyzer1->JustifyGlyphAdvances (lineWidth, glyphCount, justificationOpportunities,
|
||||
glyphAdvances, glyphOffsets, justifiedGlyphAdvances, justifiedGlyphOffsets);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL("Analyzer failed to get justified glyph advances.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWRITE_SCRIPT_PROPERTIES scriptProperties;
|
||||
hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties);
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL("Analyzer failed to get script properties.");
|
||||
return false;
|
||||
}
|
||||
uint32_t justificationCharacter = scriptProperties.justificationCharacter;
|
||||
|
||||
// if a script justificationCharacter is not space, it can have GetJustifiedGlyphs
|
||||
if (justificationCharacter != 32)
|
||||
{
|
||||
uint16_t* modifiedClusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t));
|
||||
retry_getjustifiedglyphs:
|
||||
uint16_t* modifiedGlyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t));
|
||||
float* modifiedGlyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float));
|
||||
DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*)
|
||||
malloc (maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET));
|
||||
uint32_t actualGlyphsCount;
|
||||
hr = analyzer1->GetJustifiedGlyphs (fontFace, fontEmSize, runHead->mScript,
|
||||
textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices,
|
||||
glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets,
|
||||
glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices,
|
||||
modifiedGlyphAdvances, modifiedGlyphOffsets);
|
||||
|
||||
if (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))
|
||||
{
|
||||
maxGlyphCount = actualGlyphsCount;
|
||||
free (modifiedGlyphIndices);
|
||||
free (modifiedGlyphAdvances);
|
||||
free (modifiedGlyphOffsets);
|
||||
|
||||
maxGlyphCount = actualGlyphsCount;
|
||||
|
||||
goto retry_getjustifiedglyphs;
|
||||
}
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get justified glyphs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
free (clusterMap);
|
||||
free (glyphIndices);
|
||||
free (glyphAdvances);
|
||||
free (glyphOffsets);
|
||||
|
||||
glyphCount = actualGlyphsCount;
|
||||
clusterMap = modifiedClusterMap;
|
||||
glyphIndices = modifiedGlyphIndices;
|
||||
glyphAdvances = modifiedGlyphAdvances;
|
||||
glyphOffsets = modifiedGlyphOffsets;
|
||||
|
||||
free (justifiedGlyphAdvances);
|
||||
free (justifiedGlyphOffsets);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (glyphAdvances);
|
||||
free (glyphOffsets);
|
||||
|
||||
glyphAdvances = justifiedGlyphAdvances;
|
||||
glyphOffsets = justifiedGlyphOffsets;
|
||||
}
|
||||
|
||||
free (justificationOpportunities);
|
||||
|
||||
}
|
||||
|
||||
/* Ok, we've got everything we need, now compose output buffer,
|
||||
* very, *very*, carefully! */
|
||||
|
||||
/* Calculate visual-clusters. That's what we ship. */
|
||||
for (unsigned int i = 0; i < glyphCount; i++)
|
||||
vis_clusters[i] = -1;
|
||||
for (unsigned int i = 0; i < buffer->len; i++)
|
||||
{
|
||||
uint32_t *p =
|
||||
&vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
|
||||
*p = MIN (*p, buffer->info[i].cluster);
|
||||
}
|
||||
for (unsigned int i = 1; i < glyphCount; i++)
|
||||
if (vis_clusters[i] == -1)
|
||||
vis_clusters[i] = vis_clusters[i - 1];
|
||||
|
||||
#undef utf16_index
|
||||
|
||||
if (unlikely (!buffer->ensure (glyphCount)))
|
||||
FAIL ("Buffer in error");
|
||||
|
||||
#undef FAIL
|
||||
|
||||
/* Set glyph infos */
|
||||
buffer->len = 0;
|
||||
for (unsigned int i = 0; i < glyphCount; i++)
|
||||
{
|
||||
hb_glyph_info_t *info = &buffer->info[buffer->len++];
|
||||
|
||||
info->codepoint = glyphIndices[i];
|
||||
info->cluster = vis_clusters[i];
|
||||
|
||||
/* The rest is crap. Let's store position info there for now. */
|
||||
info->mask = glyphAdvances[i];
|
||||
info->var1.i32 = glyphOffsets[i].advanceOffset;
|
||||
info->var2.i32 = glyphOffsets[i].ascenderOffset;
|
||||
}
|
||||
|
||||
/* Set glyph positions */
|
||||
buffer->clear_positions ();
|
||||
for (unsigned int i = 0; i < glyphCount; i++)
|
||||
{
|
||||
hb_glyph_info_t *info = &buffer->info[i];
|
||||
hb_glyph_position_t *pos = &buffer->pos[i];
|
||||
|
||||
/* TODO vertical */
|
||||
pos->x_advance = x_mult * (int32_t) info->mask;
|
||||
pos->x_offset =
|
||||
x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32);
|
||||
pos->y_offset = y_mult * info->var2.i32;
|
||||
}
|
||||
|
||||
if (isRightToLeft)
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
free (clusterMap);
|
||||
free (glyphIndices);
|
||||
free (textProperties);
|
||||
free (glyphProperties);
|
||||
free (glyphAdvances);
|
||||
free (glyphOffsets);
|
||||
|
||||
if (num_features)
|
||||
free (singleFeatures.features);
|
||||
|
||||
/* Wow, done! */
|
||||
return true;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
_hb_directwrite_shape(hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features)
|
||||
{
|
||||
return _hb_directwrite_shape_full(shape_plan, font, buffer,
|
||||
features, num_features, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Public [experimental] API
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_shape_dwrite_experimental_width(hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
float width)
|
||||
{
|
||||
static char *shapers = "directwrite";
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face,
|
||||
&buffer->props, features, num_features, &shapers);
|
||||
hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer,
|
||||
features, num_features, width);
|
||||
|
||||
if (res)
|
||||
buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
|
||||
|
||||
return res;
|
||||
}
|
||||
38
gfx/harfbuzz/src/hb-directwrite.h
Normal file
38
gfx/harfbuzz/src/hb-directwrite.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright © 2015 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_DIRECTWRITE_H
|
||||
#define HB_DIRECTWRITE_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_shape_dwrite_experimental_width(hb_font_t *font, hb_buffer_t *buffer,
|
||||
const hb_feature_t *features, unsigned int num_features, float width);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_DIRECTWRITE_H */
|
||||
107
gfx/harfbuzz/src/hb-face-private.hh
Normal file
107
gfx/harfbuzz/src/hb-face-private.hh
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_FACE_PRIVATE_HH
|
||||
#define HB_FACE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-shape-plan-private.hh"
|
||||
|
||||
|
||||
/*
|
||||
* hb_face_t
|
||||
*/
|
||||
|
||||
struct hb_face_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
hb_reference_table_func_t reference_table_func;
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
unsigned int index;
|
||||
mutable unsigned int upem;
|
||||
mutable unsigned int num_glyphs;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
|
||||
struct plan_node_t {
|
||||
hb_shape_plan_t *shape_plan;
|
||||
plan_node_t *next;
|
||||
} *shape_plans;
|
||||
|
||||
|
||||
inline hb_blob_t *reference_table (hb_tag_t tag) const
|
||||
{
|
||||
hb_blob_t *blob;
|
||||
|
||||
if (unlikely (!reference_table_func))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
|
||||
if (unlikely (!blob))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
inline HB_PURE_FUNC unsigned int get_upem (void) const
|
||||
{
|
||||
if (unlikely (!upem))
|
||||
load_upem ();
|
||||
return upem;
|
||||
}
|
||||
|
||||
inline unsigned int get_num_glyphs (void) const
|
||||
{
|
||||
if (unlikely (num_glyphs == (unsigned int) -1))
|
||||
load_num_glyphs ();
|
||||
return num_glyphs;
|
||||
}
|
||||
|
||||
private:
|
||||
HB_INTERNAL void load_upem (void) const;
|
||||
HB_INTERNAL void load_num_glyphs (void) const;
|
||||
};
|
||||
|
||||
extern HB_INTERNAL const hb_face_t _hb_face_nil;
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
|
||||
|
||||
#endif /* HB_FACE_PRIVATE_HH */
|
||||
479
gfx/harfbuzz/src/hb-face.cc
Normal file
479
gfx/harfbuzz/src/hb-face.cc
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-open-file-private.hh"
|
||||
#include "hb-ot-head-table.hh"
|
||||
#include "hb-ot-maxp-table.hh"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* hb_face_t
|
||||
*/
|
||||
|
||||
const hb_face_t _hb_face_nil = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
true, /* immutable */
|
||||
|
||||
NULL, /* reference_table_func */
|
||||
NULL, /* user_data */
|
||||
NULL, /* destroy */
|
||||
|
||||
0, /* index */
|
||||
1000, /* upem */
|
||||
0, /* num_glyphs */
|
||||
|
||||
{
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
},
|
||||
|
||||
NULL, /* shape_plans */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* hb_face_create_for_tables:
|
||||
* @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full)
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_face_t *face;
|
||||
|
||||
if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) {
|
||||
if (destroy)
|
||||
destroy (user_data);
|
||||
return hb_face_get_empty ();
|
||||
}
|
||||
|
||||
face->reference_table_func = reference_table_func;
|
||||
face->user_data = user_data;
|
||||
face->destroy = destroy;
|
||||
|
||||
face->upem = 0;
|
||||
face->num_glyphs = (unsigned int) -1;
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
|
||||
typedef struct hb_face_for_data_closure_t {
|
||||
hb_blob_t *blob;
|
||||
unsigned int index;
|
||||
} hb_face_for_data_closure_t;
|
||||
|
||||
static hb_face_for_data_closure_t *
|
||||
_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
|
||||
{
|
||||
hb_face_for_data_closure_t *closure;
|
||||
|
||||
closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t));
|
||||
if (unlikely (!closure))
|
||||
return NULL;
|
||||
|
||||
closure->blob = blob;
|
||||
closure->index = index;
|
||||
|
||||
return closure;
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
|
||||
{
|
||||
hb_blob_destroy (closure->blob);
|
||||
free (closure);
|
||||
}
|
||||
|
||||
static hb_blob_t *
|
||||
_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
|
||||
|
||||
if (tag == HB_TAG_NONE)
|
||||
return hb_blob_reference (data->blob);
|
||||
|
||||
const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
|
||||
const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
|
||||
|
||||
const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
|
||||
|
||||
hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_create: (Xconstructor)
|
||||
* @blob:
|
||||
* @index:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_create (hb_blob_t *blob,
|
||||
unsigned int index)
|
||||
{
|
||||
hb_face_t *face;
|
||||
|
||||
if (unlikely (!blob))
|
||||
blob = hb_blob_get_empty ();
|
||||
|
||||
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
|
||||
|
||||
if (unlikely (!closure))
|
||||
return hb_face_get_empty ();
|
||||
|
||||
face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
|
||||
closure,
|
||||
(hb_destroy_func_t) _hb_face_for_data_closure_destroy);
|
||||
|
||||
hb_face_set_index (face, index);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_get_empty:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full)
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_get_empty (void)
|
||||
{
|
||||
return const_cast<hb_face_t *> (&_hb_face_nil);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_face_reference: (skip)
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_reference (hb_face_t *face)
|
||||
{
|
||||
return hb_object_reference (face);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_destroy: (skip)
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_face_destroy (hb_face_t *face)
|
||||
{
|
||||
if (!hb_object_destroy (face)) return;
|
||||
|
||||
for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
|
||||
{
|
||||
hb_face_t::plan_node_t *next = node->next;
|
||||
hb_shape_plan_destroy (node->shape_plan);
|
||||
free (node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
|
||||
if (face->destroy)
|
||||
face->destroy (face->user_data);
|
||||
|
||||
free (face);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_set_user_data: (skip)
|
||||
* @face: a face.
|
||||
* @key:
|
||||
* @data:
|
||||
* @destroy:
|
||||
* @replace:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_face_set_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
return hb_object_set_user_data (face, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_get_user_data: (skip)
|
||||
* @face: a face.
|
||||
* @key:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void *
|
||||
hb_face_get_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (face, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_make_immutable:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_face_make_immutable (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (face)))
|
||||
return;
|
||||
|
||||
face->immutable = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_is_immutable:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_face_is_immutable (hb_face_t *face)
|
||||
{
|
||||
return face->immutable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_face_reference_table:
|
||||
* @face: a face.
|
||||
* @tag:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_face_reference_table (hb_face_t *face,
|
||||
hb_tag_t tag)
|
||||
{
|
||||
return face->reference_table (tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_reference_blob:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_face_reference_blob (hb_face_t *face)
|
||||
{
|
||||
return face->reference_table (HB_TAG_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_set_index:
|
||||
* @face: a face.
|
||||
* @index:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_face_set_index (hb_face_t *face,
|
||||
unsigned int index)
|
||||
{
|
||||
if (face->immutable)
|
||||
return;
|
||||
|
||||
face->index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_get_index:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_index (hb_face_t *face)
|
||||
{
|
||||
return face->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_set_upem:
|
||||
* @face: a face.
|
||||
* @upem:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_face_set_upem (hb_face_t *face,
|
||||
unsigned int upem)
|
||||
{
|
||||
if (face->immutable)
|
||||
return;
|
||||
|
||||
face->upem = upem;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_get_upem:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_upem (hb_face_t *face)
|
||||
{
|
||||
return face->get_upem ();
|
||||
}
|
||||
|
||||
void
|
||||
hb_face_t::load_upem (void) const
|
||||
{
|
||||
hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
|
||||
const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
|
||||
upem = head_table->get_upem ();
|
||||
hb_blob_destroy (head_blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_set_glyph_count:
|
||||
* @face: a face.
|
||||
* @glyph_count:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
hb_face_set_glyph_count (hb_face_t *face,
|
||||
unsigned int glyph_count)
|
||||
{
|
||||
if (face->immutable)
|
||||
return;
|
||||
|
||||
face->num_glyphs = glyph_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_get_glyph_count:
|
||||
* @face: a face.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_glyph_count (hb_face_t *face)
|
||||
{
|
||||
return face->get_num_glyphs ();
|
||||
}
|
||||
|
||||
void
|
||||
hb_face_t::load_num_glyphs (void) const
|
||||
{
|
||||
hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
|
||||
const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
|
||||
num_glyphs = maxp_table->get_num_glyphs ();
|
||||
hb_blob_destroy (maxp_blob);
|
||||
}
|
||||
|
||||
|
||||
117
gfx/harfbuzz/src/hb-face.h
Normal file
117
gfx/harfbuzz/src/hb-face.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_FACE_H
|
||||
#define HB_FACE_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-blob.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* hb_face_t
|
||||
*/
|
||||
|
||||
typedef struct hb_face_t hb_face_t;
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_face_create (hb_blob_t *blob,
|
||||
unsigned int index);
|
||||
|
||||
typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
|
||||
|
||||
/* calls destroy() when not needing user_data anymore */
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
|
||||
void *user_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_face_get_empty (void);
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_face_reference (hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_destroy (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_face_set_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_face_get_user_data (hb_face_t *face,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_make_immutable (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_face_is_immutable (hb_face_t *face);
|
||||
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_face_reference_table (hb_face_t *face,
|
||||
hb_tag_t tag);
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_face_reference_blob (hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_set_index (hb_face_t *face,
|
||||
unsigned int index);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_index (hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_set_upem (hb_face_t *face,
|
||||
unsigned int upem);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_upem (hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_set_glyph_count (hb_face_t *face,
|
||||
unsigned int glyph_count);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_glyph_count (hb_face_t *face);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_FACE_H */
|
||||
143
gfx/harfbuzz/src/hb-fallback-shape.cc
Normal file
143
gfx/harfbuzz/src/hb-fallback-shape.cc
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define HB_SHAPER fallback
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_face_data_t {};
|
||||
|
||||
hb_fallback_shaper_face_data_t *
|
||||
_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_font_data_t {};
|
||||
|
||||
hb_fallback_shaper_font_data_t *
|
||||
_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_shape_plan_data_t {};
|
||||
|
||||
hb_fallback_shaper_shape_plan_data_t *
|
||||
_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features HB_UNUSED,
|
||||
unsigned int num_features HB_UNUSED)
|
||||
{
|
||||
/* TODO
|
||||
*
|
||||
* - Apply fallback kern.
|
||||
* - Handle Variation Selectors?
|
||||
* - Apply normalization?
|
||||
*
|
||||
* This will make the fallback shaper into a dumb "TrueType"
|
||||
* shaper which many people unfortunately still request.
|
||||
*/
|
||||
|
||||
hb_codepoint_t space;
|
||||
bool has_space = (bool) font->get_nominal_glyph (' ', &space);
|
||||
|
||||
buffer->clear_positions ();
|
||||
|
||||
hb_direction_t direction = buffer->props.direction;
|
||||
hb_unicode_funcs_t *unicode = buffer->unicode;
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
|
||||
info[i].codepoint = space;
|
||||
pos[i].x_advance = 0;
|
||||
pos[i].y_advance = 0;
|
||||
continue;
|
||||
}
|
||||
font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint);
|
||||
font->get_glyph_advance_for_direction (info[i].codepoint,
|
||||
direction,
|
||||
&pos[i].x_advance,
|
||||
&pos[i].y_advance);
|
||||
font->subtract_glyph_origin_for_direction (info[i].codepoint,
|
||||
direction,
|
||||
&pos[i].x_offset,
|
||||
&pos[i].y_offset);
|
||||
}
|
||||
|
||||
if (HB_DIRECTION_IS_BACKWARD (direction))
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
553
gfx/harfbuzz/src/hb-font-private.hh
Normal file
553
gfx/harfbuzz/src/hb-font-private.hh
Normal file
|
|
@ -0,0 +1,553 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_FONT_PRIVATE_HH
|
||||
#define HB_FONT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-object-private.hh"
|
||||
#include "hb-face-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_funcs_t
|
||||
*/
|
||||
|
||||
#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
|
||||
HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
|
||||
HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
|
||||
HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
|
||||
HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_name) \
|
||||
HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
|
||||
/* ^--- Add new callbacks here */
|
||||
|
||||
struct hb_font_funcs_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
struct {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} user_data;
|
||||
|
||||
struct {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} destroy;
|
||||
|
||||
/* Don't access these directly. Call font->get_*() instead. */
|
||||
union get_t {
|
||||
struct get_funcs_t {
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
} f;
|
||||
void (*array[VAR]) (void);
|
||||
} get;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_t
|
||||
*/
|
||||
|
||||
struct hb_font_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_bool_t immutable;
|
||||
|
||||
hb_font_t *parent;
|
||||
hb_face_t *face;
|
||||
|
||||
int x_scale;
|
||||
int y_scale;
|
||||
|
||||
unsigned int x_ppem;
|
||||
unsigned int y_ppem;
|
||||
|
||||
/* Font variation coordinates. */
|
||||
unsigned int num_coords;
|
||||
int *coords;
|
||||
|
||||
hb_font_funcs_t *klass;
|
||||
void *user_data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
struct hb_shaper_data_t shaper_data;
|
||||
|
||||
|
||||
/* Convert from font-space to user-space */
|
||||
inline int dir_scale (hb_direction_t direction)
|
||||
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
|
||||
inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
|
||||
inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
|
||||
inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
|
||||
inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
|
||||
inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
|
||||
{ return em_scale (v, dir_scale (direction)); }
|
||||
|
||||
/* Convert from parent-font user-space to our user-space */
|
||||
inline hb_position_t parent_scale_x_distance (hb_position_t v) {
|
||||
if (unlikely (parent && parent->x_scale != x_scale))
|
||||
return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
|
||||
return v;
|
||||
}
|
||||
inline hb_position_t parent_scale_y_distance (hb_position_t v) {
|
||||
if (unlikely (parent && parent->y_scale != y_scale))
|
||||
return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
|
||||
return v;
|
||||
}
|
||||
inline hb_position_t parent_scale_x_position (hb_position_t v) {
|
||||
return parent_scale_x_distance (v);
|
||||
}
|
||||
inline hb_position_t parent_scale_y_position (hb_position_t v) {
|
||||
return parent_scale_y_distance (v);
|
||||
}
|
||||
|
||||
inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
|
||||
*x = parent_scale_x_distance (*x);
|
||||
*y = parent_scale_y_distance (*y);
|
||||
}
|
||||
inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
|
||||
*x = parent_scale_x_position (*x);
|
||||
*y = parent_scale_y_position (*y);
|
||||
}
|
||||
|
||||
|
||||
/* Public getters */
|
||||
|
||||
HB_INTERNAL bool has_func (unsigned int i);
|
||||
|
||||
/* has_* ... */
|
||||
#define HB_FONT_FUNC_IMPLEMENT(name) \
|
||||
bool \
|
||||
has_##name##_func (void) \
|
||||
{ \
|
||||
hb_font_funcs_t *funcs = this->klass; \
|
||||
unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
|
||||
return has_func (i); \
|
||||
}
|
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_FONT_FUNC_IMPLEMENT
|
||||
|
||||
inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
|
||||
{
|
||||
memset (extents, 0, sizeof (*extents));
|
||||
return klass->get.f.font_h_extents (this, user_data,
|
||||
extents,
|
||||
klass->user_data.font_h_extents);
|
||||
}
|
||||
inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
|
||||
{
|
||||
memset (extents, 0, sizeof (*extents));
|
||||
return klass->get.f.font_v_extents (this, user_data,
|
||||
extents,
|
||||
klass->user_data.font_v_extents);
|
||||
}
|
||||
|
||||
inline bool has_glyph (hb_codepoint_t unicode)
|
||||
{
|
||||
hb_codepoint_t glyph;
|
||||
return get_nominal_glyph (unicode, &glyph);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
return klass->get.f.nominal_glyph (this, user_data,
|
||||
unicode, glyph,
|
||||
klass->user_data.nominal_glyph);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
return klass->get.f.variation_glyph (this, user_data,
|
||||
unicode, variation_selector, glyph,
|
||||
klass->user_data.variation_glyph);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
|
||||
{
|
||||
return klass->get.f.glyph_h_advance (this, user_data,
|
||||
glyph,
|
||||
klass->user_data.glyph_h_advance);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
|
||||
{
|
||||
return klass->get.f.glyph_v_advance (this, user_data,
|
||||
glyph,
|
||||
klass->user_data.glyph_v_advance);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.f.glyph_h_origin (this, user_data,
|
||||
glyph, x, y,
|
||||
klass->user_data.glyph_h_origin);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.f.glyph_v_origin (this, user_data,
|
||||
glyph, x, y,
|
||||
klass->user_data.glyph_v_origin);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
|
||||
{
|
||||
return klass->get.f.glyph_h_kerning (this, user_data,
|
||||
left_glyph, right_glyph,
|
||||
klass->user_data.glyph_h_kerning);
|
||||
}
|
||||
|
||||
inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
|
||||
{
|
||||
return klass->get.f.glyph_v_kerning (this, user_data,
|
||||
top_glyph, bottom_glyph,
|
||||
klass->user_data.glyph_v_kerning);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents)
|
||||
{
|
||||
memset (extents, 0, sizeof (*extents));
|
||||
return klass->get.f.glyph_extents (this, user_data,
|
||||
glyph,
|
||||
extents,
|
||||
klass->user_data.glyph_extents);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return klass->get.f.glyph_contour_point (this, user_data,
|
||||
glyph, point_index,
|
||||
x, y,
|
||||
klass->user_data.glyph_contour_point);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
|
||||
char *name, unsigned int size)
|
||||
{
|
||||
if (size) *name = '\0';
|
||||
return klass->get.f.glyph_name (this, user_data,
|
||||
glyph,
|
||||
name, size,
|
||||
klass->user_data.glyph_name);
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
if (len == -1) len = strlen (name);
|
||||
return klass->get.f.glyph_from_name (this, user_data,
|
||||
name, len,
|
||||
glyph,
|
||||
klass->user_data.glyph_from_name);
|
||||
}
|
||||
|
||||
|
||||
/* A bit higher-level, and with fallback */
|
||||
|
||||
inline void get_h_extents_with_fallback (hb_font_extents_t *extents)
|
||||
{
|
||||
if (!get_font_h_extents (extents))
|
||||
{
|
||||
extents->ascender = y_scale * .8;
|
||||
extents->descender = extents->ascender - y_scale;
|
||||
extents->line_gap = 0;
|
||||
}
|
||||
}
|
||||
inline void get_v_extents_with_fallback (hb_font_extents_t *extents)
|
||||
{
|
||||
if (!get_font_v_extents (extents))
|
||||
{
|
||||
extents->ascender = x_scale / 2;
|
||||
extents->descender = extents->ascender - x_scale;
|
||||
extents->line_gap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void get_extents_for_direction (hb_direction_t direction,
|
||||
hb_font_extents_t *extents)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
|
||||
get_h_extents_with_fallback (extents);
|
||||
else
|
||||
get_v_extents_with_fallback (extents);
|
||||
}
|
||||
|
||||
inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
|
||||
*x = get_glyph_h_advance (glyph);
|
||||
*y = 0;
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = get_glyph_v_advance (glyph);
|
||||
}
|
||||
}
|
||||
|
||||
inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = get_glyph_h_advance (glyph) / 2;
|
||||
|
||||
/* TODO cache this somehow?! */
|
||||
hb_font_extents_t extents;
|
||||
get_h_extents_with_fallback (&extents);
|
||||
*y = extents.ascender;
|
||||
}
|
||||
|
||||
inline void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (!get_glyph_h_origin (glyph, x, y) &&
|
||||
get_glyph_v_origin (glyph, x, y))
|
||||
{
|
||||
hb_position_t dx, dy;
|
||||
guess_v_origin_minus_h_origin (glyph, &dx, &dy);
|
||||
*x -= dx; *y -= dy;
|
||||
}
|
||||
}
|
||||
inline void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (!get_glyph_v_origin (glyph, x, y) &&
|
||||
get_glyph_h_origin (glyph, x, y))
|
||||
{
|
||||
hb_position_t dx, dy;
|
||||
guess_v_origin_minus_h_origin (glyph, &dx, &dy);
|
||||
*x += dx; *y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
|
||||
get_glyph_h_origin_with_fallback (glyph, x, y);
|
||||
else
|
||||
get_glyph_v_origin_with_fallback (glyph, x, y);
|
||||
}
|
||||
|
||||
inline void add_glyph_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
|
||||
|
||||
*x += origin_x;
|
||||
*y += origin_y;
|
||||
}
|
||||
inline void add_glyph_v_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
|
||||
|
||||
*x += origin_x;
|
||||
*y += origin_y;
|
||||
}
|
||||
inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
|
||||
|
||||
*x += origin_x;
|
||||
*y += origin_y;
|
||||
}
|
||||
|
||||
inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
|
||||
|
||||
*x -= origin_x;
|
||||
*y -= origin_y;
|
||||
}
|
||||
inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
|
||||
|
||||
*x -= origin_x;
|
||||
*y -= origin_y;
|
||||
}
|
||||
inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
|
||||
|
||||
*x -= origin_x;
|
||||
*y -= origin_y;
|
||||
}
|
||||
|
||||
inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
|
||||
*x = get_glyph_h_kerning (first_glyph, second_glyph);
|
||||
*y = 0;
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = get_glyph_v_kerning (first_glyph, second_glyph);
|
||||
}
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_glyph_extents_t *extents)
|
||||
{
|
||||
hb_bool_t ret = get_glyph_extents (glyph, extents);
|
||||
|
||||
if (ret)
|
||||
subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
|
||||
|
||||
if (ret)
|
||||
subtract_glyph_origin_for_direction (glyph, direction, x, y);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generates gidDDD if glyph has no name. */
|
||||
inline void
|
||||
glyph_to_string (hb_codepoint_t glyph,
|
||||
char *s, unsigned int size)
|
||||
{
|
||||
if (get_glyph_name (glyph, s, size)) return;
|
||||
|
||||
if (size && snprintf (s, size, "gid%u", glyph) < 0)
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* Parses gidDDD and uniUUUU strings automatically. */
|
||||
inline hb_bool_t
|
||||
glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
if (get_glyph_from_name (s, len, glyph)) return true;
|
||||
|
||||
if (len == -1) len = strlen (s);
|
||||
|
||||
/* Straight glyph index. */
|
||||
if (hb_codepoint_parse (s, len, 10, glyph))
|
||||
return true;
|
||||
|
||||
if (len > 3)
|
||||
{
|
||||
/* gidDDD syntax for glyph indices. */
|
||||
if (0 == strncmp (s, "gid", 3) &&
|
||||
hb_codepoint_parse (s + 3, len - 3, 10, glyph))
|
||||
return true;
|
||||
|
||||
/* uniUUUU and other Unicode character indices. */
|
||||
hb_codepoint_t unichar;
|
||||
if (0 == strncmp (s, "uni", 3) &&
|
||||
hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
|
||||
get_nominal_glyph (unichar, glyph))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline hb_position_t em_scale (int16_t v, int scale)
|
||||
{
|
||||
int upem = face->get_upem ();
|
||||
int64_t scaled = v * (int64_t) scale;
|
||||
scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
|
||||
return (hb_position_t) (scaled / upem);
|
||||
}
|
||||
inline hb_position_t em_scalef (float v, int scale)
|
||||
{
|
||||
return (hb_position_t) (v * scale / face->get_upem ());
|
||||
}
|
||||
};
|
||||
|
||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
||||
|
||||
|
||||
#endif /* HB_FONT_PRIVATE_HH */
|
||||
1698
gfx/harfbuzz/src/hb-font.cc
Normal file
1698
gfx/harfbuzz/src/hb-font.cc
Normal file
File diff suppressed because it is too large
Load diff
614
gfx/harfbuzz/src/hb-font.h
Normal file
614
gfx/harfbuzz/src/hb-font.h
Normal file
|
|
@ -0,0 +1,614 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_H_IN
|
||||
#error "Include <hb.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_FONT_H
|
||||
#define HB_FONT_H
|
||||
|
||||
#include "hb-common.h"
|
||||
#include "hb-face.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct hb_font_t hb_font_t;
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_funcs_t
|
||||
*/
|
||||
|
||||
typedef struct hb_font_funcs_t hb_font_funcs_t;
|
||||
|
||||
HB_EXTERN hb_font_funcs_t *
|
||||
hb_font_funcs_create (void);
|
||||
|
||||
HB_EXTERN hb_font_funcs_t *
|
||||
hb_font_funcs_get_empty (void);
|
||||
|
||||
HB_EXTERN hb_font_funcs_t *
|
||||
hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
|
||||
|
||||
|
||||
/* font and glyph extents */
|
||||
|
||||
/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */
|
||||
typedef struct hb_font_extents_t
|
||||
{
|
||||
hb_position_t ascender; /* typographic ascender. */
|
||||
hb_position_t descender; /* typographic descender. */
|
||||
hb_position_t line_gap; /* suggested line spacing gap. */
|
||||
/*< private >*/
|
||||
hb_position_t reserved9;
|
||||
hb_position_t reserved8;
|
||||
hb_position_t reserved7;
|
||||
hb_position_t reserved6;
|
||||
hb_position_t reserved5;
|
||||
hb_position_t reserved4;
|
||||
hb_position_t reserved3;
|
||||
hb_position_t reserved2;
|
||||
hb_position_t reserved1;
|
||||
} hb_font_extents_t;
|
||||
|
||||
/* Note that height is negative in coordinate systems that grow up. */
|
||||
typedef struct hb_glyph_extents_t
|
||||
{
|
||||
hb_position_t x_bearing; /* left side of glyph from origin. */
|
||||
hb_position_t y_bearing; /* top side of glyph from origin. */
|
||||
hb_position_t width; /* distance from left to right side. */
|
||||
hb_position_t height; /* distance from top to bottom side. */
|
||||
} hb_glyph_extents_t;
|
||||
|
||||
/* func types */
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data);
|
||||
typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t;
|
||||
typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t;
|
||||
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
|
||||
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
|
||||
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
|
||||
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
|
||||
|
||||
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
void *user_data);
|
||||
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
|
||||
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
|
||||
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data);
|
||||
|
||||
|
||||
typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
char *name, unsigned int size,
|
||||
void *user_data);
|
||||
typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
|
||||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data);
|
||||
|
||||
|
||||
/* func setters */
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_font_h_extents_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 1.1.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_font_h_extents_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_font_v_extents_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 1.1.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_font_v_extents_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_nominal_glyph_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 1.2.3
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_nominal_glyph_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_variation_glyph_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 1.2.3
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_variation_glyph_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_h_advance_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_advance_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_v_advance_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_advance_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_h_origin_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_origin_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_v_origin_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_origin_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_h_kerning_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_h_kerning_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_v_kerning_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_v_kerning_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_extents_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_extents_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_contour_point_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_contour_point_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_name_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_name_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/**
|
||||
* hb_font_funcs_set_glyph_from_name_func:
|
||||
* @ffuncs: font functions.
|
||||
* @func: (closure user_data) (destroy destroy) (scope notified):
|
||||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
|
||||
hb_font_get_glyph_from_name_func_t func,
|
||||
void *user_data, hb_destroy_func_t destroy);
|
||||
|
||||
/* func dispatch */
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_h_extents (hb_font_t *font,
|
||||
hb_font_extents_t *extents);
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_v_extents (hb_font_t *font,
|
||||
hb_font_extents_t *extents);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_nominal_glyph (hb_font_t *font,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph);
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_variation_glyph (hb_font_t *font,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_font_get_glyph_h_advance (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
HB_EXTERN hb_position_t
|
||||
hb_font_get_glyph_v_advance (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_h_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_v_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_font_get_glyph_h_kerning (hb_font_t *font,
|
||||
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
|
||||
HB_EXTERN hb_position_t
|
||||
hb_font_get_glyph_v_kerning (hb_font_t *font,
|
||||
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_contour_point (hb_font_t *font,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_name (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
char *name, unsigned int size);
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_from_name (hb_font_t *font,
|
||||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
|
||||
/* high-level funcs, with fallback */
|
||||
|
||||
/* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
|
||||
* otherwise callse hb_font_get_variation_glyph(). */
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph (hb_font_t *font,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_get_extents_for_direction (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_font_extents_t *extents);
|
||||
HB_EXTERN void
|
||||
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
HB_EXTERN void
|
||||
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
HB_EXTERN void
|
||||
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
HB_EXTERN void
|
||||
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
|
||||
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_glyph_extents_t *extents);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
/* Generates gidDDD if glyph has no name. */
|
||||
HB_EXTERN void
|
||||
hb_font_glyph_to_string (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
char *s, unsigned int size);
|
||||
/* Parses gidDDD and uniUUUU strings automatically. */
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_glyph_from_string (hb_font_t *font,
|
||||
const char *s, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
|
||||
/*
|
||||
* hb_font_t
|
||||
*/
|
||||
|
||||
/* Fonts are very light-weight objects */
|
||||
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_font_create (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_font_create_sub_font (hb_font_t *parent);
|
||||
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_font_get_empty (void);
|
||||
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_font_reference (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_destroy (hb_font_t *font);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_set_user_data (hb_font_t *font,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_font_get_user_data (hb_font_t *font,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_make_immutable (hb_font_t *font);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_font_is_immutable (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_parent (hb_font_t *font,
|
||||
hb_font_t *parent);
|
||||
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_font_get_parent (hb_font_t *font);
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_font_get_face (hb_font_t *font);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_funcs (hb_font_t *font,
|
||||
hb_font_funcs_t *klass,
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* Be *very* careful with this function! */
|
||||
HB_EXTERN void
|
||||
hb_font_set_funcs_data (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_scale (hb_font_t *font,
|
||||
int x_scale,
|
||||
int y_scale);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_get_scale (hb_font_t *font,
|
||||
int *x_scale,
|
||||
int *y_scale);
|
||||
|
||||
/*
|
||||
* A zero value means "no hinting in that direction"
|
||||
*/
|
||||
HB_EXTERN void
|
||||
hb_font_set_ppem (hb_font_t *font,
|
||||
unsigned int x_ppem,
|
||||
unsigned int y_ppem);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_get_ppem (hb_font_t *font,
|
||||
unsigned int *x_ppem,
|
||||
unsigned int *y_ppem);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_var_coords_normalized (hb_font_t *font,
|
||||
int *coords, /* XXX 2.14 normalized */
|
||||
unsigned int coords_length);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_FONT_H */
|
||||
744
gfx/harfbuzz/src/hb-ft.cc
Normal file
744
gfx/harfbuzz/src/hb-ft.cc
Normal file
|
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2009 Keith Stribley
|
||||
* Copyright © 2015 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ft.h"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
|
||||
#include "hb-cache-private.hh" // Maybe use in the future?
|
||||
|
||||
#include FT_ADVANCES_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_FT
|
||||
#define HB_DEBUG_FT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* TODO:
|
||||
*
|
||||
* In general, this file does a fine job of what it's supposed to do.
|
||||
* There are, however, things that need more work:
|
||||
*
|
||||
* - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy.
|
||||
* Have not investigated.
|
||||
*
|
||||
* - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
|
||||
* would work fine. However, we also abuse this API for performing in font-space,
|
||||
* but don't pass the correct flags to FreeType. We just abuse the no-hinting mode
|
||||
* for that, such that no rounding etc happens. As such, we don't set ppem, and
|
||||
* pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale
|
||||
* ourselves, like we do in uniscribe, etc.
|
||||
*
|
||||
* - We don't handle / allow for emboldening / obliqueing.
|
||||
*
|
||||
* - In the future, we should add constructors to create fonts in font space?
|
||||
*
|
||||
* - FT_Load_Glyph() is exteremely costly. Do something about it?
|
||||
*/
|
||||
|
||||
|
||||
struct hb_ft_font_t
|
||||
{
|
||||
FT_Face ft_face;
|
||||
int load_flags;
|
||||
bool symbol; /* Whether selected cmap is symbol cmap. */
|
||||
bool unref; /* Whether to destroy ft_face when done. */
|
||||
};
|
||||
|
||||
static hb_ft_font_t *
|
||||
_hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
|
||||
{
|
||||
hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
|
||||
|
||||
if (unlikely (!ft_font))
|
||||
return NULL;
|
||||
|
||||
ft_font->ft_face = ft_face;
|
||||
ft_font->symbol = symbol;
|
||||
ft_font->unref = unref;
|
||||
|
||||
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
||||
|
||||
return ft_font;
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ft_face_destroy (FT_Face ft_face)
|
||||
{
|
||||
FT_Done_Face (ft_face);
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ft_font_destroy (hb_ft_font_t *ft_font)
|
||||
{
|
||||
if (ft_font->unref)
|
||||
_hb_ft_face_destroy (ft_font->ft_face);
|
||||
|
||||
free (ft_font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_font_set_load_flags:
|
||||
* @font:
|
||||
* @load_flags:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 1.0.5
|
||||
**/
|
||||
void
|
||||
hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
|
||||
{
|
||||
if (font->immutable)
|
||||
return;
|
||||
|
||||
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
||||
return;
|
||||
|
||||
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
|
||||
|
||||
ft_font->load_flags = load_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_font_get_load_flags:
|
||||
* @font:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* Since: 1.0.5
|
||||
**/
|
||||
int
|
||||
hb_ft_font_get_load_flags (hb_font_t *font)
|
||||
{
|
||||
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
||||
return 0;
|
||||
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
|
||||
|
||||
return ft_font->load_flags;
|
||||
}
|
||||
|
||||
FT_Face
|
||||
hb_ft_font_get_face (hb_font_t *font)
|
||||
{
|
||||
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
||||
return NULL;
|
||||
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
|
||||
|
||||
return ft_font->ft_face;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
|
||||
|
||||
if (unlikely (!g))
|
||||
{
|
||||
if (unlikely (ft_font->symbol) && unicode <= 0x00FFu)
|
||||
{
|
||||
/* For symbol-encoded OpenType fonts, we duplicate the
|
||||
* U+F000..F0FF range at U+0000..U+00FF. That's what
|
||||
* Windows seems to do, and that's hinted about at:
|
||||
* http://www.microsoft.com/typography/otspec/recom.htm
|
||||
* under "Non-Standard (Symbol) Fonts". */
|
||||
g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
|
||||
if (!g)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
*glyph = g;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
|
||||
|
||||
if (unlikely (!g))
|
||||
return false;
|
||||
|
||||
*glyph = g;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Fixed v;
|
||||
|
||||
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v)))
|
||||
return 0;
|
||||
|
||||
if (font->x_scale < 0)
|
||||
v = -v;
|
||||
|
||||
return (v + (1<<9)) >> 10;
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Fixed v;
|
||||
|
||||
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
|
||||
return 0;
|
||||
|
||||
if (font->y_scale < 0)
|
||||
v = -v;
|
||||
|
||||
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
||||
* have a Y growing upward. Hence the extra negation. */
|
||||
return (-v + (1<<9)) >> 10;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_position_t *x,
|
||||
hb_position_t *y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
|
||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
||||
return false;
|
||||
|
||||
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
||||
* have a Y growing upward. Hence the extra negation. */
|
||||
*x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX;
|
||||
*y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
|
||||
|
||||
if (font->x_scale < 0)
|
||||
*x = -*x;
|
||||
if (font->y_scale < 0)
|
||||
*y = -*y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ft_get_glyph_h_kerning (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_codepoint_t left_glyph,
|
||||
hb_codepoint_t right_glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Vector kerningv;
|
||||
|
||||
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
|
||||
if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
|
||||
return 0;
|
||||
|
||||
return kerningv.x;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
|
||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
||||
return false;
|
||||
|
||||
extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
|
||||
extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
|
||||
extents->width = ft_face->glyph->metrics.width;
|
||||
extents->height = -ft_face->glyph->metrics.height;
|
||||
if (font->x_scale < 0)
|
||||
{
|
||||
extents->x_bearing = -extents->x_bearing;
|
||||
extents->width = -extents->width;
|
||||
}
|
||||
if (font->y_scale < 0)
|
||||
{
|
||||
extents->y_bearing = -extents->y_bearing;
|
||||
extents->height = -extents->height;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int point_index,
|
||||
hb_position_t *x,
|
||||
hb_position_t *y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
|
||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
||||
return false;
|
||||
|
||||
if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
|
||||
return false;
|
||||
|
||||
if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
|
||||
return false;
|
||||
|
||||
*x = ft_face->glyph->outline.points[point_index].x;
|
||||
*y = ft_face->glyph->outline.points[point_index].y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
char *name, unsigned int size,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
|
||||
hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size);
|
||||
if (ret && (size && !*name))
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
const char *name, int len, /* -1 means nul-terminated */
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
|
||||
if (len < 0)
|
||||
*glyph = FT_Get_Name_Index (ft_face, (FT_String *) name);
|
||||
else {
|
||||
/* Make a nul-terminated version. */
|
||||
char buf[128];
|
||||
len = MIN (len, (int) sizeof (buf) - 1);
|
||||
strncpy (buf, name, len);
|
||||
buf[len] = '\0';
|
||||
*glyph = FT_Get_Name_Index (ft_face, buf);
|
||||
}
|
||||
|
||||
if (*glyph == 0)
|
||||
{
|
||||
/* Check whether the given name was actually the name of glyph 0. */
|
||||
char buf[128];
|
||||
if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) &&
|
||||
len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
|
||||
return true;
|
||||
}
|
||||
|
||||
return *glyph != 0;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
metrics->ascender = ft_face->size->metrics.ascender;
|
||||
metrics->descender = ft_face->size->metrics.descender;
|
||||
metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender);
|
||||
if (font->y_scale < 0)
|
||||
{
|
||||
metrics->ascender = -metrics->ascender;
|
||||
metrics->descender = -metrics->descender;
|
||||
metrics->line_gap = -metrics->line_gap;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_font_funcs_t *static_ft_funcs = NULL;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_ft_funcs (void)
|
||||
{
|
||||
hb_font_funcs_destroy (static_ft_funcs);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
|
||||
{
|
||||
retry:
|
||||
hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs);
|
||||
|
||||
if (unlikely (!funcs))
|
||||
{
|
||||
funcs = hb_font_funcs_create ();
|
||||
|
||||
hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, NULL, NULL);
|
||||
//hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, NULL, NULL);
|
||||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, NULL, NULL);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, NULL, NULL);
|
||||
|
||||
hb_font_funcs_make_immutable (funcs);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) {
|
||||
hb_font_funcs_destroy (funcs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_static_ft_funcs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
};
|
||||
|
||||
bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
|
||||
|
||||
hb_font_set_funcs (font,
|
||||
funcs,
|
||||
_hb_ft_font_create (ft_face, symbol, unref),
|
||||
(hb_destroy_func_t) _hb_ft_font_destroy);
|
||||
}
|
||||
|
||||
|
||||
static hb_blob_t *
|
||||
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
FT_Face ft_face = (FT_Face) user_data;
|
||||
FT_Byte *buffer;
|
||||
FT_ULong length = 0;
|
||||
FT_Error error;
|
||||
|
||||
/* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
|
||||
|
||||
error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
buffer = (FT_Byte *) malloc (length);
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
|
||||
if (error)
|
||||
return NULL;
|
||||
|
||||
return hb_blob_create ((const char *) buffer, length,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
buffer, free);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_face_create:
|
||||
* @ft_face: (destroy destroy) (scope notified):
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_ft_face_create (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_face_t *face;
|
||||
|
||||
if (ft_face->stream->read == NULL) {
|
||||
hb_blob_t *blob;
|
||||
|
||||
blob = hb_blob_create ((const char *) ft_face->stream->base,
|
||||
(unsigned int) ft_face->stream->size,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
ft_face, destroy);
|
||||
face = hb_face_create (blob, ft_face->face_index);
|
||||
hb_blob_destroy (blob);
|
||||
} else {
|
||||
face = hb_face_create_for_tables (reference_table, ft_face, destroy);
|
||||
}
|
||||
|
||||
hb_face_set_index (face, ft_face->face_index);
|
||||
hb_face_set_upem (face, ft_face->units_per_EM);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_face_create_referenced:
|
||||
* @ft_face:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Since: 0.9.38
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_ft_face_create_referenced (FT_Face ft_face)
|
||||
{
|
||||
FT_Reference_Face (ft_face);
|
||||
return hb_ft_face_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ft_face_finalize (FT_Face ft_face)
|
||||
{
|
||||
hb_face_destroy ((hb_face_t *) ft_face->generic.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_face_create_cached:
|
||||
* @ft_face:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_ft_face_create_cached (FT_Face ft_face)
|
||||
{
|
||||
if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
|
||||
{
|
||||
if (ft_face->generic.finalizer)
|
||||
ft_face->generic.finalizer (ft_face);
|
||||
|
||||
ft_face->generic.data = hb_ft_face_create (ft_face, NULL);
|
||||
ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
|
||||
}
|
||||
|
||||
return hb_face_reference ((hb_face_t *) ft_face->generic.data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_ft_font_create:
|
||||
* @ft_face: (destroy destroy) (scope notified):
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
hb_font_t *
|
||||
hb_ft_font_create (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy)
|
||||
{
|
||||
hb_font_t *font;
|
||||
hb_face_t *face;
|
||||
|
||||
face = hb_ft_face_create (ft_face, destroy);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
_hb_ft_font_set_funcs (font, ft_face, false);
|
||||
hb_font_set_scale (font,
|
||||
(int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16),
|
||||
(int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16));
|
||||
#if 0 /* hb-ft works in no-hinting model */
|
||||
hb_font_set_ppem (font,
|
||||
ft_face->size->metrics.x_ppem,
|
||||
ft_face->size->metrics.y_ppem);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FT_GET_VAR_BLEND_COORDINATES
|
||||
FT_MM_Var *mm_var = NULL;
|
||||
if (!FT_Get_MM_Var (ft_face, &mm_var))
|
||||
{
|
||||
FT_Fixed coords[mm_var->num_axis];
|
||||
int hbCoords[mm_var->num_axis];
|
||||
if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, coords))
|
||||
{
|
||||
for (int i = 0; i < mm_var->num_axis; ++i)
|
||||
hbCoords[i] = coords[i] >> 2;
|
||||
|
||||
hb_font_set_var_coords_normalized (font, hbCoords, mm_var->num_axis);
|
||||
}
|
||||
}
|
||||
free (mm_var);
|
||||
#endif
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ft_font_create_referenced:
|
||||
* @ft_face:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* Since: 0.9.38
|
||||
**/
|
||||
hb_font_t *
|
||||
hb_ft_font_create_referenced (FT_Face ft_face)
|
||||
{
|
||||
FT_Reference_Face (ft_face);
|
||||
return hb_ft_font_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
|
||||
}
|
||||
|
||||
|
||||
/* Thread-safe, lock-free, FT_Library */
|
||||
|
||||
static FT_Library ft_library;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_ft_library (void)
|
||||
{
|
||||
FT_Done_FreeType (ft_library);
|
||||
}
|
||||
#endif
|
||||
|
||||
static FT_Library
|
||||
get_ft_library (void)
|
||||
{
|
||||
retry:
|
||||
FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library);
|
||||
|
||||
if (unlikely (!library))
|
||||
{
|
||||
/* Not found; allocate one. */
|
||||
if (FT_Init_FreeType (&library))
|
||||
return NULL;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&ft_library, NULL, library)) {
|
||||
FT_Done_FreeType (library);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_ft_library); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
}
|
||||
|
||||
return library;
|
||||
}
|
||||
|
||||
static void
|
||||
_release_blob (FT_Face ft_face)
|
||||
{
|
||||
hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
|
||||
}
|
||||
|
||||
void
|
||||
hb_ft_font_set_funcs (hb_font_t *font)
|
||||
{
|
||||
hb_blob_t *blob = hb_face_reference_blob (font->face);
|
||||
unsigned int blob_length;
|
||||
const char *blob_data = hb_blob_get_data (blob, &blob_length);
|
||||
if (unlikely (!blob_length))
|
||||
DEBUG_MSG (FT, font, "Font face has empty blob");
|
||||
|
||||
FT_Face ft_face = NULL;
|
||||
FT_Error err = FT_New_Memory_Face (get_ft_library (),
|
||||
(const FT_Byte *) blob_data,
|
||||
blob_length,
|
||||
hb_face_get_index (font->face),
|
||||
&ft_face);
|
||||
|
||||
if (unlikely (err)) {
|
||||
hb_blob_destroy (blob);
|
||||
DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
|
||||
FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
|
||||
|
||||
FT_Set_Char_Size (ft_face,
|
||||
abs (font->x_scale), abs (font->y_scale),
|
||||
0, 0);
|
||||
#if 0
|
||||
font->x_ppem * 72 * 64 / font->x_scale,
|
||||
font->y_ppem * 72 * 64 / font->y_scale);
|
||||
#endif
|
||||
if (font->x_scale < 0 || font->y_scale < 0)
|
||||
{
|
||||
FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
|
||||
0, font->y_scale < 0 ? -1 : +1};
|
||||
FT_Set_Transform (ft_face, &matrix, NULL);
|
||||
}
|
||||
|
||||
ft_face->generic.data = blob;
|
||||
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
|
||||
|
||||
_hb_ft_font_set_funcs (font, ft_face, true);
|
||||
hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
|
||||
}
|
||||
126
gfx/harfbuzz/src/hb-ft.h
Normal file
126
gfx/harfbuzz/src/hb-ft.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2015 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_FT_H
|
||||
#define HB_FT_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Note: FreeType is not thread-safe.
|
||||
* Hence, these functions are not either.
|
||||
*/
|
||||
|
||||
/*
|
||||
* hb-face from ft-face.
|
||||
*/
|
||||
|
||||
/* This one creates a new hb-face for given ft-face.
|
||||
* When the returned hb-face is destroyed, the destroy
|
||||
* callback is called (if not NULL), with the ft-face passed
|
||||
* to it.
|
||||
*
|
||||
* The client is responsible to make sure that ft-face is
|
||||
* destroyed after hb-face is destroyed.
|
||||
*
|
||||
* Most often you don't want this function. You should use either
|
||||
* hb_ft_face_create_cached(), or hb_ft_face_create_referenced().
|
||||
* In particular, if you are going to pass NULL as destroy, you
|
||||
* probably should use (the more recent) hb_ft_face_create_referenced()
|
||||
* instead.
|
||||
*/
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_ft_face_create (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* This version is like hb_ft_face_create(), except that it caches
|
||||
* the hb-face using the generic pointer of the ft-face. This means
|
||||
* that subsequent calls to this function with the same ft-face will
|
||||
* return the same hb-face (correctly referenced).
|
||||
*
|
||||
* Client is still responsible for making sure that ft-face is destroyed
|
||||
* after hb-face is.
|
||||
*/
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_ft_face_create_cached (FT_Face ft_face);
|
||||
|
||||
/* This version is like hb_ft_face_create(), except that it calls
|
||||
* FT_Reference_Face() on ft-face, as such keeping ft-face alive
|
||||
* as long as the hb-face is.
|
||||
*
|
||||
* This is the most convenient version to use. Use it unless you have
|
||||
* very good reasons not to.
|
||||
*/
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_ft_face_create_referenced (FT_Face ft_face);
|
||||
|
||||
|
||||
/*
|
||||
* hb-font from ft-face.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
*
|
||||
* Set face size on ft-face before creating hb-font from it.
|
||||
* Otherwise hb-ft would NOT pick up the font size correctly.
|
||||
*/
|
||||
|
||||
/* See notes on hb_ft_face_create(). Same issues re lifecycle-management
|
||||
* apply here. Use hb_ft_font_create_referenced() if you can. */
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_ft_font_create (FT_Face ft_face,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
/* See notes on hb_ft_face_create_referenced() re lifecycle-management
|
||||
* issues. */
|
||||
HB_EXTERN hb_font_t *
|
||||
hb_ft_font_create_referenced (FT_Face ft_face);
|
||||
|
||||
HB_EXTERN FT_Face
|
||||
hb_ft_font_get_face (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
|
||||
|
||||
HB_EXTERN int
|
||||
hb_ft_font_get_load_flags (hb_font_t *font);
|
||||
|
||||
/* Makes an hb_font_t use FreeType internally to implement font functions. */
|
||||
HB_EXTERN void
|
||||
hb_ft_font_set_funcs (hb_font_t *font);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_FT_H */
|
||||
402
gfx/harfbuzz/src/hb-glib.cc
Normal file
402
gfx/harfbuzz/src/hb-glib.cc
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-glib.h"
|
||||
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,29,14)
|
||||
static const hb_script_t
|
||||
glib_script_to_script[] =
|
||||
{
|
||||
HB_SCRIPT_COMMON,
|
||||
HB_SCRIPT_INHERITED,
|
||||
HB_SCRIPT_ARABIC,
|
||||
HB_SCRIPT_ARMENIAN,
|
||||
HB_SCRIPT_BENGALI,
|
||||
HB_SCRIPT_BOPOMOFO,
|
||||
HB_SCRIPT_CHEROKEE,
|
||||
HB_SCRIPT_COPTIC,
|
||||
HB_SCRIPT_CYRILLIC,
|
||||
HB_SCRIPT_DESERET,
|
||||
HB_SCRIPT_DEVANAGARI,
|
||||
HB_SCRIPT_ETHIOPIC,
|
||||
HB_SCRIPT_GEORGIAN,
|
||||
HB_SCRIPT_GOTHIC,
|
||||
HB_SCRIPT_GREEK,
|
||||
HB_SCRIPT_GUJARATI,
|
||||
HB_SCRIPT_GURMUKHI,
|
||||
HB_SCRIPT_HAN,
|
||||
HB_SCRIPT_HANGUL,
|
||||
HB_SCRIPT_HEBREW,
|
||||
HB_SCRIPT_HIRAGANA,
|
||||
HB_SCRIPT_KANNADA,
|
||||
HB_SCRIPT_KATAKANA,
|
||||
HB_SCRIPT_KHMER,
|
||||
HB_SCRIPT_LAO,
|
||||
HB_SCRIPT_LATIN,
|
||||
HB_SCRIPT_MALAYALAM,
|
||||
HB_SCRIPT_MONGOLIAN,
|
||||
HB_SCRIPT_MYANMAR,
|
||||
HB_SCRIPT_OGHAM,
|
||||
HB_SCRIPT_OLD_ITALIC,
|
||||
HB_SCRIPT_ORIYA,
|
||||
HB_SCRIPT_RUNIC,
|
||||
HB_SCRIPT_SINHALA,
|
||||
HB_SCRIPT_SYRIAC,
|
||||
HB_SCRIPT_TAMIL,
|
||||
HB_SCRIPT_TELUGU,
|
||||
HB_SCRIPT_THAANA,
|
||||
HB_SCRIPT_THAI,
|
||||
HB_SCRIPT_TIBETAN,
|
||||
HB_SCRIPT_CANADIAN_SYLLABICS,
|
||||
HB_SCRIPT_YI,
|
||||
HB_SCRIPT_TAGALOG,
|
||||
HB_SCRIPT_HANUNOO,
|
||||
HB_SCRIPT_BUHID,
|
||||
HB_SCRIPT_TAGBANWA,
|
||||
|
||||
/* Unicode-4.0 additions */
|
||||
HB_SCRIPT_BRAILLE,
|
||||
HB_SCRIPT_CYPRIOT,
|
||||
HB_SCRIPT_LIMBU,
|
||||
HB_SCRIPT_OSMANYA,
|
||||
HB_SCRIPT_SHAVIAN,
|
||||
HB_SCRIPT_LINEAR_B,
|
||||
HB_SCRIPT_TAI_LE,
|
||||
HB_SCRIPT_UGARITIC,
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
HB_SCRIPT_NEW_TAI_LUE,
|
||||
HB_SCRIPT_BUGINESE,
|
||||
HB_SCRIPT_GLAGOLITIC,
|
||||
HB_SCRIPT_TIFINAGH,
|
||||
HB_SCRIPT_SYLOTI_NAGRI,
|
||||
HB_SCRIPT_OLD_PERSIAN,
|
||||
HB_SCRIPT_KHAROSHTHI,
|
||||
|
||||
/* Unicode-5.0 additions */
|
||||
HB_SCRIPT_UNKNOWN,
|
||||
HB_SCRIPT_BALINESE,
|
||||
HB_SCRIPT_CUNEIFORM,
|
||||
HB_SCRIPT_PHOENICIAN,
|
||||
HB_SCRIPT_PHAGS_PA,
|
||||
HB_SCRIPT_NKO,
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
HB_SCRIPT_KAYAH_LI,
|
||||
HB_SCRIPT_LEPCHA,
|
||||
HB_SCRIPT_REJANG,
|
||||
HB_SCRIPT_SUNDANESE,
|
||||
HB_SCRIPT_SAURASHTRA,
|
||||
HB_SCRIPT_CHAM,
|
||||
HB_SCRIPT_OL_CHIKI,
|
||||
HB_SCRIPT_VAI,
|
||||
HB_SCRIPT_CARIAN,
|
||||
HB_SCRIPT_LYCIAN,
|
||||
HB_SCRIPT_LYDIAN,
|
||||
|
||||
/* Unicode-5.2 additions */
|
||||
HB_SCRIPT_AVESTAN,
|
||||
HB_SCRIPT_BAMUM,
|
||||
HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
|
||||
HB_SCRIPT_IMPERIAL_ARAMAIC,
|
||||
HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
|
||||
HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
|
||||
HB_SCRIPT_JAVANESE,
|
||||
HB_SCRIPT_KAITHI,
|
||||
HB_SCRIPT_TAI_THAM,
|
||||
HB_SCRIPT_LISU,
|
||||
HB_SCRIPT_MEETEI_MAYEK,
|
||||
HB_SCRIPT_OLD_SOUTH_ARABIAN,
|
||||
HB_SCRIPT_OLD_TURKIC,
|
||||
HB_SCRIPT_SAMARITAN,
|
||||
HB_SCRIPT_TAI_VIET,
|
||||
|
||||
/* Unicode-6.0 additions */
|
||||
HB_SCRIPT_BATAK,
|
||||
HB_SCRIPT_BRAHMI,
|
||||
HB_SCRIPT_MANDAIC,
|
||||
|
||||
/* Unicode-6.1 additions */
|
||||
HB_SCRIPT_CHAKMA,
|
||||
HB_SCRIPT_MEROITIC_CURSIVE,
|
||||
HB_SCRIPT_MEROITIC_HIEROGLYPHS,
|
||||
HB_SCRIPT_MIAO,
|
||||
HB_SCRIPT_SHARADA,
|
||||
HB_SCRIPT_SORA_SOMPENG,
|
||||
HB_SCRIPT_TAKRI
|
||||
};
|
||||
#endif
|
||||
|
||||
hb_script_t
|
||||
hb_glib_script_to_script (GUnicodeScript script)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION(2,29,14)
|
||||
return (hb_script_t) g_unicode_script_to_iso15924 (script);
|
||||
#else
|
||||
if (likely ((unsigned int) script < ARRAY_LENGTH (glib_script_to_script)))
|
||||
return glib_script_to_script[script];
|
||||
|
||||
if (unlikely (script == G_UNICODE_SCRIPT_INVALID_CODE))
|
||||
return HB_SCRIPT_INVALID;
|
||||
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
GUnicodeScript
|
||||
hb_glib_script_from_script (hb_script_t script)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION(2,29,14)
|
||||
return g_unicode_script_from_iso15924 (script);
|
||||
#else
|
||||
unsigned int count = ARRAY_LENGTH (glib_script_to_script);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (glib_script_to_script[i] == script)
|
||||
return (GUnicodeScript) i;
|
||||
|
||||
if (unlikely (script == HB_SCRIPT_INVALID))
|
||||
return G_UNICODE_SCRIPT_INVALID_CODE;
|
||||
|
||||
return G_UNICODE_SCRIPT_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static hb_unicode_combining_class_t
|
||||
hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
|
||||
{
|
||||
return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return g_unichar_iswide (unicode) ? 2 : 1;
|
||||
}
|
||||
|
||||
static hb_unicode_general_category_t
|
||||
hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
|
||||
{
|
||||
/* hb_unicode_general_category_t and GUnicodeType are identical */
|
||||
return (hb_unicode_general_category_t) g_unichar_type (unicode);
|
||||
}
|
||||
|
||||
static hb_codepoint_t
|
||||
hb_glib_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
g_unichar_get_mirror_char (unicode, &unicode);
|
||||
return unicode;
|
||||
}
|
||||
|
||||
static hb_script_t
|
||||
hb_glib_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return hb_glib_script_to_script (g_unichar_get_script (unicode));
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION(2,29,12)
|
||||
return g_unichar_compose (a, b, ab);
|
||||
#endif
|
||||
|
||||
/* We don't ifdef-out the fallback code such that compiler always
|
||||
* sees it and makes sure it's compilable. */
|
||||
|
||||
gchar utf8[12];
|
||||
gchar *normalized;
|
||||
int len;
|
||||
hb_bool_t ret;
|
||||
|
||||
len = g_unichar_to_utf8 (a, utf8);
|
||||
len += g_unichar_to_utf8 (b, utf8 + len);
|
||||
normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC);
|
||||
len = g_utf8_strlen (normalized, -1);
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
if (len == 1) {
|
||||
*ab = g_utf8_get_char (normalized);
|
||||
ret = true;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
g_free (normalized);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION(2,29,12)
|
||||
return g_unichar_decompose (ab, a, b);
|
||||
#endif
|
||||
|
||||
/* We don't ifdef-out the fallback code such that compiler always
|
||||
* sees it and makes sure it's compilable. */
|
||||
|
||||
gchar utf8[6];
|
||||
gchar *normalized;
|
||||
int len;
|
||||
hb_bool_t ret;
|
||||
|
||||
len = g_unichar_to_utf8 (ab, utf8);
|
||||
normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD);
|
||||
len = g_utf8_strlen (normalized, -1);
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
if (len == 1) {
|
||||
*a = g_utf8_get_char (normalized);
|
||||
*b = 0;
|
||||
ret = *a != ab;
|
||||
} else if (len == 2) {
|
||||
*a = g_utf8_get_char (normalized);
|
||||
*b = g_utf8_get_char (g_utf8_next_char (normalized));
|
||||
/* Here's the ugly part: if ab decomposes to a single character and
|
||||
* that character decomposes again, we have to detect that and undo
|
||||
* the second part :-(. */
|
||||
gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC);
|
||||
hb_codepoint_t c = g_utf8_get_char (recomposed);
|
||||
if (c != ab && c != *a) {
|
||||
*a = c;
|
||||
*b = 0;
|
||||
}
|
||||
g_free (recomposed);
|
||||
ret = true;
|
||||
} else {
|
||||
/* If decomposed to more than two characters, take the last one,
|
||||
* and recompose the rest to get the first component. */
|
||||
gchar *end = g_utf8_offset_to_pointer (normalized, len - 1);
|
||||
gchar *recomposed;
|
||||
*b = g_utf8_get_char (end);
|
||||
recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC);
|
||||
/* We expect that recomposed has exactly one character now. */
|
||||
*a = g_utf8_get_char (recomposed);
|
||||
g_free (recomposed);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
g_free (normalized);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
#if GLIB_CHECK_VERSION(2,29,12)
|
||||
return g_unichar_fully_decompose (u, true, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
|
||||
#endif
|
||||
|
||||
/* If the user doesn't have GLib >= 2.29.12 we have to perform
|
||||
* a round trip to UTF-8 and the associated memory management dance. */
|
||||
gchar utf8[6];
|
||||
gchar *utf8_decomposed, *c;
|
||||
gsize utf8_len, utf8_decomposed_len, i;
|
||||
|
||||
/* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */
|
||||
utf8_len = g_unichar_to_utf8 (u, utf8);
|
||||
utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD);
|
||||
utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1);
|
||||
|
||||
assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
|
||||
|
||||
for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c))
|
||||
*decomposed++ = g_utf8_get_char (c);
|
||||
|
||||
g_free (utf8_decomposed);
|
||||
|
||||
return utf8_decomposed_len;
|
||||
}
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_glib_get_unicode_funcs (void)
|
||||
{
|
||||
static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
NULL, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
|
||||
}
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,31,10)
|
||||
/**
|
||||
* hb_glib_blob_create:
|
||||
*
|
||||
* Since: 0.9.38
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_glib_blob_create (GBytes *gbytes)
|
||||
{
|
||||
gsize size = 0;
|
||||
gconstpointer data = g_bytes_get_data (gbytes, &size);
|
||||
return hb_blob_create ((const char *) data,
|
||||
size,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
g_bytes_ref (gbytes),
|
||||
(hb_destroy_func_t) g_bytes_unref);
|
||||
}
|
||||
#endif
|
||||
56
gfx/harfbuzz/src/hb-glib.h
Normal file
56
gfx/harfbuzz/src/hb-glib.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_GLIB_H
|
||||
#define HB_GLIB_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_glib_script_to_script (GUnicodeScript script);
|
||||
|
||||
HB_EXTERN GUnicodeScript
|
||||
hb_glib_script_from_script (hb_script_t script);
|
||||
|
||||
|
||||
HB_EXTERN hb_unicode_funcs_t *
|
||||
hb_glib_get_unicode_funcs (void);
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,31,10)
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_glib_blob_create (GBytes *gbytes);
|
||||
#endif
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_GLIB_H */
|
||||
73
gfx/harfbuzz/src/hb-gobject-enums.cc.tmpl
Normal file
73
gfx/harfbuzz/src/hb-gobject-enums.cc.tmpl
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*** BEGIN file-header ***/
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
/* g++ didn't like older gtype.h gcc-only code path. */
|
||||
#include <glib.h>
|
||||
#if !GLIB_CHECK_VERSION(2,29,16)
|
||||
#undef __GNUC__
|
||||
#undef __GNUC_MINOR__
|
||||
#define __GNUC__ 2
|
||||
#define __GNUC_MINOR__ 6
|
||||
#endif
|
||||
|
||||
#include "hb-gobject.h"
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@filename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static gsize type_id = 0;
|
||||
|
||||
if (g_once_init_enter (&type_id))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType id =
|
||||
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
g_once_init_leave (&type_id, id);
|
||||
}
|
||||
|
||||
return type_id;
|
||||
}
|
||||
|
||||
/*** END value-tail ***/
|
||||
55
gfx/harfbuzz/src/hb-gobject-enums.h.tmpl
Normal file
55
gfx/harfbuzz/src/hb-gobject-enums.h.tmpl
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*** BEGIN file-header ***/
|
||||
/*
|
||||
* Copyright © 2013 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_GOBJECT_H_IN
|
||||
#error "Include <hb-gobject.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_GOBJECT_ENUMS_H
|
||||
#define HB_GOBJECT_ENUMS_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
HB_EXTERN GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
|
||||
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_GOBJECT_ENUMS_H */
|
||||
/*** END file-tail ***/
|
||||
83
gfx/harfbuzz/src/hb-gobject-structs.cc
Normal file
83
gfx/harfbuzz/src/hb-gobject-structs.cc
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
/* g++ didn't like older gtype.h gcc-only code path. */
|
||||
#include <glib.h>
|
||||
#if !GLIB_CHECK_VERSION(2,29,16)
|
||||
#undef __GNUC__
|
||||
#undef __GNUC_MINOR__
|
||||
#define __GNUC__ 2
|
||||
#define __GNUC_MINOR__ 6
|
||||
#endif
|
||||
|
||||
#include "hb-gobject.h"
|
||||
|
||||
#define HB_DEFINE_BOXED_TYPE(name,copy_func,free_func) \
|
||||
GType \
|
||||
hb_gobject_##name##_get_type (void) \
|
||||
{ \
|
||||
static gsize type_id = 0; \
|
||||
if (g_once_init_enter (&type_id)) { \
|
||||
GType id = g_boxed_type_register_static (g_intern_static_string ("hb_" #name "_t"), \
|
||||
(GBoxedCopyFunc) copy_func, \
|
||||
(GBoxedFreeFunc) free_func); \
|
||||
g_once_init_leave (&type_id, id); \
|
||||
} \
|
||||
return type_id; \
|
||||
}
|
||||
|
||||
#define HB_DEFINE_OBJECT_TYPE(name) \
|
||||
HB_DEFINE_BOXED_TYPE (name, hb_##name##_reference, hb_##name##_destroy);
|
||||
|
||||
#define HB_DEFINE_VALUE_TYPE(name) \
|
||||
static hb_##name##_t *_hb_##name##_reference (const hb_##name##_t *l) \
|
||||
{ \
|
||||
hb_##name##_t *c = (hb_##name##_t *) calloc (1, sizeof (hb_##name##_t)); \
|
||||
if (unlikely (!c)) return NULL; \
|
||||
*c = *l; \
|
||||
return c; \
|
||||
} \
|
||||
static void _hb_##name##_destroy (hb_##name##_t *l) { free (l); } \
|
||||
HB_DEFINE_BOXED_TYPE (name, _hb_##name##_reference, _hb_##name##_destroy);
|
||||
|
||||
HB_DEFINE_OBJECT_TYPE (buffer)
|
||||
HB_DEFINE_OBJECT_TYPE (blob)
|
||||
HB_DEFINE_OBJECT_TYPE (face)
|
||||
HB_DEFINE_OBJECT_TYPE (font)
|
||||
HB_DEFINE_OBJECT_TYPE (font_funcs)
|
||||
HB_DEFINE_OBJECT_TYPE (set)
|
||||
HB_DEFINE_OBJECT_TYPE (shape_plan)
|
||||
HB_DEFINE_OBJECT_TYPE (unicode_funcs)
|
||||
HB_DEFINE_VALUE_TYPE (feature)
|
||||
HB_DEFINE_VALUE_TYPE (glyph_info)
|
||||
HB_DEFINE_VALUE_TYPE (glyph_position)
|
||||
HB_DEFINE_VALUE_TYPE (segment_properties)
|
||||
HB_DEFINE_VALUE_TYPE (user_data_key)
|
||||
|
||||
HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
|
||||
HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
|
||||
117
gfx/harfbuzz/src/hb-gobject-structs.h
Normal file
117
gfx/harfbuzz/src/hb-gobject-structs.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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_GOBJECT_H_IN
|
||||
#error "Include <hb-gobject.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_GOBJECT_STRUCTS_H
|
||||
#define HB_GOBJECT_STRUCTS_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/* Object types */
|
||||
|
||||
/**
|
||||
* hb_gobject_blob_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_blob_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ())
|
||||
|
||||
/**
|
||||
* hb_gobject_buffer_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_buffer_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
|
||||
|
||||
/**
|
||||
* hb_gobject_face_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_face_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
|
||||
|
||||
/**
|
||||
* hb_gobject_font_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_font_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ())
|
||||
|
||||
/**
|
||||
* hb_gobject_font_funcs_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_font_funcs_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_set_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_shape_plan_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
|
||||
|
||||
/**
|
||||
* hb_gobject_unicode_funcs_get_type:
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ())
|
||||
|
||||
/* Value types */
|
||||
|
||||
HB_EXTERN GType hb_gobject_feature_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_glyph_info_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_glyph_position_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_segment_properties_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ())
|
||||
|
||||
HB_EXTERN GType hb_gobject_user_data_key_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ())
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_GOBJECT_H */
|
||||
40
gfx/harfbuzz/src/hb-gobject.h
Normal file
40
gfx/harfbuzz/src/hb-gobject.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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_GOBJECT_H
|
||||
#define HB_GOBJECT_H
|
||||
#define HB_GOBJECT_H_IN
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include "hb-gobject-enums.h"
|
||||
#include "hb-gobject-structs.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
HB_END_DECLS
|
||||
|
||||
#undef HB_GOBJECT_H_IN
|
||||
#endif /* HB_GOBJECT_H */
|
||||
427
gfx/harfbuzz/src/hb-graphite2.cc
Normal file
427
gfx/harfbuzz/src/hb-graphite2.cc
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
* Copyright © 2011 Martin Hosken
|
||||
* Copyright © 2011 SIL International
|
||||
* Copyright © 2011,2012 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
|
||||
*/
|
||||
|
||||
#define HB_SHAPER graphite2
|
||||
#define hb_graphite2_shaper_font_data_t gr_font
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
#include "hb-graphite2.h"
|
||||
|
||||
#include <graphite2/Segment.h>
|
||||
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(graphite2, face)
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(graphite2, font)
|
||||
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
||||
typedef struct hb_graphite2_tablelist_t {
|
||||
struct hb_graphite2_tablelist_t *next;
|
||||
hb_blob_t *blob;
|
||||
unsigned int tag;
|
||||
} hb_graphite2_tablelist_t;
|
||||
|
||||
struct hb_graphite2_shaper_face_data_t {
|
||||
hb_face_t *face;
|
||||
gr_face *grface;
|
||||
hb_graphite2_tablelist_t *tlist;
|
||||
};
|
||||
|
||||
static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len)
|
||||
{
|
||||
hb_graphite2_shaper_face_data_t *face_data = (hb_graphite2_shaper_face_data_t *) data;
|
||||
hb_graphite2_tablelist_t *tlist = face_data->tlist;
|
||||
|
||||
hb_blob_t *blob = NULL;
|
||||
|
||||
for (hb_graphite2_tablelist_t *p = tlist; p; p = p->next)
|
||||
if (p->tag == tag) {
|
||||
blob = p->blob;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely (!blob))
|
||||
{
|
||||
blob = face_data->face->reference_table (tag);
|
||||
|
||||
hb_graphite2_tablelist_t *p = (hb_graphite2_tablelist_t *) calloc (1, sizeof (hb_graphite2_tablelist_t));
|
||||
if (unlikely (!p)) {
|
||||
hb_blob_destroy (blob);
|
||||
return NULL;
|
||||
}
|
||||
p->blob = blob;
|
||||
p->tag = tag;
|
||||
|
||||
/* TODO Not thread-safe, but fairly harmless.
|
||||
* We can do the double-chcked pointer cmpexch thing here. */
|
||||
p->next = face_data->tlist;
|
||||
face_data->tlist = p;
|
||||
}
|
||||
|
||||
unsigned int tlen;
|
||||
const char *d = hb_blob_get_data (blob, &tlen);
|
||||
*len = tlen;
|
||||
return d;
|
||||
}
|
||||
|
||||
hb_graphite2_shaper_face_data_t *
|
||||
_hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
hb_blob_t *silf_blob = face->reference_table (HB_GRAPHITE2_TAG_SILF);
|
||||
/* Umm, we just reference the table to check whether it exists.
|
||||
* Maybe add better API for this? */
|
||||
if (!hb_blob_get_length (silf_blob))
|
||||
{
|
||||
hb_blob_destroy (silf_blob);
|
||||
return NULL;
|
||||
}
|
||||
hb_blob_destroy (silf_blob);
|
||||
|
||||
hb_graphite2_shaper_face_data_t *data = (hb_graphite2_shaper_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t));
|
||||
if (unlikely (!data))
|
||||
return NULL;
|
||||
|
||||
data->face = face;
|
||||
data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
|
||||
|
||||
if (unlikely (!data->grface)) {
|
||||
free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data)
|
||||
{
|
||||
hb_graphite2_tablelist_t *tlist = data->tlist;
|
||||
|
||||
while (tlist)
|
||||
{
|
||||
hb_graphite2_tablelist_t *old = tlist;
|
||||
hb_blob_destroy (tlist->blob);
|
||||
tlist = tlist->next;
|
||||
free (old);
|
||||
}
|
||||
|
||||
gr_face_destroy (data->grface);
|
||||
|
||||
free (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
gr_face *
|
||||
hb_graphite2_face_get_gr_face (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return NULL;
|
||||
return HB_SHAPER_DATA_GET (face)->grface;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper font data
|
||||
*/
|
||||
|
||||
static float hb_graphite2_get_advance (const void *hb_font, unsigned short gid)
|
||||
{
|
||||
return ((hb_font_t *) hb_font)->get_glyph_h_advance (gid);
|
||||
}
|
||||
|
||||
hb_graphite2_shaper_font_data_t *
|
||||
_hb_graphite2_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_graphite2_shaper_face_data_ensure (font->face))) return NULL;
|
||||
|
||||
hb_face_t *face = font->face;
|
||||
hb_graphite2_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
|
||||
return gr_make_font_with_advance_fn (font->x_scale, font, &hb_graphite2_get_advance, face_data->grface);
|
||||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data)
|
||||
{
|
||||
gr_font_destroy (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
gr_font *
|
||||
hb_graphite2_font_get_gr_font (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_graphite2_shaper_font_data_ensure (font))) return NULL;
|
||||
return HB_SHAPER_DATA_GET (font);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_graphite2_shaper_shape_plan_data_t {};
|
||||
|
||||
hb_graphite2_shaper_shape_plan_data_t *
|
||||
_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
||||
struct hb_graphite2_cluster_t {
|
||||
unsigned int base_char;
|
||||
unsigned int num_chars;
|
||||
unsigned int base_glyph;
|
||||
unsigned int num_glyphs;
|
||||
unsigned int cluster;
|
||||
float advance;
|
||||
};
|
||||
|
||||
hb_bool_t
|
||||
_hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
const hb_feature_t *features,
|
||||
unsigned int num_features)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
|
||||
gr_font *grfont = HB_SHAPER_DATA_GET (font);
|
||||
|
||||
const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
|
||||
const char *lang_end = lang ? strchr (lang, '-') : NULL;
|
||||
int lang_len = lang_end ? lang_end - lang : -1;
|
||||
gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0);
|
||||
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
const gr_feature_ref *fref = gr_face_find_fref (grface, features[i].tag);
|
||||
if (fref)
|
||||
gr_fref_set_feature_value (fref, features[i].value, feats);
|
||||
}
|
||||
|
||||
gr_segment *seg = NULL;
|
||||
const gr_slot *is;
|
||||
unsigned int ci = 0, ic = 0;
|
||||
float curradvx = 0., curradvy = 0.;
|
||||
|
||||
unsigned int scratch_size;
|
||||
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
|
||||
uint32_t *chars = (uint32_t *) scratch;
|
||||
|
||||
for (unsigned int i = 0; i < buffer->len; ++i)
|
||||
chars[i] = buffer->info[i].codepoint;
|
||||
|
||||
/* TODO ensure_native_direction. */
|
||||
|
||||
hb_tag_t script_tag[2];
|
||||
hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
|
||||
|
||||
seg = gr_make_seg (grfont, grface,
|
||||
script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
|
||||
feats,
|
||||
gr_utf32, chars, buffer->len,
|
||||
2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
|
||||
|
||||
if (unlikely (!seg)) {
|
||||
if (feats) gr_featureval_destroy (feats);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int glyph_count = gr_seg_n_slots (seg);
|
||||
if (unlikely (!glyph_count)) {
|
||||
if (feats) gr_featureval_destroy (feats);
|
||||
gr_seg_destroy (seg);
|
||||
buffer->len = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
buffer->ensure (glyph_count);
|
||||
scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
|
||||
DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)
|
||||
{
|
||||
if (unlikely (!buffer->ensure (buffer->allocated * 2)))
|
||||
{
|
||||
if (feats) gr_featureval_destroy (feats);
|
||||
gr_seg_destroy (seg);
|
||||
return false;
|
||||
}
|
||||
scratch = buffer->get_scratch_buffer (&scratch_size);
|
||||
}
|
||||
|
||||
#define ALLOCATE_ARRAY(Type, name, len) \
|
||||
Type *name = (Type *) scratch; \
|
||||
{ \
|
||||
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
|
||||
assert (_consumed <= scratch_size); \
|
||||
scratch += _consumed; \
|
||||
scratch_size -= _consumed; \
|
||||
}
|
||||
|
||||
ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
|
||||
ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
|
||||
|
||||
#undef ALLOCATE_ARRAY
|
||||
|
||||
memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
|
||||
|
||||
hb_codepoint_t *pg = gids;
|
||||
clusters[0].cluster = buffer->info[0].cluster;
|
||||
float curradv = HB_DIRECTION_IS_BACKWARD(buffer->props.direction) ? gr_slot_origin_X(gr_seg_first_slot(seg)) : 0.;
|
||||
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
{
|
||||
curradv = gr_slot_origin_X(gr_seg_first_slot(seg));
|
||||
clusters[0].advance = gr_seg_advance_X(seg) - curradv;
|
||||
}
|
||||
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
|
||||
{
|
||||
unsigned int before = gr_slot_before (is);
|
||||
unsigned int after = gr_slot_after (is);
|
||||
*pg = gr_slot_gid (is);
|
||||
pg++;
|
||||
while (clusters[ci].base_char > before && ci)
|
||||
{
|
||||
clusters[ci-1].num_chars += clusters[ci].num_chars;
|
||||
clusters[ci-1].num_glyphs += clusters[ci].num_glyphs;
|
||||
clusters[ci-1].advance += clusters[ci].advance;
|
||||
ci--;
|
||||
}
|
||||
|
||||
if (gr_slot_can_insert_before (is) && clusters[ci].num_chars && before >= clusters[ci].base_char + clusters[ci].num_chars)
|
||||
{
|
||||
hb_graphite2_cluster_t *c = clusters + ci + 1;
|
||||
c->base_char = clusters[ci].base_char + clusters[ci].num_chars;
|
||||
c->cluster = buffer->info[c->base_char].cluster;
|
||||
c->num_chars = before - c->base_char;
|
||||
c->base_glyph = ic;
|
||||
c->num_glyphs = 0;
|
||||
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
{
|
||||
ci++;
|
||||
clusters[ci].advance = curradv - gr_slot_origin_X(is);
|
||||
} else {
|
||||
clusters[ci].advance = gr_slot_origin_X(is) - curradv;
|
||||
ci++;
|
||||
}
|
||||
curradv = gr_slot_origin_X(is);
|
||||
}
|
||||
clusters[ci].num_glyphs++;
|
||||
|
||||
if (clusters[ci].base_char + clusters[ci].num_chars < after + 1)
|
||||
clusters[ci].num_chars = after + 1 - clusters[ci].base_char;
|
||||
}
|
||||
|
||||
if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
clusters[ci].advance = gr_seg_advance_X(seg) - curradv;
|
||||
ci++;
|
||||
|
||||
for (unsigned int i = 0; i < ci; ++i)
|
||||
{
|
||||
for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j)
|
||||
{
|
||||
hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
|
||||
info->codepoint = gids[clusters[i].base_glyph + j];
|
||||
info->cluster = clusters[i].cluster;
|
||||
info->var1.i32 = clusters[i].advance; // all glyphs in the cluster get the same advance
|
||||
}
|
||||
}
|
||||
buffer->len = glyph_count;
|
||||
|
||||
float yscale = font->y_scale / font->x_scale;
|
||||
/* Positioning. */
|
||||
if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
{
|
||||
int currclus = -1;
|
||||
const hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
curradvx = 0;
|
||||
for (is = gr_seg_first_slot (seg); is; pPos++, ++info, is = gr_slot_next_in_segment (is))
|
||||
{
|
||||
pPos->x_offset = gr_slot_origin_X (is) - curradvx;
|
||||
pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy;
|
||||
if (info->cluster != currclus) {
|
||||
pPos->x_advance = info->var1.i32;
|
||||
curradvx += pPos->x_advance;
|
||||
currclus = info->cluster;
|
||||
} else
|
||||
pPos->x_advance = 0.;
|
||||
|
||||
pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale;
|
||||
curradvy += pPos->y_advance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int currclus = -1;
|
||||
const hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL);
|
||||
curradvx = gr_seg_advance_X(seg);
|
||||
for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is))
|
||||
{
|
||||
if (info->cluster != currclus)
|
||||
{
|
||||
pPos->x_advance = info->var1.i32;
|
||||
if (currclus != -1) curradvx -= info[-1].var1.i32;
|
||||
currclus = info->cluster;
|
||||
} else
|
||||
pPos->x_advance = 0.;
|
||||
|
||||
pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale;
|
||||
curradvy -= pPos->y_advance;
|
||||
pPos->x_offset = gr_slot_origin_X (is) - curradvx + pPos->x_advance;
|
||||
pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy;
|
||||
}
|
||||
hb_buffer_reverse_clusters (buffer);
|
||||
}
|
||||
|
||||
if (feats) gr_featureval_destroy (feats);
|
||||
gr_seg_destroy (seg);
|
||||
|
||||
return true;
|
||||
}
|
||||
48
gfx/harfbuzz/src/hb-graphite2.h
Normal file
48
gfx/harfbuzz/src/hb-graphite2.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Martin Hosken
|
||||
* Copyright (C) 2011 SIL International
|
||||
*
|
||||
* 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_GRAPHITE2_H
|
||||
#define HB_GRAPHITE2_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <graphite2/Font.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f')
|
||||
|
||||
|
||||
HB_EXTERN gr_face *
|
||||
hb_graphite2_face_get_gr_face (hb_face_t *face);
|
||||
|
||||
HB_EXTERN gr_font *
|
||||
hb_graphite2_font_get_gr_font (hb_font_t *font);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_GRAPHITE2_H */
|
||||
371
gfx/harfbuzz/src/hb-icu.cc
Normal file
371
gfx/harfbuzz/src/hb-icu.cc
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2009 Keith Stribley
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-icu.h"
|
||||
|
||||
#include "hb-unicode-private.hh"
|
||||
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/unorm.h>
|
||||
#include <unicode/ustring.h>
|
||||
#include <unicode/utf16.h>
|
||||
#include <unicode/uversion.h>
|
||||
|
||||
|
||||
hb_script_t
|
||||
hb_icu_script_to_script (UScriptCode script)
|
||||
{
|
||||
if (unlikely (script == USCRIPT_INVALID_CODE))
|
||||
return HB_SCRIPT_INVALID;
|
||||
|
||||
return hb_script_from_string (uscript_getShortName (script), -1);
|
||||
}
|
||||
|
||||
UScriptCode
|
||||
hb_icu_script_from_script (hb_script_t script)
|
||||
{
|
||||
if (unlikely (script == HB_SCRIPT_INVALID))
|
||||
return USCRIPT_INVALID_CODE;
|
||||
|
||||
for (unsigned int i = 0; i < USCRIPT_CODE_LIMIT; i++)
|
||||
if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script))
|
||||
return (UScriptCode) i;
|
||||
|
||||
return USCRIPT_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
static hb_unicode_combining_class_t
|
||||
hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
|
||||
{
|
||||
return (hb_unicode_combining_class_t) u_getCombiningClass (unicode);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH))
|
||||
{
|
||||
case U_EA_WIDE:
|
||||
case U_EA_FULLWIDTH:
|
||||
return 2;
|
||||
case U_EA_NEUTRAL:
|
||||
case U_EA_AMBIGUOUS:
|
||||
case U_EA_HALFWIDTH:
|
||||
case U_EA_NARROW:
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static hb_unicode_general_category_t
|
||||
hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
switch (u_getIntPropertyValue(unicode, UCHAR_GENERAL_CATEGORY))
|
||||
{
|
||||
case U_UNASSIGNED: return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
|
||||
|
||||
case U_UPPERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER;
|
||||
case U_LOWERCASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER;
|
||||
case U_TITLECASE_LETTER: return HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER;
|
||||
case U_MODIFIER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER;
|
||||
case U_OTHER_LETTER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
|
||||
|
||||
case U_NON_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK;
|
||||
case U_ENCLOSING_MARK: return HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
|
||||
case U_COMBINING_SPACING_MARK: return HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK;
|
||||
|
||||
case U_DECIMAL_DIGIT_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER;
|
||||
case U_LETTER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER;
|
||||
case U_OTHER_NUMBER: return HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER;
|
||||
|
||||
case U_SPACE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
|
||||
case U_LINE_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR;
|
||||
case U_PARAGRAPH_SEPARATOR: return HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR;
|
||||
|
||||
case U_CONTROL_CHAR: return HB_UNICODE_GENERAL_CATEGORY_CONTROL;
|
||||
case U_FORMAT_CHAR: return HB_UNICODE_GENERAL_CATEGORY_FORMAT;
|
||||
case U_PRIVATE_USE_CHAR: return HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE;
|
||||
case U_SURROGATE: return HB_UNICODE_GENERAL_CATEGORY_SURROGATE;
|
||||
|
||||
|
||||
case U_DASH_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION;
|
||||
case U_START_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION;
|
||||
case U_END_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION;
|
||||
case U_CONNECTOR_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION;
|
||||
case U_OTHER_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION;
|
||||
|
||||
case U_MATH_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL;
|
||||
case U_CURRENCY_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL;
|
||||
case U_MODIFIER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL;
|
||||
case U_OTHER_SYMBOL: return HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL;
|
||||
|
||||
case U_INITIAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION;
|
||||
case U_FINAL_PUNCTUATION: return HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION;
|
||||
}
|
||||
|
||||
return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
|
||||
}
|
||||
|
||||
static hb_codepoint_t
|
||||
hb_icu_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
return u_charMirror(unicode);
|
||||
}
|
||||
|
||||
static hb_script_t
|
||||
hb_icu_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t unicode,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UScriptCode scriptCode = uscript_getScript(unicode, &status);
|
||||
|
||||
if (unlikely (U_FAILURE (status)))
|
||||
return HB_SCRIPT_UNKNOWN;
|
||||
|
||||
return hb_icu_script_to_script (scriptCode);
|
||||
}
|
||||
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
static const UNormalizer2 *normalizer;
|
||||
#endif
|
||||
|
||||
static hb_bool_t
|
||||
hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
{
|
||||
UChar32 ret = unorm2_composePair (normalizer, a, b);
|
||||
if (ret < 0) return false;
|
||||
*ab = ret;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We don't ifdef-out the fallback code such that compiler always
|
||||
* sees it and makes sure it's compilable. */
|
||||
|
||||
UChar utf16[4], normalized[5];
|
||||
unsigned int len;
|
||||
hb_bool_t ret, err;
|
||||
UErrorCode icu_err;
|
||||
|
||||
len = 0;
|
||||
err = false;
|
||||
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err);
|
||||
if (err) return false;
|
||||
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err);
|
||||
if (err) return false;
|
||||
|
||||
icu_err = U_ZERO_ERROR;
|
||||
len = unorm_normalize (utf16, len, UNORM_NFC, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
|
||||
if (U_FAILURE (icu_err))
|
||||
return false;
|
||||
if (u_countChar32 (normalized, len) == 1) {
|
||||
U16_GET_UNSAFE (normalized, 0, *ab);
|
||||
ret = true;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t ab,
|
||||
hb_codepoint_t *a,
|
||||
hb_codepoint_t *b,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
{
|
||||
UChar decomposed[4];
|
||||
int len;
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
len = unorm2_getRawDecomposition (normalizer, ab, decomposed,
|
||||
ARRAY_LENGTH (decomposed), &icu_err);
|
||||
if (U_FAILURE (icu_err) || len < 0) return false;
|
||||
|
||||
len = u_countChar32 (decomposed, len);
|
||||
if (len == 1) {
|
||||
U16_GET_UNSAFE (decomposed, 0, *a);
|
||||
*b = 0;
|
||||
return *a != ab;
|
||||
} else if (len == 2) {
|
||||
len =0;
|
||||
U16_NEXT_UNSAFE (decomposed, len, *a);
|
||||
U16_NEXT_UNSAFE (decomposed, len, *b);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We don't ifdef-out the fallback code such that compiler always
|
||||
* sees it and makes sure it's compilable. */
|
||||
|
||||
UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
|
||||
unsigned int len;
|
||||
hb_bool_t ret, err;
|
||||
UErrorCode icu_err;
|
||||
|
||||
/* This function is a monster! Maybe it wasn't a good idea adding a
|
||||
* pairwise decompose API... */
|
||||
/* Watchout for the dragons. Err, watchout for macros changing len. */
|
||||
|
||||
len = 0;
|
||||
err = false;
|
||||
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err);
|
||||
if (err) return false;
|
||||
|
||||
icu_err = U_ZERO_ERROR;
|
||||
len = unorm_normalize (utf16, len, UNORM_NFD, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
|
||||
if (U_FAILURE (icu_err))
|
||||
return false;
|
||||
|
||||
len = u_countChar32 (normalized, len);
|
||||
|
||||
if (len == 1) {
|
||||
U16_GET_UNSAFE (normalized, 0, *a);
|
||||
*b = 0;
|
||||
ret = *a != ab;
|
||||
} else if (len == 2) {
|
||||
len =0;
|
||||
U16_NEXT_UNSAFE (normalized, len, *a);
|
||||
U16_NEXT_UNSAFE (normalized, len, *b);
|
||||
|
||||
/* Here's the ugly part: if ab decomposes to a single character and
|
||||
* that character decomposes again, we have to detect that and undo
|
||||
* the second part :-(. */
|
||||
UChar recomposed[20];
|
||||
icu_err = U_ZERO_ERROR;
|
||||
unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
|
||||
if (U_FAILURE (icu_err))
|
||||
return false;
|
||||
hb_codepoint_t c;
|
||||
U16_GET_UNSAFE (recomposed, 0, c);
|
||||
if (c != *a && c != ab) {
|
||||
*a = c;
|
||||
*b = 0;
|
||||
}
|
||||
ret = true;
|
||||
} else {
|
||||
/* If decomposed to more than two characters, take the last one,
|
||||
* and recompose the rest to get the first component. */
|
||||
U16_PREV_UNSAFE (normalized, len, *b); /* Changes len in-place. */
|
||||
UChar recomposed[18 * 2];
|
||||
icu_err = U_ZERO_ERROR;
|
||||
len = unorm_normalize (normalized, len, UNORM_NFC, 0, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
|
||||
if (U_FAILURE (icu_err))
|
||||
return false;
|
||||
/* We expect that recomposed has exactly one character now. */
|
||||
if (unlikely (u_countChar32 (recomposed, len) != 1))
|
||||
return false;
|
||||
U16_GET_UNSAFE (recomposed, 0, *a);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
hb_codepoint_t u,
|
||||
hb_codepoint_t *decomposed,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
|
||||
unsigned int len;
|
||||
int32_t utf32_len;
|
||||
hb_bool_t err;
|
||||
UErrorCode icu_err;
|
||||
|
||||
/* Copy @u into a UTF-16 array to be passed to ICU. */
|
||||
len = 0;
|
||||
err = false;
|
||||
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
/* Normalise the codepoint using NFKD mode. */
|
||||
icu_err = U_ZERO_ERROR;
|
||||
len = unorm_normalize (utf16, len, UNORM_NFKD, 0, normalized, ARRAY_LENGTH (normalized), &icu_err);
|
||||
if (icu_err)
|
||||
return 0;
|
||||
|
||||
/* Convert the decomposed form from UTF-16 to UTF-32. */
|
||||
icu_err = U_ZERO_ERROR;
|
||||
u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err);
|
||||
if (icu_err)
|
||||
return 0;
|
||||
|
||||
return utf32_len;
|
||||
}
|
||||
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_icu_get_unicode_funcs (void)
|
||||
{
|
||||
static const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
NULL, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
}
|
||||
};
|
||||
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
if (!hb_atomic_ptr_get (&normalizer)) {
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
/* We ignore failure in getNFCInstace(). */
|
||||
(void) hb_atomic_ptr_cmpexch (&normalizer, NULL, unorm2_getNFCInstance (&icu_err));
|
||||
}
|
||||
#endif
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
|
||||
}
|
||||
52
gfx/harfbuzz/src/hb-icu.h
Normal file
52
gfx/harfbuzz/src/hb-icu.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_ICU_H
|
||||
#define HB_ICU_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <unicode/uscript.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_icu_script_to_script (UScriptCode script);
|
||||
|
||||
HB_EXTERN UScriptCode
|
||||
hb_icu_script_from_script (hb_script_t script);
|
||||
|
||||
|
||||
HB_EXTERN hb_unicode_funcs_t *
|
||||
hb_icu_get_unicode_funcs (void);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_ICU_H */
|
||||
141
gfx/harfbuzz/src/hb-mutex-private.hh
Normal file
141
gfx/harfbuzz/src/hb-mutex-private.hh
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_MUTEX_PRIVATE_HH
|
||||
#define HB_MUTEX_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
/* mutex */
|
||||
|
||||
/* We need external help for these */
|
||||
|
||||
#if defined(HB_MUTEX_IMPL_INIT) \
|
||||
&& defined(hb_mutex_impl_init) \
|
||||
&& defined(hb_mutex_impl_lock) \
|
||||
&& defined(hb_mutex_impl_unlock) \
|
||||
&& defined(hb_mutex_impl_finish)
|
||||
|
||||
/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#include <windows.h>
|
||||
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT {0}
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||
#define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0)
|
||||
#else
|
||||
#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
|
||||
#endif
|
||||
#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
|
||||
#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
|
||||
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
|
||||
|
||||
#include <pthread.h>
|
||||
typedef pthread_mutex_t hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#define hb_mutex_impl_init(M) pthread_mutex_init (M, NULL)
|
||||
#define hb_mutex_impl_lock(M) pthread_mutex_lock (M)
|
||||
#define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M)
|
||||
#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
|
||||
# include <sched.h>
|
||||
# define HB_SCHED_YIELD() sched_yield ()
|
||||
#else
|
||||
# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
|
||||
#endif
|
||||
|
||||
/* This actually is not a totally awful implementation. */
|
||||
typedef volatile int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) *(M) = 0
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
|
||||
# include <sched.h>
|
||||
# define HB_SCHED_YIELD() sched_yield ()
|
||||
#else
|
||||
# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
|
||||
#endif
|
||||
|
||||
#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
typedef volatile int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) *(M) = 0
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) (*(M))--;
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#else /* HB_NO_MT */
|
||||
|
||||
typedef int hb_mutex_impl_t;
|
||||
#define HB_MUTEX_IMPL_INIT 0
|
||||
#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END
|
||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
|
||||
|
||||
struct hb_mutex_t
|
||||
{
|
||||
/* TODO Add tracing. */
|
||||
|
||||
hb_mutex_impl_t m;
|
||||
|
||||
inline void init (void) { hb_mutex_impl_init (&m); }
|
||||
inline void lock (void) { hb_mutex_impl_lock (&m); }
|
||||
inline void unlock (void) { hb_mutex_impl_unlock (&m); }
|
||||
inline void finish (void) { hb_mutex_impl_finish (&m); }
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_MUTEX_PRIVATE_HH */
|
||||
202
gfx/harfbuzz/src/hb-object-private.hh
Normal file
202
gfx/harfbuzz/src/hb-object-private.hh
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2011,2012 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.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OBJECT_PRIVATE_HH
|
||||
#define HB_OBJECT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-atomic-private.hh"
|
||||
#include "hb-mutex-private.hh"
|
||||
|
||||
|
||||
/* Debug */
|
||||
|
||||
#ifndef HB_DEBUG_OBJECT
|
||||
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* reference_count */
|
||||
|
||||
#define HB_REFERENCE_COUNT_INERT_VALUE -1
|
||||
#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
|
||||
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
|
||||
|
||||
struct hb_reference_count_t
|
||||
{
|
||||
hb_atomic_int_t ref_count;
|
||||
|
||||
inline void init (int v) { ref_count.set_unsafe (v); }
|
||||
inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
|
||||
inline int inc (void) { return ref_count.inc (); }
|
||||
inline int dec (void) { return ref_count.dec (); }
|
||||
inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
|
||||
|
||||
inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
|
||||
inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
|
||||
};
|
||||
|
||||
|
||||
/* user_data */
|
||||
|
||||
#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
|
||||
struct hb_user_data_array_t
|
||||
{
|
||||
struct hb_user_data_item_t {
|
||||
hb_user_data_key_t *key;
|
||||
void *data;
|
||||
hb_destroy_func_t destroy;
|
||||
|
||||
inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
|
||||
inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
|
||||
|
||||
void finish (void) { if (destroy) destroy (data); }
|
||||
};
|
||||
|
||||
hb_mutex_t lock;
|
||||
hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
|
||||
|
||||
inline void init (void) { lock.init (); items.init (); }
|
||||
|
||||
HB_INTERNAL bool set (hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
HB_INTERNAL void *get (hb_user_data_key_t *key);
|
||||
|
||||
inline void finish (void) { items.finish (lock); lock.finish (); }
|
||||
};
|
||||
|
||||
|
||||
/* object_header */
|
||||
|
||||
struct hb_object_header_t
|
||||
{
|
||||
hb_reference_count_t ref_count;
|
||||
hb_user_data_array_t user_data;
|
||||
|
||||
#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
|
||||
|
||||
private:
|
||||
ASSERT_POD ();
|
||||
};
|
||||
|
||||
|
||||
/* object */
|
||||
|
||||
template <typename Type>
|
||||
static inline void hb_object_trace (const Type *obj, const char *function)
|
||||
{
|
||||
DEBUG_MSG (OBJECT, (void *) obj,
|
||||
"%s refcount=%d",
|
||||
function,
|
||||
obj ? obj->header.ref_count.get_unsafe () : 0);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static inline Type *hb_object_create (void)
|
||||
{
|
||||
Type *obj = (Type *) calloc (1, sizeof (Type));
|
||||
|
||||
if (unlikely (!obj))
|
||||
return obj;
|
||||
|
||||
hb_object_init (obj);
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
return obj;
|
||||
}
|
||||
template <typename Type>
|
||||
static inline void hb_object_init (Type *obj)
|
||||
{
|
||||
obj->header.ref_count.init (1);
|
||||
obj->header.user_data.init ();
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_is_inert (const Type *obj)
|
||||
{
|
||||
return unlikely (obj->header.ref_count.is_inert ());
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_is_valid (const Type *obj)
|
||||
{
|
||||
return likely (obj->header.ref_count.is_valid ());
|
||||
}
|
||||
template <typename Type>
|
||||
static inline Type *hb_object_reference (Type *obj)
|
||||
{
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
if (unlikely (!obj || hb_object_is_inert (obj)))
|
||||
return obj;
|
||||
assert (hb_object_is_valid (obj));
|
||||
obj->header.ref_count.inc ();
|
||||
return obj;
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_destroy (Type *obj)
|
||||
{
|
||||
hb_object_trace (obj, HB_FUNC);
|
||||
if (unlikely (!obj || hb_object_is_inert (obj)))
|
||||
return false;
|
||||
assert (hb_object_is_valid (obj));
|
||||
if (obj->header.ref_count.dec () != 1)
|
||||
return false;
|
||||
|
||||
obj->header.ref_count.finish (); /* Do this before user_data */
|
||||
obj->header.user_data.finish ();
|
||||
return true;
|
||||
}
|
||||
template <typename Type>
|
||||
static inline bool hb_object_set_user_data (Type *obj,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
if (unlikely (!obj || hb_object_is_inert (obj)))
|
||||
return false;
|
||||
assert (hb_object_is_valid (obj));
|
||||
return obj->header.user_data.set (key, data, destroy, replace);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static inline void *hb_object_get_user_data (Type *obj,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
if (unlikely (!obj || hb_object_is_inert (obj)))
|
||||
return NULL;
|
||||
assert (hb_object_is_valid (obj));
|
||||
return obj->header.user_data.get (key);
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_OBJECT_PRIVATE_HH */
|
||||
268
gfx/harfbuzz/src/hb-open-file-private.hh
Normal file
268
gfx/harfbuzz/src/hb-open-file-private.hh
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OPEN_FILE_PRIVATE_HH
|
||||
#define HB_OPEN_FILE_PRIVATE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* The OpenType Font File
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Organization of an OpenType Font
|
||||
*/
|
||||
|
||||
struct OpenTypeFontFile;
|
||||
struct OffsetTable;
|
||||
struct TTCHeader;
|
||||
|
||||
|
||||
typedef struct TableRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
Tag tag; /* 4-byte identifier. */
|
||||
CheckSum checkSum; /* CheckSum for this table. */
|
||||
ULONG offset; /* Offset from beginning of TrueType font
|
||||
* file. */
|
||||
ULONG length; /* Length of this table. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
} OpenTypeTable;
|
||||
|
||||
typedef struct OffsetTable
|
||||
{
|
||||
friend struct OpenTypeFontFile;
|
||||
|
||||
inline unsigned int get_table_count (void) const
|
||||
{ return numTables; }
|
||||
inline const TableRecord& get_table (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= numTables)) return Null(TableRecord);
|
||||
return tables[i];
|
||||
}
|
||||
inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
|
||||
{
|
||||
Tag t;
|
||||
t.set (tag);
|
||||
unsigned int count = numTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (t == tables[i].tag)
|
||||
{
|
||||
if (table_index) *table_index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (table_index) *table_index = Index::NOT_FOUND_INDEX;
|
||||
return false;
|
||||
}
|
||||
inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
|
||||
{
|
||||
unsigned int table_index;
|
||||
find_table_index (tag, &table_index);
|
||||
return get_table (table_index);
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
|
||||
USHORT numTables; /* Number of tables. */
|
||||
USHORT searchRangeZ; /* (Maximum power of 2 <= numTables) x 16 */
|
||||
USHORT entrySelectorZ; /* Log2(maximum power of 2 <= numTables). */
|
||||
USHORT rangeShiftZ; /* NumTables x 16-searchRange. */
|
||||
TableRecord tables[VAR]; /* TableRecord entries. numTables items */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, tables);
|
||||
} OpenTypeFontFace;
|
||||
|
||||
|
||||
/*
|
||||
* TrueType Collections
|
||||
*/
|
||||
|
||||
struct TTCHeaderVersion1
|
||||
{
|
||||
friend struct TTCHeader;
|
||||
|
||||
inline unsigned int get_face_count (void) const { return table.len; }
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (table.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||
FixedVersion<>version; /* Version of the TTC Header (1.0),
|
||||
* 0x00010000u */
|
||||
ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG>
|
||||
table; /* Array of offsets to the OffsetTable for each font
|
||||
* from the beginning of the file */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, table);
|
||||
};
|
||||
|
||||
struct TTCHeader
|
||||
{
|
||||
friend struct OpenTypeFontFile;
|
||||
|
||||
private:
|
||||
|
||||
inline unsigned int get_face_count (void) const
|
||||
{
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return u.version1.get_face_count ();
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const
|
||||
{
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return u.version1.get_face (i);
|
||||
default:return Null(OpenTypeFontFace);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
|
||||
switch (u.header.version.major) {
|
||||
case 2: /* version 2 is compatible with version 1 */
|
||||
case 1: return_trace (u.version1.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
struct {
|
||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||
FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0),
|
||||
* 0x00010000u or 0x00020000u */
|
||||
} header;
|
||||
TTCHeaderVersion1 version1;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* OpenType Font File
|
||||
*/
|
||||
|
||||
struct OpenTypeFontFile
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
|
||||
|
||||
static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
|
||||
static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
|
||||
static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */
|
||||
static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
|
||||
static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
|
||||
|
||||
inline hb_tag_t get_tag (void) const { return u.tag; }
|
||||
|
||||
inline unsigned int get_face_count (void) const
|
||||
{
|
||||
switch (u.tag) {
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return 1;
|
||||
case TTCTag: return u.ttcHeader.get_face_count ();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const
|
||||
{
|
||||
switch (u.tag) {
|
||||
/* Note: for non-collection SFNT data we ignore index. This is because
|
||||
* Apple dfont container is a container of SFNT's. So each SFNT is a
|
||||
* non-TTC, but the index is more than zero. */
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return u.fontFace;
|
||||
case TTCTag: return u.ttcHeader.get_face (i);
|
||||
default: return Null(OpenTypeFontFace);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!u.tag.sanitize (c))) return_trace (false);
|
||||
switch (u.tag) {
|
||||
case CFFTag: /* All the non-collection tags */
|
||||
case TrueTag:
|
||||
case Typ1Tag:
|
||||
case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
|
||||
case TTCTag: return_trace (u.ttcHeader.sanitize (c));
|
||||
default: return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
Tag tag; /* 4-byte identifier. */
|
||||
OpenTypeFontFace fontFace;
|
||||
TTCHeader ttcHeader;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (4, tag);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OPEN_FILE_PRIVATE_HH */
|
||||
1067
gfx/harfbuzz/src/hb-open-type-private.hh
Normal file
1067
gfx/harfbuzz/src/hb-open-type-private.hh
Normal file
File diff suppressed because it is too large
Load diff
384
gfx/harfbuzz/src/hb-ot-cbdt-table.hh
Normal file
384
gfx/harfbuzz/src/hb-ot-cbdt-table.hh
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Copyright © 2016 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): Seigo Nonaka
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_CBDT_TABLE_HH
|
||||
#define HB_OT_CBDT_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
namespace OT {
|
||||
|
||||
struct SmallGlyphMetrics
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
inline void get_extents (hb_glyph_extents_t *extents) const
|
||||
{
|
||||
extents->x_bearing = bearingX;
|
||||
extents->y_bearing = bearingY;
|
||||
extents->width = width;
|
||||
extents->height = -height;
|
||||
}
|
||||
|
||||
BYTE height;
|
||||
BYTE width;
|
||||
CHAR bearingX;
|
||||
CHAR bearingY;
|
||||
BYTE advance;
|
||||
|
||||
DEFINE_SIZE_STATIC(5);
|
||||
};
|
||||
|
||||
struct BigGlyphMetrics : SmallGlyphMetrics
|
||||
{
|
||||
CHAR vertBearingX;
|
||||
CHAR vertBearingY;
|
||||
BYTE vertAdvance;
|
||||
|
||||
DEFINE_SIZE_STATIC(8);
|
||||
};
|
||||
|
||||
struct SBitLineMetrics
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
CHAR ascender;
|
||||
CHAR decender;
|
||||
BYTE widthMax;
|
||||
CHAR caretSlopeNumerator;
|
||||
CHAR caretSlopeDenominator;
|
||||
CHAR caretOffset;
|
||||
CHAR minOriginSB;
|
||||
CHAR minAdvanceSB;
|
||||
CHAR maxBeforeBL;
|
||||
CHAR minAfterBL;
|
||||
CHAR padding1;
|
||||
CHAR padding2;
|
||||
|
||||
DEFINE_SIZE_STATIC(12);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Index Subtables.
|
||||
*/
|
||||
|
||||
struct IndexSubtableHeader
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
USHORT indexFormat;
|
||||
USHORT imageFormat;
|
||||
ULONG imageDataOffset;
|
||||
|
||||
DEFINE_SIZE_STATIC(8);
|
||||
};
|
||||
|
||||
template <typename OffsetType>
|
||||
struct IndexSubtableFormat1Or3
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
|
||||
}
|
||||
|
||||
bool get_image_data (unsigned int idx,
|
||||
unsigned int *offset,
|
||||
unsigned int *length) const
|
||||
{
|
||||
if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
|
||||
return false;
|
||||
|
||||
*offset = header.imageDataOffset + offsetArrayZ[idx];
|
||||
*length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
|
||||
return true;
|
||||
}
|
||||
|
||||
IndexSubtableHeader header;
|
||||
Offset<OffsetType> offsetArrayZ[VAR];
|
||||
|
||||
DEFINE_SIZE_ARRAY(8, offsetArrayZ);
|
||||
};
|
||||
|
||||
struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<ULONG> {};
|
||||
struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<USHORT> {};
|
||||
|
||||
struct IndexSubtable
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.header.sanitize (c)) return_trace (false);
|
||||
switch (u.header.indexFormat) {
|
||||
case 1: return_trace (u.format1.sanitize (c, glyph_count));
|
||||
case 3: return_trace (u.format3.sanitize (c, glyph_count));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool get_extents (hb_glyph_extents_t *extents) const
|
||||
{
|
||||
switch (u.header.indexFormat) {
|
||||
case 2: case 5: /* TODO */
|
||||
case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
|
||||
default:return (false);
|
||||
}
|
||||
}
|
||||
|
||||
bool get_image_data (unsigned int idx,
|
||||
unsigned int *offset,
|
||||
unsigned int *length,
|
||||
unsigned int *format) const
|
||||
{
|
||||
*format = u.header.imageFormat;
|
||||
switch (u.header.indexFormat) {
|
||||
case 1: return u.format1.get_image_data (idx, offset, length);
|
||||
case 3: return u.format3.get_image_data (idx, offset, length);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
IndexSubtableHeader header;
|
||||
IndexSubtableFormat1 format1;
|
||||
IndexSubtableFormat3 format3;
|
||||
/* TODO: Format 2, 4, 5. */
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (8, header);
|
||||
};
|
||||
|
||||
struct IndexSubtableRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
firstGlyphIndex <= lastGlyphIndex &&
|
||||
offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
|
||||
}
|
||||
|
||||
inline bool get_extents (hb_glyph_extents_t *extents) const
|
||||
{
|
||||
return (this+offsetToSubtable).get_extents (extents);
|
||||
}
|
||||
|
||||
bool get_image_data (unsigned int gid,
|
||||
unsigned int *offset,
|
||||
unsigned int *length,
|
||||
unsigned int *format) const
|
||||
{
|
||||
if (gid < firstGlyphIndex || gid > lastGlyphIndex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
|
||||
offset, length, format);
|
||||
}
|
||||
|
||||
USHORT firstGlyphIndex;
|
||||
USHORT lastGlyphIndex;
|
||||
OffsetTo<IndexSubtable, ULONG> offsetToSubtable;
|
||||
|
||||
DEFINE_SIZE_STATIC(8);
|
||||
};
|
||||
|
||||
struct IndexSubtableArray
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
|
||||
return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
|
||||
return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
public:
|
||||
const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
|
||||
{
|
||||
for (unsigned int i = 0; i < numTables; ++i)
|
||||
{
|
||||
unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
|
||||
unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
|
||||
if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
|
||||
return &indexSubtablesZ[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexSubtableRecord indexSubtablesZ[VAR];
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
|
||||
};
|
||||
|
||||
struct BitmapSizeTable
|
||||
{
|
||||
friend struct CBLC;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
|
||||
c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
|
||||
horizontal.sanitize (c) &&
|
||||
vertical.sanitize (c));
|
||||
}
|
||||
|
||||
const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
|
||||
{
|
||||
return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<IndexSubtableArray, ULONG> indexSubtableArrayOffset;
|
||||
ULONG indexTablesSize;
|
||||
ULONG numberOfIndexSubtables;
|
||||
ULONG colorRef;
|
||||
SBitLineMetrics horizontal;
|
||||
SBitLineMetrics vertical;
|
||||
USHORT startGlyphIndex;
|
||||
USHORT endGlyphIndex;
|
||||
BYTE ppemX;
|
||||
BYTE ppemY;
|
||||
BYTE bitDepth;
|
||||
CHAR flags;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC(48);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Glyph Bitmap Data Formats.
|
||||
*/
|
||||
|
||||
struct GlyphBitmapDataFormat17
|
||||
{
|
||||
SmallGlyphMetrics glyphMetrics;
|
||||
ULONG dataLen;
|
||||
BYTE dataZ[VAR];
|
||||
|
||||
DEFINE_SIZE_ARRAY(9, dataZ);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CBLC -- Color Bitmap Location Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
|
||||
|
||||
struct CBLC
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (version.major == 2 || version.major == 3) &&
|
||||
sizeTables.sanitize (c, this));
|
||||
}
|
||||
|
||||
public:
|
||||
const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
|
||||
unsigned int *x_ppem, unsigned int *y_ppem) const
|
||||
{
|
||||
/* TODO: Make it possible to select strike. */
|
||||
|
||||
unsigned int count = sizeTables.len;
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
|
||||
unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
|
||||
if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
|
||||
{
|
||||
*x_ppem = sizeTables[i].ppemX;
|
||||
*y_ppem = sizeTables[i].ppemY;
|
||||
return sizeTables[i].find_table (glyph, this);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version;
|
||||
ArrayOf<BitmapSizeTable, ULONG> sizeTables;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(8, sizeTables);
|
||||
};
|
||||
|
||||
/*
|
||||
* CBDT -- Color Bitmap Data Table
|
||||
*/
|
||||
#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
|
||||
|
||||
struct CBDT
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (version.major == 2 || version.major == 3));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version;
|
||||
BYTE dataZ[VAR];
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(4, dataZ);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
#endif /* HB_OT_CBDT_TABLE_HH */
|
||||
535
gfx/harfbuzz/src/hb-ot-cmap-table.hh
Normal file
535
gfx/harfbuzz/src/hb-ot-cmap-table.hh
Normal file
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
* Copyright © 2014 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_CMAP_TABLE_HH
|
||||
#define HB_OT_CMAP_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* cmap -- Character To Glyph Index Mapping Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
|
||||
|
||||
|
||||
struct CmapSubtableFormat0
|
||||
{
|
||||
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||
{
|
||||
hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
|
||||
if (!gid)
|
||||
return false;
|
||||
*glyph = gid;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format number is set to 0. */
|
||||
USHORT lengthZ; /* Byte length of this subtable. */
|
||||
USHORT languageZ; /* Ignore. */
|
||||
BYTE glyphIdArray[256];/* An array that maps character
|
||||
* code to glyph index values. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6 + 256);
|
||||
};
|
||||
|
||||
struct CmapSubtableFormat4
|
||||
{
|
||||
struct accelerator_t
|
||||
{
|
||||
inline void init (const CmapSubtableFormat4 *subtable)
|
||||
{
|
||||
segCount = subtable->segCountX2 / 2;
|
||||
endCount = subtable->values;
|
||||
startCount = endCount + segCount + 1;
|
||||
idDelta = startCount + segCount;
|
||||
idRangeOffset = idDelta + segCount;
|
||||
glyphIdArray = idRangeOffset + segCount;
|
||||
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
|
||||
}
|
||||
|
||||
static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
|
||||
{
|
||||
const accelerator_t *thiz = (const accelerator_t *) obj;
|
||||
|
||||
/* Custom two-array bsearch. */
|
||||
int min = 0, max = (int) thiz->segCount - 1;
|
||||
const USHORT *startCount = thiz->startCount;
|
||||
const USHORT *endCount = thiz->endCount;
|
||||
unsigned int i;
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
if (codepoint < startCount[mid])
|
||||
max = mid - 1;
|
||||
else if (codepoint > endCount[mid])
|
||||
min = mid + 1;
|
||||
else
|
||||
{
|
||||
i = mid;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
found:
|
||||
hb_codepoint_t gid;
|
||||
unsigned int rangeOffset = thiz->idRangeOffset[i];
|
||||
if (rangeOffset == 0)
|
||||
gid = codepoint + thiz->idDelta[i];
|
||||
else
|
||||
{
|
||||
/* Somebody has been smoking... */
|
||||
unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount;
|
||||
if (unlikely (index >= thiz->glyphIdArrayLength))
|
||||
return false;
|
||||
gid = thiz->glyphIdArray[index];
|
||||
if (unlikely (!gid))
|
||||
return false;
|
||||
gid += thiz->idDelta[i];
|
||||
}
|
||||
|
||||
*glyph = gid & 0xFFFFu;
|
||||
return true;
|
||||
}
|
||||
|
||||
const USHORT *endCount;
|
||||
const USHORT *startCount;
|
||||
const USHORT *idDelta;
|
||||
const USHORT *idRangeOffset;
|
||||
const USHORT *glyphIdArray;
|
||||
unsigned int segCount;
|
||||
unsigned int glyphIdArrayLength;
|
||||
};
|
||||
|
||||
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||
{
|
||||
accelerator_t accel;
|
||||
accel.init (this);
|
||||
return accel.get_glyph_func (&accel, codepoint, glyph);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (this)))
|
||||
return_trace (false);
|
||||
|
||||
if (unlikely (!c->check_range (this, length)))
|
||||
{
|
||||
/* Some broken fonts have too long of a "length" value.
|
||||
* If that is the case, just change the value to truncate
|
||||
* the subtable at the end of the blob. */
|
||||
uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
|
||||
(uintptr_t) (c->end -
|
||||
(char *) this));
|
||||
if (!c->try_set (&length, new_length))
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format number is set to 4. */
|
||||
USHORT length; /* This is the length in bytes of the
|
||||
* subtable. */
|
||||
USHORT languageZ; /* Ignore. */
|
||||
USHORT segCountX2; /* 2 x segCount. */
|
||||
USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
|
||||
USHORT entrySelectorZ; /* log2(searchRange/2) */
|
||||
USHORT rangeShiftZ; /* 2 x segCount - searchRange */
|
||||
|
||||
USHORT values[VAR];
|
||||
#if 0
|
||||
USHORT endCount[segCount]; /* End characterCode for each segment,
|
||||
* last=0xFFFFu. */
|
||||
USHORT reservedPad; /* Set to 0. */
|
||||
USHORT startCount[segCount]; /* Start character code for each segment. */
|
||||
SHORT idDelta[segCount]; /* Delta for all character codes in segment. */
|
||||
USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
|
||||
USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
|
||||
#endif
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (14, values);
|
||||
};
|
||||
|
||||
struct CmapSubtableLongGroup
|
||||
{
|
||||
friend struct CmapSubtableFormat12;
|
||||
friend struct CmapSubtableFormat13;
|
||||
|
||||
int cmp (hb_codepoint_t codepoint) const
|
||||
{
|
||||
if (codepoint < startCharCode) return -1;
|
||||
if (codepoint > endCharCode) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
private:
|
||||
ULONG startCharCode; /* First character code in this group. */
|
||||
ULONG endCharCode; /* Last character code in this group. */
|
||||
ULONG glyphID; /* Glyph index; interpretation depends on
|
||||
* subtable format. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
template <typename UINT>
|
||||
struct CmapSubtableTrimmed
|
||||
{
|
||||
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||
{
|
||||
/* Rely on our implicit array bound-checking. */
|
||||
hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
|
||||
if (!gid)
|
||||
return false;
|
||||
*glyph = gid;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && glyphIdArray.sanitize (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
UINT formatReserved; /* Subtable format and (maybe) padding. */
|
||||
UINT lengthZ; /* Byte length of this subtable. */
|
||||
UINT languageZ; /* Ignore. */
|
||||
UINT startCharCode; /* First character code covered. */
|
||||
ArrayOf<GlyphID, UINT>
|
||||
glyphIdArray; /* Array of glyph index values for character
|
||||
* codes in the range. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
|
||||
};
|
||||
|
||||
struct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {};
|
||||
struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
|
||||
|
||||
template <typename T>
|
||||
struct CmapSubtableLongSegmented
|
||||
{
|
||||
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||
{
|
||||
int i = groups.bsearch (codepoint);
|
||||
if (i == -1)
|
||||
return false;
|
||||
*glyph = T::group_get_glyph (groups[i], codepoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && groups.sanitize (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Subtable format; set to 12. */
|
||||
USHORT reservedZ; /* Reserved; set to 0. */
|
||||
ULONG lengthZ; /* Byte length of this subtable. */
|
||||
ULONG languageZ; /* Ignore. */
|
||||
SortedArrayOf<CmapSubtableLongGroup, ULONG>
|
||||
groups; /* Groupings. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (16, groups);
|
||||
};
|
||||
|
||||
struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||
{
|
||||
static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
|
||||
hb_codepoint_t u)
|
||||
{ return group.glyphID + (u - group.startCharCode); }
|
||||
};
|
||||
|
||||
struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
|
||||
{
|
||||
static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
|
||||
hb_codepoint_t u HB_UNUSED)
|
||||
{ return group.glyphID; }
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GLYPH_VARIANT_NOT_FOUND = 0,
|
||||
GLYPH_VARIANT_FOUND = 1,
|
||||
GLYPH_VARIANT_USE_DEFAULT = 2
|
||||
} glyph_variant_t;
|
||||
|
||||
struct UnicodeValueRange
|
||||
{
|
||||
inline int cmp (const hb_codepoint_t &codepoint) const
|
||||
{
|
||||
if (codepoint < startUnicodeValue) return -1;
|
||||
if (codepoint > startUnicodeValue + additionalCount) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
UINT24 startUnicodeValue; /* First value in this range. */
|
||||
BYTE additionalCount; /* Number of additional values in this
|
||||
* range. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
|
||||
|
||||
struct UVSMapping
|
||||
{
|
||||
inline int cmp (const hb_codepoint_t &codepoint) const
|
||||
{
|
||||
return unicodeValue.cmp (codepoint);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
UINT24 unicodeValue; /* Base Unicode value of the UVS */
|
||||
GlyphID glyphID; /* Glyph ID of the UVS */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (5);
|
||||
};
|
||||
|
||||
typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
|
||||
|
||||
struct VariationSelectorRecord
|
||||
{
|
||||
inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph,
|
||||
const void *base) const
|
||||
{
|
||||
int i;
|
||||
const DefaultUVS &defaults = base+defaultUVS;
|
||||
i = defaults.bsearch (codepoint);
|
||||
if (i != -1)
|
||||
return GLYPH_VARIANT_USE_DEFAULT;
|
||||
const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
|
||||
i = nonDefaults.bsearch (codepoint);
|
||||
if (i != -1)
|
||||
{
|
||||
*glyph = nonDefaults[i].glyphID;
|
||||
return GLYPH_VARIANT_FOUND;
|
||||
}
|
||||
return GLYPH_VARIANT_NOT_FOUND;
|
||||
}
|
||||
|
||||
inline int cmp (const hb_codepoint_t &variation_selector) const
|
||||
{
|
||||
return varSelector.cmp (variation_selector);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
defaultUVS.sanitize (c, base) &&
|
||||
nonDefaultUVS.sanitize (c, base));
|
||||
}
|
||||
|
||||
UINT24 varSelector; /* Variation selector. */
|
||||
OffsetTo<DefaultUVS, ULONG>
|
||||
defaultUVS; /* Offset to Default UVS Table. May be 0. */
|
||||
OffsetTo<NonDefaultUVS, ULONG>
|
||||
nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (11);
|
||||
};
|
||||
|
||||
struct CmapSubtableFormat14
|
||||
{
|
||||
inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
|
||||
hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
record.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format number is set to 14. */
|
||||
ULONG lengthZ; /* Byte length of this subtable. */
|
||||
SortedArrayOf<VariationSelectorRecord, ULONG>
|
||||
record; /* Variation selector records; sorted
|
||||
* in increasing order of `varSelector'. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (10, record);
|
||||
};
|
||||
|
||||
struct CmapSubtable
|
||||
{
|
||||
/* Note: We intentionally do NOT implement subtable formats 2 and 8. */
|
||||
|
||||
inline bool get_glyph (hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 0: return u.format0 .get_glyph(codepoint, glyph);
|
||||
case 4: return u.format4 .get_glyph(codepoint, glyph);
|
||||
case 6: return u.format6 .get_glyph(codepoint, glyph);
|
||||
case 10: return u.format10.get_glyph(codepoint, glyph);
|
||||
case 12: return u.format12.get_glyph(codepoint, glyph);
|
||||
case 13: return u.format13.get_glyph(codepoint, glyph);
|
||||
case 14:
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 0: return_trace (u.format0 .sanitize (c));
|
||||
case 4: return_trace (u.format4 .sanitize (c));
|
||||
case 6: return_trace (u.format6 .sanitize (c));
|
||||
case 10: return_trace (u.format10.sanitize (c));
|
||||
case 12: return_trace (u.format12.sanitize (c));
|
||||
case 13: return_trace (u.format13.sanitize (c));
|
||||
case 14: return_trace (u.format14.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
CmapSubtableFormat0 format0;
|
||||
CmapSubtableFormat4 format4;
|
||||
CmapSubtableFormat6 format6;
|
||||
CmapSubtableFormat10 format10;
|
||||
CmapSubtableFormat12 format12;
|
||||
CmapSubtableFormat13 format13;
|
||||
CmapSubtableFormat14 format14;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
|
||||
struct EncodingRecord
|
||||
{
|
||||
inline int cmp (const EncodingRecord &other) const
|
||||
{
|
||||
int ret;
|
||||
ret = platformID.cmp (other.platformID);
|
||||
if (ret) return ret;
|
||||
ret = encodingID.cmp (other.encodingID);
|
||||
if (ret) return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
subtable.sanitize (c, base));
|
||||
}
|
||||
|
||||
USHORT platformID; /* Platform ID. */
|
||||
USHORT encodingID; /* Platform-specific encoding ID. */
|
||||
OffsetTo<CmapSubtable, ULONG>
|
||||
subtable; /* Byte offset from beginning of table to the subtable for this encoding. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct cmap
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_cmap;
|
||||
|
||||
inline const CmapSubtable *find_subtable (unsigned int platform_id,
|
||||
unsigned int encoding_id) const
|
||||
{
|
||||
EncodingRecord key;
|
||||
key.platformID.set (platform_id);
|
||||
key.encodingID.set (encoding_id);
|
||||
|
||||
/* Note: We can use bsearch, but since it has no performance
|
||||
* implications, we use lsearch and as such accept fonts with
|
||||
* unsorted subtable list. */
|
||||
int result = encodingRecord./*bsearch*/lsearch (key);
|
||||
if (result == -1 || !encodingRecord[result].subtable)
|
||||
return NULL;
|
||||
|
||||
return &(this+encodingRecord[result].subtable);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (version == 0) &&
|
||||
encodingRecord.sanitize (c, this));
|
||||
}
|
||||
|
||||
USHORT version; /* Table version number (0). */
|
||||
SortedArrayOf<EncodingRecord>
|
||||
encodingRecord; /* Encoding tables. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, encodingRecord);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_CMAP_TABLE_HH */
|
||||
662
gfx/harfbuzz/src/hb-ot-font.cc
Normal file
662
gfx/harfbuzz/src/hb-ot-font.cc
Normal file
|
|
@ -0,0 +1,662 @@
|
|||
/*
|
||||
* Copyright © 2011,2014 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, Roozbeh Pournader
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot.h"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
|
||||
#include "hb-ot-cmap-table.hh"
|
||||
#include "hb-ot-cbdt-table.hh"
|
||||
#include "hb-ot-glyf-table.hh"
|
||||
#include "hb-ot-head-table.hh"
|
||||
#include "hb-ot-hhea-table.hh"
|
||||
#include "hb-ot-hmtx-table.hh"
|
||||
#include "hb-ot-os2-table.hh"
|
||||
//#include "hb-ot-post-table.hh"
|
||||
|
||||
|
||||
struct hb_ot_face_metrics_accelerator_t
|
||||
{
|
||||
unsigned int num_metrics;
|
||||
unsigned int num_advances;
|
||||
unsigned int default_advance;
|
||||
unsigned short ascender;
|
||||
unsigned short descender;
|
||||
unsigned short line_gap;
|
||||
bool has_font_extents;
|
||||
|
||||
const OT::_mtx *table;
|
||||
hb_blob_t *blob;
|
||||
|
||||
inline void init (hb_face_t *face,
|
||||
hb_tag_t _hea_tag,
|
||||
hb_tag_t _mtx_tag,
|
||||
hb_tag_t os2_tag,
|
||||
unsigned int default_advance = 0)
|
||||
{
|
||||
this->default_advance = default_advance ? default_advance : face->get_upem ();
|
||||
|
||||
bool got_font_extents = false;
|
||||
if (os2_tag)
|
||||
{
|
||||
hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_table (os2_tag));
|
||||
const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob);
|
||||
#define USE_TYPO_METRICS (1u<<7)
|
||||
if (0 != (os2->fsSelection & USE_TYPO_METRICS))
|
||||
{
|
||||
this->ascender = os2->sTypoAscender;
|
||||
this->descender = os2->sTypoDescender;
|
||||
this->line_gap = os2->sTypoLineGap;
|
||||
got_font_extents = (this->ascender | this->descender) != 0;
|
||||
}
|
||||
hb_blob_destroy (os2_blob);
|
||||
}
|
||||
|
||||
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
|
||||
const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
|
||||
this->num_advances = _hea->numberOfLongMetrics;
|
||||
if (!got_font_extents)
|
||||
{
|
||||
this->ascender = _hea->ascender;
|
||||
this->descender = _hea->descender;
|
||||
this->line_gap = _hea->lineGap;
|
||||
got_font_extents = (this->ascender | this->descender) != 0;
|
||||
}
|
||||
hb_blob_destroy (_hea_blob);
|
||||
|
||||
this->has_font_extents = got_font_extents;
|
||||
|
||||
this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
|
||||
|
||||
/* Cap num_metrics() and num_advances() based on table length. */
|
||||
unsigned int len = hb_blob_get_length (this->blob);
|
||||
if (unlikely (this->num_advances * 4 > len))
|
||||
this->num_advances = len / 4;
|
||||
this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2;
|
||||
|
||||
/* We MUST set num_metrics to zero if num_advances is zero.
|
||||
* Our get_advance() depends on that. */
|
||||
if (unlikely (!this->num_advances))
|
||||
{
|
||||
this->num_metrics = this->num_advances = 0;
|
||||
hb_blob_destroy (this->blob);
|
||||
this->blob = hb_blob_get_empty ();
|
||||
}
|
||||
this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob);
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
hb_blob_destroy (this->blob);
|
||||
}
|
||||
|
||||
inline unsigned int get_advance (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (unlikely (glyph >= this->num_metrics))
|
||||
{
|
||||
/* If this->num_metrics is zero, it means we don't have the metrics table
|
||||
* for this direction: return default advance. Otherwise, it means that the
|
||||
* glyph index is out of bound: return zero. */
|
||||
if (this->num_metrics)
|
||||
return 0;
|
||||
else
|
||||
return this->default_advance;
|
||||
}
|
||||
|
||||
if (glyph >= this->num_advances)
|
||||
glyph = this->num_advances - 1;
|
||||
|
||||
return this->table->longMetric[glyph].advance;
|
||||
}
|
||||
};
|
||||
|
||||
struct hb_ot_face_glyf_accelerator_t
|
||||
{
|
||||
bool short_offset;
|
||||
unsigned int num_glyphs;
|
||||
const OT::loca *loca;
|
||||
const OT::glyf *glyf;
|
||||
hb_blob_t *loca_blob;
|
||||
hb_blob_t *glyf_blob;
|
||||
unsigned int glyf_len;
|
||||
|
||||
inline void init (hb_face_t *face)
|
||||
{
|
||||
hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head));
|
||||
const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob);
|
||||
if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0)
|
||||
{
|
||||
/* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
|
||||
hb_blob_destroy (head_blob);
|
||||
return;
|
||||
}
|
||||
this->short_offset = 0 == head->indexToLocFormat;
|
||||
hb_blob_destroy (head_blob);
|
||||
|
||||
this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca));
|
||||
this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob);
|
||||
this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf));
|
||||
this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob);
|
||||
|
||||
this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1;
|
||||
this->glyf_len = hb_blob_get_length (this->glyf_blob);
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
hb_blob_destroy (this->loca_blob);
|
||||
hb_blob_destroy (this->glyf_blob);
|
||||
}
|
||||
|
||||
inline bool get_extents (hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents) const
|
||||
{
|
||||
if (unlikely (glyph >= this->num_glyphs))
|
||||
return false;
|
||||
|
||||
unsigned int start_offset, end_offset;
|
||||
if (this->short_offset)
|
||||
{
|
||||
start_offset = 2 * this->loca->u.shortsZ[glyph];
|
||||
end_offset = 2 * this->loca->u.shortsZ[glyph + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
start_offset = this->loca->u.longsZ[glyph];
|
||||
end_offset = this->loca->u.longsZ[glyph + 1];
|
||||
}
|
||||
|
||||
if (start_offset > end_offset || end_offset > this->glyf_len)
|
||||
return false;
|
||||
|
||||
if (end_offset - start_offset < OT::glyfGlyphHeader::static_size)
|
||||
return true; /* Empty glyph; zero extents. */
|
||||
|
||||
const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset);
|
||||
|
||||
extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
|
||||
extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
|
||||
extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
|
||||
extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct hb_ot_face_cbdt_accelerator_t
|
||||
{
|
||||
hb_blob_t *cblc_blob;
|
||||
hb_blob_t *cbdt_blob;
|
||||
const OT::CBLC *cblc;
|
||||
const OT::CBDT *cbdt;
|
||||
|
||||
unsigned int cbdt_len;
|
||||
float upem;
|
||||
|
||||
inline void init (hb_face_t *face)
|
||||
{
|
||||
upem = face->get_upem();
|
||||
|
||||
cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
|
||||
cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
|
||||
cbdt_len = hb_blob_get_length (cbdt_blob);
|
||||
|
||||
if (hb_blob_get_length (cblc_blob) == 0) {
|
||||
cblc = NULL;
|
||||
cbdt = NULL;
|
||||
return; /* Not a bitmap font. */
|
||||
}
|
||||
cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob);
|
||||
cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
|
||||
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
hb_blob_destroy (this->cblc_blob);
|
||||
hb_blob_destroy (this->cbdt_blob);
|
||||
}
|
||||
|
||||
inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
|
||||
{
|
||||
unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
|
||||
|
||||
if (cblc == NULL)
|
||||
return false; // Not a color bitmap font.
|
||||
|
||||
const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
|
||||
if (subtable_record == NULL)
|
||||
return false;
|
||||
|
||||
if (subtable_record->get_extents (extents))
|
||||
return true;
|
||||
|
||||
unsigned int image_offset = 0, image_length = 0, image_format = 0;
|
||||
if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
|
||||
return false;
|
||||
|
||||
{
|
||||
/* TODO Move the following into CBDT struct when adding more formats. */
|
||||
|
||||
if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
|
||||
return false;
|
||||
|
||||
switch (image_format)
|
||||
{
|
||||
case 17: {
|
||||
if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size))
|
||||
return false;
|
||||
|
||||
const OT::GlyphBitmapDataFormat17& glyphFormat17 =
|
||||
OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
|
||||
glyphFormat17.glyphMetrics.get_extents (extents);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// TODO: Support other image formats.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert to the font units. */
|
||||
extents->x_bearing *= upem / (float) x_ppem;
|
||||
extents->y_bearing *= upem / (float) y_ppem;
|
||||
extents->width *= upem / (float) x_ppem;
|
||||
extents->height *= upem / (float) y_ppem;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
||||
hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph);
|
||||
|
||||
template <typename Type>
|
||||
static inline bool get_glyph_from (const void *obj,
|
||||
hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
const Type *typed_obj = (const Type *) obj;
|
||||
return typed_obj->get_glyph (codepoint, glyph);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
static inline bool get_glyph_from_symbol (const void *obj,
|
||||
hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
const Type *typed_obj = (const Type *) obj;
|
||||
if (likely (typed_obj->get_glyph (codepoint, glyph)))
|
||||
return true;
|
||||
|
||||
if (codepoint <= 0x00FFu)
|
||||
{
|
||||
/* For symbol-encoded OpenType fonts, we duplicate the
|
||||
* U+F000..F0FF range at U+0000..U+00FF. That's what
|
||||
* Windows seems to do, and that's hinted about at:
|
||||
* http://www.microsoft.com/typography/otspec/recom.htm
|
||||
* under "Non-Standard (Symbol) Fonts". */
|
||||
return typed_obj->get_glyph (0xF000u + codepoint, glyph);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct hb_ot_face_cmap_accelerator_t
|
||||
{
|
||||
hb_cmap_get_glyph_func_t get_glyph_func;
|
||||
const void *get_glyph_data;
|
||||
OT::CmapSubtableFormat4::accelerator_t format4_accel;
|
||||
|
||||
const OT::CmapSubtableFormat14 *uvs_table;
|
||||
hb_blob_t *blob;
|
||||
|
||||
inline void init (hb_face_t *face)
|
||||
{
|
||||
this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
|
||||
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
|
||||
const OT::CmapSubtable *subtable = NULL;
|
||||
const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
|
||||
|
||||
bool symbol = false;
|
||||
/* 32-bit subtables. */
|
||||
if (!subtable) subtable = cmap->find_subtable (3, 10);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 6);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 4);
|
||||
/* 16-bit subtables. */
|
||||
if (!subtable) subtable = cmap->find_subtable (3, 1);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 3);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 2);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 1);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 0);
|
||||
if (!subtable)
|
||||
{
|
||||
subtable = cmap->find_subtable (3, 0);
|
||||
if (subtable) symbol = true;
|
||||
}
|
||||
/* Meh. */
|
||||
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
||||
|
||||
/* UVS subtable. */
|
||||
if (!subtable_uvs)
|
||||
{
|
||||
const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
|
||||
if (st && st->u.format == 14)
|
||||
subtable_uvs = &st->u.format14;
|
||||
}
|
||||
/* Meh. */
|
||||
if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
|
||||
|
||||
this->uvs_table = subtable_uvs;
|
||||
|
||||
this->get_glyph_data = subtable;
|
||||
if (unlikely (symbol))
|
||||
this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
|
||||
else
|
||||
switch (subtable->u.format) {
|
||||
/* Accelerate format 4 and format 12. */
|
||||
default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
|
||||
case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
|
||||
case 4:
|
||||
{
|
||||
this->format4_accel.init (&subtable->u.format4);
|
||||
this->get_glyph_data = &this->format4_accel;
|
||||
this->get_glyph_func = this->format4_accel.get_glyph_func;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
hb_blob_destroy (this->blob);
|
||||
}
|
||||
|
||||
inline bool get_nominal_glyph (hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
|
||||
}
|
||||
|
||||
inline bool get_variation_glyph (hb_codepoint_t unicode,
|
||||
hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
switch (this->uvs_table->get_glyph_variant (unicode,
|
||||
variation_selector,
|
||||
glyph))
|
||||
{
|
||||
case OT::GLYPH_VARIANT_NOT_FOUND: return false;
|
||||
case OT::GLYPH_VARIANT_FOUND: return true;
|
||||
case OT::GLYPH_VARIANT_USE_DEFAULT: break;
|
||||
}
|
||||
|
||||
return get_nominal_glyph (unicode, glyph);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct hb_lazy_loader_t
|
||||
{
|
||||
inline void init (hb_face_t *face_)
|
||||
{
|
||||
face = face_;
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
if (instance && instance != &OT::Null(T))
|
||||
{
|
||||
instance->fini();
|
||||
free (instance);
|
||||
}
|
||||
}
|
||||
|
||||
inline const T* operator-> (void) const
|
||||
{
|
||||
retry:
|
||||
T *p = (T *) hb_atomic_ptr_get (&instance);
|
||||
if (unlikely (!p))
|
||||
{
|
||||
p = (T *) calloc (1, sizeof (T));
|
||||
if (unlikely (!p))
|
||||
return &OT::Null(T);
|
||||
p->init (face);
|
||||
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p)))
|
||||
{
|
||||
p->fini ();
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_face_t *face;
|
||||
T *instance;
|
||||
};
|
||||
|
||||
struct hb_ot_font_t
|
||||
{
|
||||
hb_ot_face_cmap_accelerator_t cmap;
|
||||
hb_ot_face_metrics_accelerator_t h_metrics;
|
||||
hb_ot_face_metrics_accelerator_t v_metrics;
|
||||
hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
|
||||
hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
|
||||
};
|
||||
|
||||
|
||||
static hb_ot_font_t *
|
||||
_hb_ot_font_create (hb_face_t *face)
|
||||
{
|
||||
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
|
||||
|
||||
if (unlikely (!ot_font))
|
||||
return NULL;
|
||||
|
||||
ot_font->cmap.init (face);
|
||||
ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2);
|
||||
ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE,
|
||||
ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
|
||||
ot_font->glyf.init (face);
|
||||
ot_font->cbdt.init (face);
|
||||
|
||||
return ot_font;
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
|
||||
{
|
||||
ot_font->cmap.fini ();
|
||||
ot_font->h_metrics.fini ();
|
||||
ot_font->v_metrics.fini ();
|
||||
ot_font->glyf.fini ();
|
||||
ot_font->cbdt.fini ();
|
||||
|
||||
free (ot_font);
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
return ot_font->cmap.get_nominal_glyph (unicode, glyph);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t variation_selector,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph);
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
return font->em_scale_x (ot_font->h_metrics.get_advance (glyph));
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph));
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
bool ret = ot_font->glyf->get_extents (glyph, extents);
|
||||
if (!ret)
|
||||
ret = ot_font->cbdt->get_extents (glyph, extents);
|
||||
extents->x_bearing = font->em_scale_x (extents->x_bearing);
|
||||
extents->y_bearing = font->em_scale_y (extents->y_bearing);
|
||||
extents->width = font->em_scale_x (extents->width);
|
||||
extents->height = font->em_scale_y (extents->height);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
|
||||
metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
|
||||
metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
|
||||
return ot_font->h_metrics.has_font_extents;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
|
||||
metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
|
||||
metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
|
||||
return ot_font->v_metrics.has_font_extents;
|
||||
}
|
||||
|
||||
static hb_font_funcs_t *static_ot_funcs = NULL;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_ot_funcs (void)
|
||||
{
|
||||
hb_font_funcs_destroy (static_ot_funcs);
|
||||
}
|
||||
#endif
|
||||
|
||||
static hb_font_funcs_t *
|
||||
_hb_ot_get_font_funcs (void)
|
||||
{
|
||||
retry:
|
||||
hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs);
|
||||
|
||||
if (unlikely (!funcs))
|
||||
{
|
||||
funcs = hb_font_funcs_create ();
|
||||
|
||||
hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL);
|
||||
hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL);
|
||||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, NULL, NULL);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO
|
||||
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL);
|
||||
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL);
|
||||
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO
|
||||
//hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO
|
||||
//hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO
|
||||
|
||||
hb_font_funcs_make_immutable (funcs);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) {
|
||||
hb_font_funcs_destroy (funcs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_static_ot_funcs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
};
|
||||
|
||||
return funcs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_ot_font_set_funcs:
|
||||
*
|
||||
* Since: 0.9.28
|
||||
**/
|
||||
void
|
||||
hb_ot_font_set_funcs (hb_font_t *font)
|
||||
{
|
||||
hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
|
||||
if (unlikely (!ot_font))
|
||||
return;
|
||||
|
||||
hb_font_set_funcs (font,
|
||||
_hb_ot_get_font_funcs (),
|
||||
ot_font,
|
||||
(hb_destroy_func_t) _hb_ot_font_destroy);
|
||||
}
|
||||
45
gfx/harfbuzz/src/hb-ot-font.h
Normal file
45
gfx/harfbuzz/src/hb-ot-font.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright © 2014 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, Roozbeh Pournader
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_FONT_H
|
||||
#define HB_OT_FONT_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_font_set_funcs (hb_font_t *font);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_FONT_H */
|
||||
104
gfx/harfbuzz/src/hb-ot-glyf-table.hh
Normal file
104
gfx/harfbuzz/src/hb-ot-glyf-table.hh
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright © 2015 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_GLYF_TABLE_HH
|
||||
#define HB_OT_GLYF_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* loca -- Index to Location
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
|
||||
|
||||
|
||||
struct loca
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_loca;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
public:
|
||||
union {
|
||||
USHORT shortsZ[VAR]; /* Location offset divided by 2. */
|
||||
ULONG longsZ[VAR]; /* Location offset. */
|
||||
} u;
|
||||
DEFINE_SIZE_ARRAY (0, u.longsZ);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* glyf -- TrueType Glyph Data
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
|
||||
|
||||
|
||||
struct glyf
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_glyf;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* We don't check for anything specific here. The users of the
|
||||
* struct do all the hard work... */
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
public:
|
||||
BYTE dataX[VAR]; /* Glyphs data. */
|
||||
|
||||
DEFINE_SIZE_ARRAY (0, dataX);
|
||||
};
|
||||
|
||||
struct glyfGlyphHeader
|
||||
{
|
||||
SHORT numberOfContours; /* If the number of contours is
|
||||
* greater than or equal to zero,
|
||||
* this is a simple glyph; if negative,
|
||||
* this is a composite glyph. */
|
||||
FWORD xMin; /* Minimum x for coordinate data. */
|
||||
FWORD yMin; /* Minimum y for coordinate data. */
|
||||
FWORD xMax; /* Maximum x for coordinate data. */
|
||||
FWORD yMax; /* Maximum y for coordinate data. */
|
||||
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_GLYF_TABLE_HH */
|
||||
154
gfx/harfbuzz/src/hb-ot-head-table.hh
Normal file
154
gfx/harfbuzz/src/hb-ot-head-table.hh
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright © 2010 Red Hat, Inc.
|
||||
* Copyright © 2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_HEAD_TABLE_HH
|
||||
#define HB_OT_HEAD_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* head -- Font Header
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_head HB_TAG('h','e','a','d')
|
||||
|
||||
struct head
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_head;
|
||||
|
||||
inline unsigned int get_upem (void) const
|
||||
{
|
||||
unsigned int upem = unitsPerEm;
|
||||
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
|
||||
return 16 <= upem && upem <= 16384 ? upem : 1000;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
version.major == 1 &&
|
||||
magicNumber == 0x5F0F3CF5u);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the head table--currently
|
||||
* 0x00010000u for version 1.0. */
|
||||
FixedVersion<>fontRevision; /* Set by font manufacturer. */
|
||||
ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
|
||||
* entire font as ULONG, then store
|
||||
* 0xB1B0AFBAu - sum. */
|
||||
ULONG magicNumber; /* Set to 0x5F0F3CF5u. */
|
||||
USHORT flags; /* Bit 0: Baseline for font at y=0;
|
||||
* Bit 1: Left sidebearing point at x=0;
|
||||
* Bit 2: Instructions may depend on point size;
|
||||
* Bit 3: Force ppem to integer values for all
|
||||
* internal scaler math; may use fractional
|
||||
* ppem sizes if this bit is clear;
|
||||
* Bit 4: Instructions may alter advance width
|
||||
* (the advance widths might not scale linearly);
|
||||
|
||||
* Bits 5-10: These should be set according to
|
||||
* Apple's specification. However, they are not
|
||||
* implemented in OpenType.
|
||||
* Bit 5: This bit should be set in fonts that are
|
||||
* intended to e laid out vertically, and in
|
||||
* which the glyphs have been drawn such that an
|
||||
* x-coordinate of 0 corresponds to the desired
|
||||
* vertical baseline.
|
||||
* Bit 6: This bit must be set to zero.
|
||||
* Bit 7: This bit should be set if the font
|
||||
* requires layout for correct linguistic
|
||||
* rendering (e.g. Arabic fonts).
|
||||
* Bit 8: This bit should be set for a GX font
|
||||
* which has one or more metamorphosis effects
|
||||
* designated as happening by default.
|
||||
* Bit 9: This bit should be set if the font
|
||||
* contains any strong right-to-left glyphs.
|
||||
* Bit 10: This bit should be set if the font
|
||||
* contains Indic-style rearrangement effects.
|
||||
|
||||
* Bit 11: Font data is 'lossless,' as a result
|
||||
* of having been compressed and decompressed
|
||||
* with the Agfa MicroType Express engine.
|
||||
* Bit 12: Font converted (produce compatible metrics)
|
||||
* Bit 13: Font optimized for ClearType™.
|
||||
* Note, fonts that rely on embedded bitmaps (EBDT)
|
||||
* for rendering should not be considered optimized
|
||||
* for ClearType, and therefore should keep this bit
|
||||
* cleared.
|
||||
* Bit 14: Last Resort font. If set, indicates that
|
||||
* the glyphs encoded in the cmap subtables are simply
|
||||
* generic symbolic representations of code point
|
||||
* ranges and don’t truly represent support for those
|
||||
* code points. If unset, indicates that the glyphs
|
||||
* encoded in the cmap subtables represent proper
|
||||
* support for those code points.
|
||||
* Bit 15: Reserved, set to 0. */
|
||||
USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value
|
||||
* should be a power of 2 for fonts that have
|
||||
* TrueType outlines. */
|
||||
LONGDATETIME created; /* Number of seconds since 12:00 midnight,
|
||||
January 1, 1904. 64-bit integer */
|
||||
LONGDATETIME modified; /* Number of seconds since 12:00 midnight,
|
||||
January 1, 1904. 64-bit integer */
|
||||
SHORT xMin; /* For all glyph bounding boxes. */
|
||||
SHORT yMin; /* For all glyph bounding boxes. */
|
||||
SHORT xMax; /* For all glyph bounding boxes. */
|
||||
SHORT yMax; /* For all glyph bounding boxes. */
|
||||
USHORT macStyle; /* Bit 0: Bold (if set to 1);
|
||||
* Bit 1: Italic (if set to 1)
|
||||
* Bit 2: Underline (if set to 1)
|
||||
* Bit 3: Outline (if set to 1)
|
||||
* Bit 4: Shadow (if set to 1)
|
||||
* Bit 5: Condensed (if set to 1)
|
||||
* Bit 6: Extended (if set to 1)
|
||||
* Bits 7-15: Reserved (set to 0). */
|
||||
USHORT lowestRecPPEM; /* Smallest readable size in pixels. */
|
||||
SHORT fontDirectionHint; /* Deprecated (Set to 2).
|
||||
* 0: Fully mixed directional glyphs;
|
||||
* 1: Only strongly left to right;
|
||||
* 2: Like 1 but also contains neutrals;
|
||||
* -1: Only strongly right to left;
|
||||
* -2: Like -1 but also contains neutrals. */
|
||||
public:
|
||||
SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */
|
||||
SHORT glyphDataFormat; /* 0 for current format. */
|
||||
|
||||
DEFINE_SIZE_STATIC (54);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HEAD_TABLE_HH */
|
||||
103
gfx/harfbuzz/src/hb-ot-hhea-table.hh
Normal file
103
gfx/harfbuzz/src/hb-ot-hhea-table.hh
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_HHEA_TABLE_HH
|
||||
#define HB_OT_HHEA_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* hhea -- The Horizontal Header Table
|
||||
* vhea -- The Vertical Header Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
|
||||
#define HB_OT_TAG_vhea HB_TAG('v','h','e','a')
|
||||
|
||||
|
||||
struct _hea
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_TAG('_','h','e','a');
|
||||
|
||||
static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
|
||||
static const hb_tag_t vheaTag = HB_OT_TAG_vhea;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && likely (version.major == 1));
|
||||
}
|
||||
|
||||
public:
|
||||
FixedVersion<>version; /* 0x00010000u for version 1.0. */
|
||||
FWORD ascender; /* Typographic ascent. */
|
||||
FWORD descender; /* Typographic descent. */
|
||||
FWORD lineGap; /* Typographic line gap. */
|
||||
UFWORD advanceMax; /* Maximum advance width/height value in
|
||||
* metrics table. */
|
||||
FWORD minLeadingBearing; /* Minimum left/top sidebearing value in
|
||||
* metrics table. */
|
||||
FWORD minTrailingBearing; /* Minimum right/bottom sidebearing value;
|
||||
* calculated as Min(aw - lsb -
|
||||
* (xMax - xMin)) for horizontal. */
|
||||
FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)),
|
||||
* vertical: minLeadingBearing+(yMax-yMin). */
|
||||
SHORT caretSlopeRise; /* Used to calculate the slope of the
|
||||
* cursor (rise/run); 1 for vertical caret,
|
||||
* 0 for horizontal.*/
|
||||
SHORT caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
|
||||
SHORT caretOffset; /* The amount by which a slanted
|
||||
* highlight on a glyph needs
|
||||
* to be shifted to produce the
|
||||
* best appearance. Set to 0 for
|
||||
* non-slanted fonts. */
|
||||
SHORT reserved1; /* Set to 0. */
|
||||
SHORT reserved2; /* Set to 0. */
|
||||
SHORT reserved3; /* Set to 0. */
|
||||
SHORT reserved4; /* Set to 0. */
|
||||
SHORT metricDataFormat; /* 0 for current format. */
|
||||
USHORT numberOfLongMetrics; /* Number of LongMetric entries in metric
|
||||
* table. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (36);
|
||||
};
|
||||
|
||||
struct hhea : _hea {
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_hhea;
|
||||
};
|
||||
struct vhea : _hea {
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_vhea;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HHEA_TABLE_HH */
|
||||
104
gfx/harfbuzz/src/hb-ot-hmtx-table.hh
Normal file
104
gfx/harfbuzz/src/hb-ot-hmtx-table.hh
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_HMTX_TABLE_HH
|
||||
#define HB_OT_HMTX_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* hmtx -- The Horizontal Metrics Table
|
||||
* vmtx -- The Vertical Metrics Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
|
||||
#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
|
||||
|
||||
|
||||
struct LongMetric
|
||||
{
|
||||
UFWORD advance; /* Advance width/height. */
|
||||
FWORD lsb; /* Leading (left/top) side bearing. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct _mtx
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_TAG('_','m','t','x');
|
||||
|
||||
static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
|
||||
static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* We don't check for anything specific here. The users of the
|
||||
* struct do all the hard work... */
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
public:
|
||||
LongMetric longMetric[VAR]; /* Paired advance width and leading
|
||||
* bearing values for each glyph. The
|
||||
* value numOfHMetrics comes from
|
||||
* the 'hhea' table. If the font is
|
||||
* monospaced, only one entry need
|
||||
* be in the array, but that entry is
|
||||
* required. The last entry applies to
|
||||
* all subsequent glyphs. */
|
||||
FWORD leadingBearingX[VAR]; /* Here the advance is assumed
|
||||
* to be the same as the advance
|
||||
* for the last entry above. The
|
||||
* number of entries in this array is
|
||||
* derived from numGlyphs (from 'maxp'
|
||||
* table) minus numberOfLongMetrics.
|
||||
* This generally is used with a run
|
||||
* of monospaced glyphs (e.g., Kanji
|
||||
* fonts or Courier fonts). Only one
|
||||
* run is allowed and it must be at
|
||||
* the end. This allows a monospaced
|
||||
* font to vary the side bearing
|
||||
* values for each glyph. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
|
||||
};
|
||||
|
||||
struct hmtx : _mtx {
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_hmtx;
|
||||
};
|
||||
struct vmtx : _mtx {
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_vmtx;
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_HMTX_TABLE_HH */
|
||||
1713
gfx/harfbuzz/src/hb-ot-layout-common-private.hh
Normal file
1713
gfx/harfbuzz/src/hb-ot-layout-common-private.hh
Normal file
File diff suppressed because it is too large
Load diff
459
gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh
Normal file
459
gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
|
||||
#define HB_OT_LAYOUT_GDEF_TABLE_HH
|
||||
|
||||
#include "hb-ot-layout-common-private.hh"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* Attachment List Table
|
||||
*/
|
||||
|
||||
typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in
|
||||
* increasing numerical order */
|
||||
|
||||
struct AttachList
|
||||
{
|
||||
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (point_count)
|
||||
*point_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const AttachPoint &points = this+attachPoint[index];
|
||||
|
||||
if (point_count) {
|
||||
const USHORT *array = points.sub_array (start_offset, point_count);
|
||||
unsigned int count = *point_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
point_array[i] = array[i];
|
||||
}
|
||||
|
||||
return points.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table -- from
|
||||
* beginning of AttachList table */
|
||||
OffsetArrayOf<AttachPoint>
|
||||
attachPoint; /* Array of AttachPoint tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, attachPoint);
|
||||
};
|
||||
|
||||
/*
|
||||
* Ligature Caret Table
|
||||
*/
|
||||
|
||||
struct CaretValueFormat1
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
private:
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 1 */
|
||||
SHORT coordinate; /* X or Y value, in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat2
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
private:
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
hb_position_t x, y;
|
||||
if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 2 */
|
||||
USHORT caretValuePoint; /* Contour point index on glyph */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat3
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, const VariationStore &var_store) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ?
|
||||
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
|
||||
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT caretValueFormat; /* Format identifier--format = 3 */
|
||||
SHORT coordinate; /* X or Y value, in design units */
|
||||
OffsetTo<Device>
|
||||
deviceTable; /* Offset to Device table for X or Y
|
||||
* value--from beginning of CaretValue
|
||||
* table */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct CaretValue
|
||||
{
|
||||
inline hb_position_t get_caret_value (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_caret_value (font, direction);
|
||||
case 2: return u.format2.get_caret_value (font, direction, glyph_id);
|
||||
case 3: return u.format3.get_caret_value (font, direction, var_store);
|
||||
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 (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
CaretValueFormat1 format1;
|
||||
CaretValueFormat2 format2;
|
||||
CaretValueFormat3 format3;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
struct LigGlyph
|
||||
{
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
if (caret_count) {
|
||||
const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
|
||||
unsigned int count = *caret_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
|
||||
}
|
||||
|
||||
return carets.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (carets.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetArrayOf<CaretValue>
|
||||
carets; /* Offset array of CaretValue tables
|
||||
* --from beginning of LigGlyph table
|
||||
* --in increasing coordinate order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, carets);
|
||||
};
|
||||
|
||||
struct LigCaretList
|
||||
{
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (caret_count)
|
||||
*caret_count = 0;
|
||||
return 0;
|
||||
}
|
||||
const LigGlyph &lig_glyph = this+ligGlyph[index];
|
||||
return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of LigCaretList table */
|
||||
OffsetArrayOf<LigGlyph>
|
||||
ligGlyph; /* Array of LigGlyph tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, ligGlyph);
|
||||
};
|
||||
|
||||
|
||||
struct MarkGlyphSetsFormat1
|
||||
{
|
||||
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format identifier--format = 1 */
|
||||
ArrayOf<OffsetTo<Coverage, ULONG> >
|
||||
coverage; /* Array of long offsets to mark set
|
||||
* coverage tables */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, coverage);
|
||||
};
|
||||
|
||||
struct MarkGlyphSets
|
||||
{
|
||||
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.covers (set_index, glyph_id);
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
MarkGlyphSetsFormat1 format1;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GDEF -- The Glyph Definition Table
|
||||
*/
|
||||
|
||||
struct GDEF
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_GDEF;
|
||||
|
||||
enum GlyphClasses {
|
||||
UnclassifiedGlyph = 0,
|
||||
BaseGlyph = 1,
|
||||
LigatureGlyph = 2,
|
||||
MarkGlyph = 3,
|
||||
ComponentGlyph = 4
|
||||
};
|
||||
|
||||
inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
|
||||
inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
|
||||
{ return (this+glyphClassDef).get_class (glyph); }
|
||||
inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
|
||||
{ (this+glyphClassDef).add_class (glyphs, klass); }
|
||||
|
||||
inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
|
||||
inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
|
||||
{ return (this+markAttachClassDef).get_class (glyph); }
|
||||
|
||||
inline bool has_attach_points (void) const { return attachList != 0; }
|
||||
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{ return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
|
||||
|
||||
inline bool has_lig_carets (void) const { return ligCaretList != 0; }
|
||||
inline unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{ return (this+ligCaretList).get_lig_carets (font,
|
||||
direction, glyph_id, get_var_store(),
|
||||
start_offset, caret_count, caret_array); }
|
||||
|
||||
inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; }
|
||||
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); }
|
||||
|
||||
inline bool has_var_store (void) const { return version.to_int () >= 0x00010003u && varStore != 0; }
|
||||
inline const VariationStore &get_var_store (void) const
|
||||
{ return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
glyphClassDef.sanitize (c, this) &&
|
||||
attachList.sanitize (c, this) &&
|
||||
ligCaretList.sanitize (c, this) &&
|
||||
markAttachClassDef.sanitize (c, this) &&
|
||||
(version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
|
||||
(version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
|
||||
}
|
||||
|
||||
/* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
|
||||
* glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
|
||||
* Not to be confused with lookup_props which is very similar. */
|
||||
inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
|
||||
{
|
||||
unsigned int klass = get_glyph_class (glyph);
|
||||
|
||||
ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
|
||||
ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
|
||||
ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
|
||||
|
||||
switch (klass) {
|
||||
default: return 0;
|
||||
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
|
||||
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
|
||||
case MarkGlyph:
|
||||
klass = get_mark_attachment_type (glyph);
|
||||
return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the GDEF table--currently
|
||||
* 0x00010003u */
|
||||
OffsetTo<ClassDef>
|
||||
glyphClassDef; /* Offset to class definition table
|
||||
* for glyph type--from beginning of
|
||||
* GDEF header (may be Null) */
|
||||
OffsetTo<AttachList>
|
||||
attachList; /* Offset to list of glyphs with
|
||||
* attachment points--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<LigCaretList>
|
||||
ligCaretList; /* Offset to list of positioning points
|
||||
* for ligature carets--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<ClassDef>
|
||||
markAttachClassDef; /* Offset to class definition table for
|
||||
* mark attachment type--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
OffsetTo<MarkGlyphSets>
|
||||
markGlyphSetsDef; /* Offset to the table of mark set
|
||||
* definitions--from beginning of GDEF
|
||||
* header (may be NULL). Introduced
|
||||
* in version 0x00010002. */
|
||||
OffsetTo<VariationStore, ULONG>
|
||||
varStore; /* Offset to the table of Item Variation
|
||||
* Store--from beginning of GDEF
|
||||
* header (may be NULL). Introduced
|
||||
* in version 0x00010003. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (12);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
|
||||
1654
gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
Normal file
1654
gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
Normal file
File diff suppressed because it is too large
Load diff
1369
gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh
Normal file
1369
gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh
Normal file
File diff suppressed because it is too large
Load diff
2329
gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
Normal file
2329
gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
Normal file
File diff suppressed because it is too large
Load diff
234
gfx/harfbuzz/src/hb-ot-layout-jstf-table.hh
Normal file
234
gfx/harfbuzz/src/hb-ot-layout-jstf-table.hh
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Copyright © 2013 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_JSTF_TABLE_HH
|
||||
#define HB_OT_LAYOUT_JSTF_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-ot-layout-gpos-table.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* JstfModList -- Justification Modification List Tables
|
||||
*/
|
||||
|
||||
typedef IndexArray JstfModList;
|
||||
|
||||
|
||||
/*
|
||||
* JstfMax -- Justification Maximum Table
|
||||
*/
|
||||
|
||||
typedef OffsetListOf<PosLookup> JstfMax;
|
||||
|
||||
|
||||
/*
|
||||
* JstfPriority -- Justification Priority Table
|
||||
*/
|
||||
|
||||
struct JstfPriority
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
shrinkageEnableGSUB.sanitize (c, this) &&
|
||||
shrinkageDisableGSUB.sanitize (c, this) &&
|
||||
shrinkageEnableGPOS.sanitize (c, this) &&
|
||||
shrinkageDisableGPOS.sanitize (c, this) &&
|
||||
shrinkageJstfMax.sanitize (c, this) &&
|
||||
extensionEnableGSUB.sanitize (c, this) &&
|
||||
extensionDisableGSUB.sanitize (c, this) &&
|
||||
extensionEnableGPOS.sanitize (c, this) &&
|
||||
extensionDisableGPOS.sanitize (c, this) &&
|
||||
extensionJstfMax.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<JstfModList>
|
||||
shrinkageEnableGSUB; /* Offset to Shrinkage Enable GSUB
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
shrinkageDisableGSUB; /* Offset to Shrinkage Disable GSUB
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
shrinkageEnableGPOS; /* Offset to Shrinkage Enable GPOS
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
shrinkageDisableGPOS; /* Offset to Shrinkage Disable GPOS
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfMax>
|
||||
shrinkageJstfMax; /* Offset to Shrinkage JstfMax table--
|
||||
* from beginning of JstfPriority table
|
||||
* --may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
extensionEnableGSUB; /* Offset to Extension Enable GSUB
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
extensionDisableGSUB; /* Offset to Extension Disable GSUB
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
extensionEnableGPOS; /* Offset to Extension Enable GPOS
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfModList>
|
||||
extensionDisableGPOS; /* Offset to Extension Disable GPOS
|
||||
* JstfModList table--from beginning of
|
||||
* JstfPriority table--may be NULL */
|
||||
OffsetTo<JstfMax>
|
||||
extensionJstfMax; /* Offset to Extension JstfMax table--
|
||||
* from beginning of JstfPriority table
|
||||
* --may be NULL */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (20);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* JstfLangSys -- Justification Language System Table
|
||||
*/
|
||||
|
||||
struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<JstfLangSys>::sanitize_closure_t * = NULL) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (OffsetListOf<JstfPriority>::sanitize (c));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ExtenderGlyphs -- Extender Glyph Table
|
||||
*/
|
||||
|
||||
typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
|
||||
|
||||
|
||||
/*
|
||||
* JstfScript -- The Justification Table
|
||||
*/
|
||||
|
||||
struct JstfScript
|
||||
{
|
||||
inline unsigned int get_lang_sys_count (void) const
|
||||
{ return langSys.len; }
|
||||
inline const Tag& get_lang_sys_tag (unsigned int i) const
|
||||
{ return langSys.get_tag (i); }
|
||||
inline unsigned int get_lang_sys_tags (unsigned int start_offset,
|
||||
unsigned int *lang_sys_count /* IN/OUT */,
|
||||
hb_tag_t *lang_sys_tags /* OUT */) const
|
||||
{ return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
|
||||
inline const JstfLangSys& get_lang_sys (unsigned int i) const
|
||||
{
|
||||
if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
|
||||
return this+langSys[i].offset;
|
||||
}
|
||||
inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
|
||||
{ return langSys.find_index (tag, index); }
|
||||
|
||||
inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
|
||||
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<JstfScript>::sanitize_closure_t * = NULL) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (extenderGlyphs.sanitize (c, this) &&
|
||||
defaultLangSys.sanitize (c, this) &&
|
||||
langSys.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<ExtenderGlyphs>
|
||||
extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning
|
||||
* of JstfScript table-may be NULL */
|
||||
OffsetTo<JstfLangSys>
|
||||
defaultLangSys; /* Offset to DefaultJstfLangSys table--from
|
||||
* beginning of JstfScript table--may be Null */
|
||||
RecordArrayOf<JstfLangSys>
|
||||
langSys; /* Array of JstfLangSysRecords--listed
|
||||
* alphabetically by LangSysTag */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, langSys);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* JSTF -- The Justification Table
|
||||
*/
|
||||
|
||||
struct JSTF
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_JSTF;
|
||||
|
||||
inline unsigned int get_script_count (void) const
|
||||
{ return scriptList.len; }
|
||||
inline const Tag& get_script_tag (unsigned int i) const
|
||||
{ return scriptList.get_tag (i); }
|
||||
inline unsigned int get_script_tags (unsigned int start_offset,
|
||||
unsigned int *script_count /* IN/OUT */,
|
||||
hb_tag_t *script_tags /* OUT */) const
|
||||
{ return scriptList.get_tags (start_offset, script_count, script_tags); }
|
||||
inline const JstfScript& get_script (unsigned int i) const
|
||||
{ return this+scriptList[i].offset; }
|
||||
inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
|
||||
{ return scriptList.find_index (tag, index); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
scriptList.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the JSTF table--initially set
|
||||
* to 0x00010000u */
|
||||
RecordArrayOf<JstfScript>
|
||||
scriptList; /* Array of JstfScripts--listed
|
||||
* alphabetically by ScriptTag */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, scriptList);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_JSTF_TABLE_HH */
|
||||
722
gfx/harfbuzz/src/hb-ot-layout-math-table.hh
Normal file
722
gfx/harfbuzz/src/hb-ot-layout-math-table.hh
Normal file
|
|
@ -0,0 +1,722 @@
|
|||
/*
|
||||
* Copyright © 2016 Igalia S.L.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Igalia Author(s): Frédéric Wang
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_MATH_TABLE_HH
|
||||
#define HB_OT_LAYOUT_MATH_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-ot-layout-common-private.hh"
|
||||
#include "hb-ot-math.h"
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
struct MathValueRecord
|
||||
{
|
||||
inline hb_position_t get_x_value (hb_font_t *font, const void *base) const
|
||||
{ return font->em_scale_x (value) + (base+deviceTable).get_x_delta (font); }
|
||||
inline hb_position_t get_y_value (hb_font_t *font, const void *base) const
|
||||
{ return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && deviceTable.sanitize (c, base));
|
||||
}
|
||||
|
||||
protected:
|
||||
SHORT value; /* The X or Y value in design units */
|
||||
OffsetTo<Device> deviceTable; /* Offset to the device table - from the
|
||||
* beginning of parent table. May be NULL.
|
||||
* Suggested format for device table is 1. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct MathConstants
|
||||
{
|
||||
inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
||||
unsigned int count = ARRAY_LENGTH (mathValueRecords);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!mathValueRecords[i].sanitize (c, this))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && sanitize_math_value_records(c));
|
||||
}
|
||||
|
||||
inline hb_position_t get_value (hb_ot_math_constant_t constant,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
switch (constant) {
|
||||
|
||||
case HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN:
|
||||
return percentScaleDown[constant - HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN];
|
||||
|
||||
case HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT:
|
||||
case HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT:
|
||||
return font->em_scale_y (minHeight[constant - HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT]);
|
||||
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE:
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
|
||||
case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
|
||||
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this);
|
||||
|
||||
case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
|
||||
case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
|
||||
case HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS:
|
||||
case HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_MATH_LEADING:
|
||||
case HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER:
|
||||
case HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS:
|
||||
case HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER:
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS:
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_STACK_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN:
|
||||
case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN:
|
||||
case HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN:
|
||||
case HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX:
|
||||
case HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN:
|
||||
case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX:
|
||||
case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT:
|
||||
case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN:
|
||||
case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP:
|
||||
case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED:
|
||||
case HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER:
|
||||
case HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS:
|
||||
case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
|
||||
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
|
||||
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
|
||||
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this);
|
||||
|
||||
case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
|
||||
return radicalDegreeBottomRaisePercent;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SHORT percentScaleDown[2];
|
||||
USHORT minHeight[2];
|
||||
MathValueRecord mathValueRecords[51];
|
||||
SHORT radicalDegreeBottomRaisePercent;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (214);
|
||||
};
|
||||
|
||||
struct MathItalicsCorrectionInfo
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
coverage.sanitize (c, this) &&
|
||||
italicsCorrection.sanitize (c, this));
|
||||
}
|
||||
|
||||
inline hb_position_t get_value (hb_codepoint_t glyph,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph);
|
||||
return italicsCorrection[index].get_x_value (font, this);
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage> coverage; /* Offset to Coverage table -
|
||||
* from the beginning of
|
||||
* MathItalicsCorrectionInfo
|
||||
* table. */
|
||||
ArrayOf<MathValueRecord> italicsCorrection; /* Array of MathValueRecords
|
||||
* defining italics correction
|
||||
* values for each
|
||||
* covered glyph. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, italicsCorrection);
|
||||
};
|
||||
|
||||
struct MathTopAccentAttachment
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
topAccentCoverage.sanitize (c, this) &&
|
||||
topAccentAttachment.sanitize (c, this));
|
||||
}
|
||||
|
||||
inline hb_position_t get_value (hb_codepoint_t glyph,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
|
||||
if (index == NOT_COVERED)
|
||||
return font->get_glyph_h_advance (glyph) / 2;
|
||||
return topAccentAttachment[index].get_x_value(font, this);
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage> topAccentCoverage; /* Offset to Coverage table -
|
||||
* from the beginning of
|
||||
* MathTopAccentAttachment
|
||||
* table. */
|
||||
ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
|
||||
* defining top accent
|
||||
* attachment points for each
|
||||
* covered glyph. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2 + 2, topAccentAttachment);
|
||||
};
|
||||
|
||||
struct MathKern
|
||||
{
|
||||
inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
unsigned int count = 2 * heightCount + 1;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (mathValueRecords,
|
||||
mathValueRecords[0].static_size,
|
||||
2 * heightCount + 1) &&
|
||||
sanitize_math_value_records (c));
|
||||
}
|
||||
|
||||
inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
|
||||
{
|
||||
const MathValueRecord* correctionHeight = mathValueRecords;
|
||||
const MathValueRecord* kernValue = mathValueRecords + heightCount;
|
||||
int sign = font->y_scale < 0 ? -1 : +1;
|
||||
|
||||
/* The description of the MathKern table is a ambiguous, but interpreting
|
||||
* "between the two heights found at those indexes" for 0 < i < len as
|
||||
*
|
||||
* correctionHeight[i-1] < correction_height <= correctionHeight[i]
|
||||
*
|
||||
* makes the result consistent with the limit cases and we can just use the
|
||||
* binary search algorithm of std::upper_bound:
|
||||
*/
|
||||
unsigned int i = 0;
|
||||
unsigned int count = heightCount;
|
||||
while (count > 0)
|
||||
{
|
||||
unsigned int half = count / 2;
|
||||
hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
|
||||
if (sign * height < sign * correction_height)
|
||||
{
|
||||
i += half + 1;
|
||||
count -= half + 1;
|
||||
} else
|
||||
count = half;
|
||||
}
|
||||
return kernValue[i].get_x_value(font, this);
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT heightCount;
|
||||
MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
|
||||
* which the kern value changes.
|
||||
* Sorted by the height value in
|
||||
* design units (heightCount entries),
|
||||
* Followed by:
|
||||
* Array of kern values corresponding
|
||||
* to heights. (heightCount+1 entries).
|
||||
*/
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, mathValueRecords);
|
||||
};
|
||||
|
||||
struct MathKernInfoRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
||||
unsigned int count = ARRAY_LENGTH (mathKern);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!mathKern[i].sanitize (c, base)))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
inline hb_position_t get_kerning (hb_ot_math_kern_t kern,
|
||||
hb_position_t correction_height,
|
||||
hb_font_t *font,
|
||||
const void *base) const
|
||||
{
|
||||
unsigned int idx = kern;
|
||||
if (unlikely (idx >= ARRAY_LENGTH (mathKern))) return 0;
|
||||
return (base+mathKern[idx]).get_value (correction_height, font);
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Offset to MathKern table for each corner -
|
||||
* from the beginning of MathKernInfo table. May be NULL. */
|
||||
OffsetTo<MathKern> mathKern[4];
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct MathKernInfo
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
mathKernCoverage.sanitize (c, this) &&
|
||||
mathKernInfoRecords.sanitize (c, this));
|
||||
}
|
||||
|
||||
inline hb_position_t get_kerning (hb_codepoint_t glyph,
|
||||
hb_ot_math_kern_t kern,
|
||||
hb_position_t correction_height,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
|
||||
return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<Coverage> mathKernCoverage; /* Offset to Coverage table -
|
||||
* from the beginning of the
|
||||
* MathKernInfo table. */
|
||||
ArrayOf<MathKernInfoRecord> mathKernInfoRecords; /* Array of
|
||||
* MathKernInfoRecords,
|
||||
* per-glyph information for
|
||||
* mathematical positioning
|
||||
* of subscripts and
|
||||
* superscripts. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, mathKernInfoRecords);
|
||||
};
|
||||
|
||||
struct MathGlyphInfo
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
mathItalicsCorrectionInfo.sanitize (c, this) &&
|
||||
mathTopAccentAttachment.sanitize (c, this) &&
|
||||
extendedShapeCoverage.sanitize (c, this) &&
|
||||
mathKernInfo.sanitize(c, this));
|
||||
}
|
||||
|
||||
inline hb_position_t
|
||||
get_italics_correction (hb_codepoint_t glyph, hb_font_t *font) const
|
||||
{ return (this+mathItalicsCorrectionInfo).get_value (glyph, font); }
|
||||
|
||||
inline hb_position_t
|
||||
get_top_accent_attachment (hb_codepoint_t glyph, hb_font_t *font) const
|
||||
{ return (this+mathTopAccentAttachment).get_value (glyph, font); }
|
||||
|
||||
inline bool is_extended_shape (hb_codepoint_t glyph) const
|
||||
{ return (this+extendedShapeCoverage).get_coverage (glyph) != NOT_COVERED; }
|
||||
|
||||
inline hb_position_t get_kerning (hb_codepoint_t glyph,
|
||||
hb_ot_math_kern_t kern,
|
||||
hb_position_t correction_height,
|
||||
hb_font_t *font) const
|
||||
{ return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
|
||||
|
||||
protected:
|
||||
/* Offset to MathItalicsCorrectionInfo table -
|
||||
* from the beginning of MathGlyphInfo table. */
|
||||
OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
|
||||
|
||||
/* Offset to MathTopAccentAttachment table -
|
||||
* from the beginning of MathGlyphInfo table. */
|
||||
OffsetTo<MathTopAccentAttachment> mathTopAccentAttachment;
|
||||
|
||||
/* Offset to coverage table for Extended Shape glyphs -
|
||||
* from the beginning of MathGlyphInfo table. When the left or right glyph of
|
||||
* a box is an extended shape variant, the (ink) box (and not the default
|
||||
* position defined by values in MathConstants table) should be used for
|
||||
* vertical positioning purposes. May be NULL.. */
|
||||
OffsetTo<Coverage> extendedShapeCoverage;
|
||||
|
||||
/* Offset to MathKernInfo table -
|
||||
* from the beginning of MathGlyphInfo table. */
|
||||
OffsetTo<MathKernInfo> mathKernInfo;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct MathGlyphVariantRecord
|
||||
{
|
||||
friend struct MathGlyphConstruction;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID variantGlyph; /* Glyph ID for the variant. */
|
||||
USHORT advanceMeasurement; /* Advance width/height, in design units, of the
|
||||
* variant, in the direction of requested
|
||||
* glyph extension. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct PartFlags : USHORT
|
||||
{
|
||||
enum Flags {
|
||||
Extender = 0x0001u, /* If set, the part can be skipped or repeated. */
|
||||
|
||||
Defined = 0x0001u, /* All defined flags. */
|
||||
};
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (2);
|
||||
};
|
||||
|
||||
struct MathGlyphPartRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
inline void extract (hb_ot_math_glyph_part_t &out,
|
||||
int scale,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
out.glyph = glyph;
|
||||
|
||||
out.start_connector_length = font->em_scale (startConnectorLength, scale);
|
||||
out.end_connector_length = font->em_scale (endConnectorLength, scale);
|
||||
out.full_advance = font->em_scale (fullAdvance, scale);
|
||||
|
||||
ASSERT_STATIC ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER ==
|
||||
(unsigned int) PartFlags::Extender);
|
||||
|
||||
out.flags = (hb_ot_math_glyph_part_flags_t)
|
||||
(unsigned int)
|
||||
(partFlags & PartFlags::Defined);
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID glyph; /* Glyph ID for the part. */
|
||||
USHORT startConnectorLength; /* Advance width/ height of the straight bar
|
||||
* connector material, in design units, is at
|
||||
* the beginning of the glyph, in the
|
||||
* direction of the extension. */
|
||||
USHORT endConnectorLength; /* Advance width/ height of the straight bar
|
||||
* connector material, in design units, is at
|
||||
* the end of the glyph, in the direction of
|
||||
* the extension. */
|
||||
USHORT fullAdvance; /* Full advance width/height for this part,
|
||||
* in the direction of the extension.
|
||||
* In design units. */
|
||||
PartFlags partFlags; /* Part qualifiers. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
struct MathGlyphAssembly
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
italicsCorrection.sanitize(c, this) &&
|
||||
partRecords.sanitize(c));
|
||||
}
|
||||
|
||||
inline unsigned int get_parts (hb_direction_t direction,
|
||||
hb_font_t *font,
|
||||
unsigned int start_offset,
|
||||
unsigned int *parts_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_part_t *parts /* OUT */,
|
||||
hb_position_t *italics_correction /* OUT */) const
|
||||
{
|
||||
if (parts_count)
|
||||
{
|
||||
int scale = font->dir_scale (direction);
|
||||
const MathGlyphPartRecord *arr =
|
||||
partRecords.sub_array (start_offset, parts_count);
|
||||
unsigned int count = *parts_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
arr[i].extract (parts[i], scale, font);
|
||||
}
|
||||
|
||||
if (italics_correction)
|
||||
*italics_correction = italicsCorrection.get_x_value (font, this);
|
||||
|
||||
return partRecords.len;
|
||||
}
|
||||
|
||||
protected:
|
||||
MathValueRecord italicsCorrection; /* Italics correction of this
|
||||
* MathGlyphAssembly. Should not
|
||||
* depend on the assembly size. */
|
||||
ArrayOf<MathGlyphPartRecord> partRecords; /* Array of part records, from
|
||||
* left to right and bottom to
|
||||
* top. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, partRecords);
|
||||
};
|
||||
|
||||
struct MathGlyphConstruction
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
glyphAssembly.sanitize(c, this) &&
|
||||
mathGlyphVariantRecord.sanitize(c));
|
||||
}
|
||||
|
||||
inline const MathGlyphAssembly &get_assembly (void) const
|
||||
{ return this+glyphAssembly; }
|
||||
|
||||
inline unsigned int get_variants (hb_direction_t direction,
|
||||
hb_font_t *font,
|
||||
unsigned int start_offset,
|
||||
unsigned int *variants_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_variant_t *variants /* OUT */) const
|
||||
{
|
||||
if (variants_count)
|
||||
{
|
||||
int scale = font->dir_scale (direction);
|
||||
const MathGlyphVariantRecord *arr =
|
||||
mathGlyphVariantRecord.sub_array (start_offset, variants_count);
|
||||
unsigned int count = *variants_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
variants[i].glyph = arr[i].variantGlyph;
|
||||
variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
|
||||
}
|
||||
}
|
||||
return mathGlyphVariantRecord.len;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Offset to MathGlyphAssembly table for this shape - from the beginning of
|
||||
MathGlyphConstruction table. May be NULL. */
|
||||
OffsetTo<MathGlyphAssembly> glyphAssembly;
|
||||
|
||||
/* MathGlyphVariantRecords for alternative variants of the glyphs. */
|
||||
ArrayOf<MathGlyphVariantRecord> mathGlyphVariantRecord;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord);
|
||||
};
|
||||
|
||||
struct MathVariants
|
||||
{
|
||||
inline bool sanitize_offsets (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
unsigned int count = vertGlyphCount + horizGlyphCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
vertGlyphCoverage.sanitize (c, this) &&
|
||||
horizGlyphCoverage.sanitize (c, this) &&
|
||||
c->check_array (glyphConstruction,
|
||||
glyphConstruction[0].static_size,
|
||||
vertGlyphCount + horizGlyphCount) &&
|
||||
sanitize_offsets (c));
|
||||
}
|
||||
|
||||
inline hb_position_t get_min_connector_overlap (hb_direction_t direction,
|
||||
hb_font_t *font) const
|
||||
{ return font->em_scale_dir (minConnectorOverlap, direction); }
|
||||
|
||||
inline unsigned int get_glyph_variants (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_font_t *font,
|
||||
unsigned int start_offset,
|
||||
unsigned int *variants_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_variant_t *variants /* OUT */) const
|
||||
{ return get_glyph_construction (glyph, direction, font)
|
||||
.get_variants (direction, font, start_offset, variants_count, variants); }
|
||||
|
||||
inline unsigned int get_glyph_parts (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_font_t *font,
|
||||
unsigned int start_offset,
|
||||
unsigned int *parts_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_part_t *parts /* OUT */,
|
||||
hb_position_t *italics_correction /* OUT */) const
|
||||
{ return get_glyph_construction (glyph, direction, font)
|
||||
.get_assembly ()
|
||||
.get_parts (direction, font,
|
||||
start_offset, parts_count, parts,
|
||||
italics_correction); }
|
||||
|
||||
private:
|
||||
inline const MathGlyphConstruction &
|
||||
get_glyph_construction (hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
hb_font_t *font) const
|
||||
{
|
||||
bool vertical = HB_DIRECTION_IS_VERTICAL (direction);
|
||||
unsigned int count = vertical ? vertGlyphCount : horizGlyphCount;
|
||||
const OffsetTo<Coverage> &coverage = vertical ? vertGlyphCoverage
|
||||
: horizGlyphCoverage;
|
||||
|
||||
unsigned int index = (this+coverage).get_coverage (glyph);
|
||||
if (unlikely (index >= count)) return Null(MathGlyphConstruction);
|
||||
|
||||
if (!vertical)
|
||||
index += vertGlyphCount;
|
||||
|
||||
return this+glyphConstruction[index];
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT minConnectorOverlap; /* Minimum overlap of connecting
|
||||
* glyphs during glyph construction,
|
||||
* in design units. */
|
||||
OffsetTo<Coverage> vertGlyphCoverage; /* Offset to Coverage table -
|
||||
* from the beginning of MathVariants
|
||||
* table. */
|
||||
OffsetTo<Coverage> horizGlyphCoverage; /* Offset to Coverage table -
|
||||
* from the beginning of MathVariants
|
||||
* table. */
|
||||
USHORT vertGlyphCount; /* Number of glyphs for which
|
||||
* information is provided for
|
||||
* vertically growing variants. */
|
||||
USHORT horizGlyphCount; /* Number of glyphs for which
|
||||
* information is provided for
|
||||
* horizontally growing variants. */
|
||||
|
||||
/* Array of offsets to MathGlyphConstruction tables - from the beginning of
|
||||
the MathVariants table, for shapes growing in vertical/horizontal
|
||||
direction. */
|
||||
OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (10, glyphConstruction);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MATH -- The MATH Table
|
||||
*/
|
||||
|
||||
struct MATH
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_MATH;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
mathConstants.sanitize (c, this) &&
|
||||
mathGlyphInfo.sanitize (c, this) &&
|
||||
mathVariants.sanitize (c, this));
|
||||
}
|
||||
|
||||
inline hb_position_t get_constant (hb_ot_math_constant_t constant,
|
||||
hb_font_t *font) const
|
||||
{ return (this+mathConstants).get_value (constant, font); }
|
||||
|
||||
inline const MathGlyphInfo &get_math_glyph_info (void) const
|
||||
{ return this+mathGlyphInfo; }
|
||||
|
||||
inline const MathVariants &get_math_variants (void) const
|
||||
{ return this+mathVariants; }
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the MATH table
|
||||
* initially set to 0x00010000u */
|
||||
OffsetTo<MathConstants> mathConstants;/* MathConstants table */
|
||||
OffsetTo<MathGlyphInfo> mathGlyphInfo;/* MathGlyphInfo table */
|
||||
OffsetTo<MathVariants> mathVariants; /* MathVariants table */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
} /* mathspace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_MATH_TABLE_HH */
|
||||
621
gfx/harfbuzz/src/hb-ot-layout-private.hh
Normal file
621
gfx/harfbuzz/src/hb-ot-layout-private.hh
Normal file
|
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2012,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_LAYOUT_PRIVATE_HH
|
||||
#define HB_OT_LAYOUT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
/* Private API corresponding to hb-ot-layout.h: */
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
hb_ot_layout_table_find_feature (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_tag_t feature_tag,
|
||||
unsigned int *feature_index);
|
||||
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
enum hb_ot_layout_glyph_props_flags_t
|
||||
{
|
||||
/* The following three match LookupFlags::Ignore* numbers. */
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u,
|
||||
|
||||
/* The following are used internally; not derived from GDEF. */
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u,
|
||||
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t);
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS
|
||||
*/
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context);
|
||||
|
||||
|
||||
/* Should be called before all the substitute_lookup's are done. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_start (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
struct hb_ot_layout_lookup_accelerator_t;
|
||||
|
||||
namespace OT {
|
||||
struct hb_apply_context_t;
|
||||
struct SubstLookup;
|
||||
}
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
|
||||
const OT::SubstLookup &lookup,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel);
|
||||
|
||||
|
||||
/* Should be called before all the position_lookup's are done. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_position_start (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
/* Should be called after all the position_lookup's are done, to finish advances. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_position_finish_advances (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */
|
||||
HB_INTERNAL void
|
||||
hb_ot_layout_position_finish_offsets (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hb_ot_layout_t
|
||||
*/
|
||||
|
||||
namespace OT {
|
||||
struct GDEF;
|
||||
struct GSUB;
|
||||
struct GPOS;
|
||||
struct MATH;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct hb_ot_layout_t
|
||||
{
|
||||
hb_blob_t *gdef_blob;
|
||||
hb_blob_t *gsub_blob;
|
||||
hb_blob_t *gpos_blob;
|
||||
hb_blob_t *math_blob;
|
||||
|
||||
const struct OT::GDEF *gdef;
|
||||
const struct OT::GSUB *gsub;
|
||||
const struct OT::GPOS *gpos;
|
||||
const struct OT::MATH *math;
|
||||
|
||||
unsigned int gsub_lookup_count;
|
||||
unsigned int gpos_lookup_count;
|
||||
|
||||
hb_ot_layout_lookup_accelerator_t *gsub_accels;
|
||||
hb_ot_layout_lookup_accelerator_t *gpos_accels;
|
||||
};
|
||||
|
||||
|
||||
HB_INTERNAL hb_ot_layout_t *
|
||||
_hb_ot_layout_create (hb_face_t *face);
|
||||
|
||||
HB_INTERNAL void
|
||||
_hb_ot_layout_destroy (hb_ot_layout_t *layout);
|
||||
|
||||
|
||||
#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
|
||||
|
||||
|
||||
/*
|
||||
* Buffer var routines.
|
||||
*/
|
||||
|
||||
/* buffer var allocations, used during the entire shaping process */
|
||||
#define unicode_props() var2.u16[0]
|
||||
|
||||
/* buffer var allocations, used during the GSUB/GPOS processing */
|
||||
#define glyph_props() var1.u16[0] /* GDEF glyph properties */
|
||||
#define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */
|
||||
#define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */
|
||||
|
||||
|
||||
/* loop over syllables */
|
||||
|
||||
#define foreach_syllable(buffer, start, end) \
|
||||
for (unsigned int \
|
||||
_count = buffer->len, \
|
||||
start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
|
||||
start < _count; \
|
||||
start = end, end = _next_syllable (buffer, start))
|
||||
|
||||
static inline unsigned int
|
||||
_next_syllable (hb_buffer_t *buffer, unsigned int start)
|
||||
{
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
unsigned int syllable = info[start].syllable();
|
||||
while (++start < count && syllable == info[start].syllable())
|
||||
;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
/* unicode_props */
|
||||
|
||||
/* Design:
|
||||
* unicode_props() is a two-byte number. The low byte includes:
|
||||
* - General_Category: 5 bits.
|
||||
* - A bit each for:
|
||||
* * Is it Default_Ignorable(); we have a modified Default_Ignorable().
|
||||
* * Whether it's one of the three Mongolian Free Variation Selectors.
|
||||
* * One free bit right now.
|
||||
*
|
||||
* The high-byte has different meanings, switched by the Gen-Cat:
|
||||
* - For Mn,Mc,Me: the modified Combining_Class.
|
||||
* - For Cf: whether it's ZWJ, ZWNJ, or something else.
|
||||
* - For Ws: index of which space character this is, if space fallback
|
||||
* is needed, ie. we don't set this by default, only if asked to.
|
||||
*/
|
||||
|
||||
enum hb_unicode_props_flags_t {
|
||||
UPROPS_MASK_GEN_CAT = 0x001Fu,
|
||||
UPROPS_MASK_IGNORABLE = 0x0020u,
|
||||
UPROPS_MASK_FVS = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3 */
|
||||
|
||||
/* If GEN_CAT=FORMAT, top byte masks: */
|
||||
UPROPS_MASK_Cf_ZWJ = 0x0100u,
|
||||
UPROPS_MASK_Cf_ZWNJ = 0x0200u
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t);
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
|
||||
{
|
||||
hb_unicode_funcs_t *unicode = buffer->unicode;
|
||||
unsigned int u = info->codepoint;
|
||||
unsigned int gen_cat = (unsigned int) unicode->general_category (u);
|
||||
unsigned int props = gen_cat;
|
||||
|
||||
if (u >= 0x80)
|
||||
{
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
|
||||
if (unlikely (unicode->is_default_ignorable (u)))
|
||||
{
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
|
||||
props |= UPROPS_MASK_IGNORABLE;
|
||||
if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
|
||||
if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
|
||||
/* Mongolian Free Variation Selectors need to be remembered
|
||||
* because although we need to hide them like default-ignorables,
|
||||
* they need to non-ignorable during shaping. This is similar to
|
||||
* what we do for joiners in Indic-like shapers, but since the
|
||||
* FVSes are GC=Mn, we have use a separate bit to remember them.
|
||||
* Fixes:
|
||||
* https://github.com/behdad/harfbuzz/issues/234
|
||||
*/
|
||||
if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_FVS;
|
||||
}
|
||||
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
|
||||
{
|
||||
/* The above check is just an optimization to let in only things we need further
|
||||
* processing on. */
|
||||
|
||||
/* Only Mn and Mc can have non-zero ccc:
|
||||
* http://www.unicode.org/policies/stability_policy.html#Property_Value
|
||||
* """
|
||||
* Canonical_Combining_Class, General_Category
|
||||
* All characters other than those with General_Category property values
|
||||
* Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class
|
||||
* property value 0.
|
||||
* 1.1.5+
|
||||
* """
|
||||
*
|
||||
* Also, all Mn's that are Default_Ignorable, have ccc=0, hence
|
||||
* the "else if".
|
||||
*/
|
||||
props |= unicode->modified_combining_class (info->codepoint)<<8;
|
||||
|
||||
/* Recategorize emoji skin-tone modifiers as Unicode mark, so they
|
||||
* behave correctly in non-native directionality. They originally
|
||||
* are MODIFIER_SYMBOL. Fixes:
|
||||
* https://github.com/behdad/harfbuzz/issues/169
|
||||
*/
|
||||
if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
|
||||
{
|
||||
props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->unicode_props() = props;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
|
||||
hb_unicode_general_category_t gen_cat)
|
||||
{
|
||||
/* Clears top-byte. */
|
||||
info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xFF & ~UPROPS_MASK_GEN_CAT));
|
||||
}
|
||||
|
||||
static inline hb_unicode_general_category_t
|
||||
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
|
||||
{
|
||||
return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info)
|
||||
{
|
||||
return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MASK_GEN_CAT);
|
||||
}
|
||||
static inline void
|
||||
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
|
||||
unsigned int modified_class)
|
||||
{
|
||||
if (unlikely (!_hb_glyph_info_is_unicode_mark (info)))
|
||||
return;
|
||||
info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF);
|
||||
}
|
||||
static inline unsigned int
|
||||
_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;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_get_general_category (info) ==
|
||||
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
|
||||
}
|
||||
static inline void
|
||||
_hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s)
|
||||
{
|
||||
if (unlikely (!_hb_glyph_info_is_unicode_space (info)))
|
||||
return;
|
||||
info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF);
|
||||
}
|
||||
static inline hb_unicode_funcs_t::space_t
|
||||
_hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_is_unicode_space (info) ?
|
||||
(hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) :
|
||||
hb_unicode_funcs_t::NOT_SPACE;
|
||||
}
|
||||
|
||||
static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
||||
{
|
||||
return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
|
||||
!_hb_glyph_info_ligated (info);
|
||||
}
|
||||
static inline hb_bool_t
|
||||
_hb_glyph_info_is_default_ignorable_and_not_fvs (const hb_glyph_info_t *info)
|
||||
{
|
||||
return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_FVS))
|
||||
== UPROPS_MASK_IGNORABLE) &&
|
||||
!_hb_glyph_info_ligated (info);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_get_general_category (info) ==
|
||||
HB_UNICODE_GENERAL_CATEGORY_FORMAT;
|
||||
}
|
||||
static inline hb_bool_t
|
||||
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ);
|
||||
}
|
||||
static inline hb_bool_t
|
||||
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ);
|
||||
}
|
||||
static inline hb_bool_t
|
||||
_hb_glyph_info_is_joiner (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ));
|
||||
}
|
||||
static inline void
|
||||
_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
|
||||
{
|
||||
if (!_hb_glyph_info_is_unicode_format (info))
|
||||
return;
|
||||
info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ;
|
||||
}
|
||||
|
||||
/* lig_props: aka lig_id / lig_comp
|
||||
*
|
||||
* When a ligature is formed:
|
||||
*
|
||||
* - The ligature glyph and any marks in between all the same newly allocated
|
||||
* lig_id,
|
||||
* - The ligature glyph will get lig_num_comps set to the number of components
|
||||
* - The marks get lig_comp > 0, reflecting which component of the ligature
|
||||
* they were applied to.
|
||||
* - This is used in GPOS to attach marks to the right component of a ligature
|
||||
* in MarkLigPos,
|
||||
* - Note that when marks are ligated together, much of the above is skipped
|
||||
* and the current lig_id reused.
|
||||
*
|
||||
* When a multiple-substitution is done:
|
||||
*
|
||||
* - All resulting glyphs will have lig_id = 0,
|
||||
* - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
|
||||
* - This is used in GPOS to attach marks to the first component of a
|
||||
* multiple substitution in MarkBasePos.
|
||||
*
|
||||
* The numbers are also used in GPOS to do mark-to-mark positioning only
|
||||
* to marks that belong to the same component of the same ligature.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
|
||||
{
|
||||
info->lig_props() = 0;
|
||||
}
|
||||
|
||||
#define IS_LIG_BASE 0x10
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
|
||||
unsigned int lig_id,
|
||||
unsigned int lig_num_comps)
|
||||
{
|
||||
info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
|
||||
unsigned int lig_id,
|
||||
unsigned int lig_comp)
|
||||
{
|
||||
info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
|
||||
{
|
||||
_hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->lig_props() >> 5;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->lig_props() & IS_LIG_BASE);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
|
||||
{
|
||||
if (_hb_glyph_info_ligated_internal (info))
|
||||
return 0;
|
||||
else
|
||||
return info->lig_props() & 0x0F;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
|
||||
{
|
||||
if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
|
||||
_hb_glyph_info_ligated_internal (info))
|
||||
return info->lig_props() & 0x0F;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
_hb_allocate_lig_id (hb_buffer_t *buffer) {
|
||||
uint8_t lig_id = buffer->next_serial () & 0x07;
|
||||
if (unlikely (!lig_id))
|
||||
lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
/* glyph_props: */
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
|
||||
{
|
||||
info->glyph_props() = props;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->glyph_props();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_substituted (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_multiplied (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated_and_didnt_multiply (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_ligated (info) && !_hb_glyph_info_multiplied (info);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
|
||||
{
|
||||
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
|
||||
{
|
||||
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
|
||||
}
|
||||
|
||||
|
||||
/* Allocation / deallocation. */
|
||||
|
||||
static inline void
|
||||
_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_ASSERT_VAR (buffer, unicode_props);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
|
||||
HB_BUFFER_ASSERT_VAR (buffer, lig_props);
|
||||
HB_BUFFER_ASSERT_VAR (buffer, syllable);
|
||||
}
|
||||
|
||||
/* Make sure no one directly touches our props... */
|
||||
#undef unicode_props0
|
||||
#undef unicode_props1
|
||||
#undef lig_props
|
||||
#undef glyph_props
|
||||
|
||||
|
||||
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
|
||||
1237
gfx/harfbuzz/src/hb-ot-layout.cc
Normal file
1237
gfx/harfbuzz/src/hb-ot-layout.cc
Normal file
File diff suppressed because it is too large
Load diff
321
gfx/harfbuzz/src/hb-ot-layout.h
Normal file
321
gfx/harfbuzz/src/hb-ot-layout.h
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_LAYOUT_H
|
||||
#define HB_OT_LAYOUT_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include "hb-ot-tag.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#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')
|
||||
#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
|
||||
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_has_glyph_classes (hb_face_t *face);
|
||||
|
||||
typedef enum {
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 1,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 2,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_MARK = 3,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4
|
||||
} hb_ot_layout_glyph_class_t;
|
||||
|
||||
HB_EXTERN hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class (hb_face_t *face,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
|
||||
hb_ot_layout_glyph_class_t klass,
|
||||
hb_set_t *glyphs /* OUT */);
|
||||
|
||||
|
||||
/* Not that useful. Provides list of attach points for a glyph that a
|
||||
* client may want to cache */
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */);
|
||||
|
||||
/* Ligature caret positions */
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */);
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS feature query and enumeration interface
|
||||
*/
|
||||
|
||||
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu
|
||||
#define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu
|
||||
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu
|
||||
#define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *script_count /* IN/OUT */,
|
||||
hb_tag_t *script_tags /* OUT */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_table_find_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_tag_t script_tag,
|
||||
unsigned int *script_index);
|
||||
|
||||
/* Like find_script, but takes zero-terminated array of scripts to test */
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_script_get_language_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *language_count /* IN/OUT */,
|
||||
hb_tag_t *language_tags /* OUT */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int *feature_index);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_language_get_required_feature (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int *feature_index,
|
||||
hb_tag_t *feature_tag);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
unsigned int *feature_indexes /* OUT */);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *feature_count /* IN/OUT */,
|
||||
hb_tag_t *feature_tags /* OUT */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_language_find_feature (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
hb_tag_t feature_tag,
|
||||
unsigned int *feature_index);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_feature_get_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int feature_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *lookup_count /* IN/OUT */,
|
||||
unsigned int *lookup_indexes /* OUT */);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_table_get_lookup_count (hb_face_t *face,
|
||||
hb_tag_t table_tag);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_collect_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *scripts,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs_before, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_input, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_after, /* OUT. May be NULL */
|
||||
hb_set_t *glyphs_output /* OUT. May be NULL */);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
typedef struct
|
||||
{
|
||||
const hb_codepoint_t *before,
|
||||
unsigned int before_length,
|
||||
const hb_codepoint_t *input,
|
||||
unsigned int input_length,
|
||||
const hb_codepoint_t *after,
|
||||
unsigned int after_length,
|
||||
} hb_ot_layout_glyph_sequence_t;
|
||||
|
||||
typedef hb_bool_t
|
||||
(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t *font,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
void *user_data);
|
||||
|
||||
HB_EXTERN void
|
||||
Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int lookup_index,
|
||||
hb_ot_layout_glyph_sequence_func_t callback,
|
||||
void *user_data);
|
||||
#endif
|
||||
|
||||
/* Variations support */
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_table_find_feature_variations (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const int *coords,
|
||||
unsigned int num_coords,
|
||||
unsigned int *variations_index /* out */);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int feature_index,
|
||||
unsigned int variations_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *lookup_count /* IN/OUT */,
|
||||
unsigned int *lookup_indexes /* OUT */);
|
||||
|
||||
|
||||
/*
|
||||
* GSUB
|
||||
*/
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_has_substitution (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
const hb_codepoint_t *glyphs,
|
||||
unsigned int glyphs_length,
|
||||
hb_bool_t zero_context);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs
|
||||
/*TODO , hb_bool_t inclusive */);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
/* Note: You better have GDEF when using this API, or marks won't do much. */
|
||||
HB_EXTERN hb_bool_t
|
||||
Xhb_ot_layout_lookup_substitute (hb_font_t *font,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
unsigned int out_size,
|
||||
hb_codepoint_t *glyphs_out, /* OUT */
|
||||
unsigned int *clusters_out, /* OUT */
|
||||
unsigned int *out_length /* OUT */);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* GPOS
|
||||
*/
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_has_positioning (hb_face_t *face);
|
||||
|
||||
#ifdef HB_NOT_IMPLEMENTED
|
||||
/* Note: You better have GDEF when using this API, or marks won't do much. */
|
||||
HB_EXTERN hb_bool_t
|
||||
Xhb_ot_layout_lookup_position (hb_font_t *font,
|
||||
unsigned int lookup_index,
|
||||
const hb_ot_layout_glyph_sequence_t *sequence,
|
||||
hb_glyph_position_t *positions /* IN / OUT */);
|
||||
#endif
|
||||
|
||||
/* Optical 'size' feature info. Returns true if found.
|
||||
* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_get_size_params (hb_face_t *face,
|
||||
unsigned int *design_size, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_id, /* OUT. May be NULL */
|
||||
unsigned int *subfamily_name_id, /* OUT. May be NULL */
|
||||
unsigned int *range_start, /* OUT. May be NULL */
|
||||
unsigned int *range_end /* OUT. May be NULL */);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_LAYOUT_H */
|
||||
239
gfx/harfbuzz/src/hb-ot-map-private.hh
Normal file
239
gfx/harfbuzz/src/hb-ot-map-private.hh
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_MAP_PRIVATE_HH
|
||||
#define HB_OT_MAP_PRIVATE_HH
|
||||
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
struct hb_ot_shape_plan_t;
|
||||
|
||||
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
|
||||
|
||||
struct hb_ot_map_t
|
||||
{
|
||||
friend struct hb_ot_map_builder_t;
|
||||
|
||||
public:
|
||||
|
||||
struct feature_map_t {
|
||||
hb_tag_t tag; /* should be first for our bsearch to work */
|
||||
unsigned int index[2]; /* GSUB/GPOS */
|
||||
unsigned int stage[2]; /* GSUB/GPOS */
|
||||
unsigned int shift;
|
||||
hb_mask_t mask;
|
||||
hb_mask_t _1_mask; /* mask for value=1, for quick access */
|
||||
unsigned int needs_fallback : 1;
|
||||
unsigned int auto_zwj : 1;
|
||||
|
||||
static int cmp (const feature_map_t *a, const feature_map_t *b)
|
||||
{ return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
|
||||
};
|
||||
|
||||
struct lookup_map_t {
|
||||
unsigned short index;
|
||||
unsigned short auto_zwj : 1;
|
||||
hb_mask_t mask;
|
||||
|
||||
static int cmp (const lookup_map_t *a, const lookup_map_t *b)
|
||||
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
|
||||
};
|
||||
|
||||
typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
struct stage_map_t {
|
||||
unsigned int last_lookup; /* Cumulative */
|
||||
pause_func_t pause_func;
|
||||
};
|
||||
|
||||
|
||||
hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
|
||||
|
||||
inline hb_mask_t get_global_mask (void) const { return global_mask; }
|
||||
|
||||
inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
if (shift) *shift = map ? map->shift : 0;
|
||||
return map ? map->mask : 0;
|
||||
}
|
||||
|
||||
inline bool needs_fallback (hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->needs_fallback : false;
|
||||
}
|
||||
|
||||
inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->_1_mask : 0;
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
|
||||
}
|
||||
|
||||
inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
|
||||
const feature_map_t *map = features.bsearch (&feature_tag);
|
||||
return map ? map->stage[table_index] : (unsigned int) -1;
|
||||
}
|
||||
|
||||
inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
|
||||
const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
|
||||
if (unlikely (stage == (unsigned int) -1)) {
|
||||
*plookups = NULL;
|
||||
*lookup_count = 0;
|
||||
return;
|
||||
}
|
||||
assert (stage <= stages[table_index].len);
|
||||
unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
|
||||
unsigned int end = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
|
||||
*plookups = &lookups[table_index][start];
|
||||
*lookup_count = end - start;
|
||||
}
|
||||
|
||||
HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
|
||||
template <typename Proxy>
|
||||
HB_INTERNAL inline void apply (const Proxy &proxy,
|
||||
const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
|
||||
|
||||
inline void finish (void) {
|
||||
features.finish ();
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
lookups[table_index].finish ();
|
||||
stages[table_index].finish ();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
hb_tag_t chosen_script[2];
|
||||
bool found_script[2];
|
||||
|
||||
private:
|
||||
|
||||
hb_mask_t global_mask;
|
||||
|
||||
hb_prealloced_array_t<feature_map_t, 8> features;
|
||||
hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
|
||||
hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
|
||||
};
|
||||
|
||||
enum hb_ot_map_feature_flags_t {
|
||||
F_NONE = 0x0000u,
|
||||
F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */
|
||||
F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
|
||||
F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */
|
||||
F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
|
||||
/* Macro version for where const is desired. */
|
||||
#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
|
||||
|
||||
|
||||
struct hb_ot_map_builder_t
|
||||
{
|
||||
public:
|
||||
|
||||
HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
|
||||
const hb_segment_properties_t *props_);
|
||||
|
||||
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags);
|
||||
|
||||
inline void add_global_bool_feature (hb_tag_t tag)
|
||||
{ add_feature (tag, 1, F_GLOBAL); }
|
||||
|
||||
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (0, pause_func); }
|
||||
inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (1, pause_func); }
|
||||
|
||||
HB_INTERNAL void compile (hb_ot_map_t &m,
|
||||
const int *coords,
|
||||
unsigned int num_coords);
|
||||
|
||||
inline void finish (void) {
|
||||
feature_infos.finish ();
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
stages[table_index].finish ();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HB_INTERNAL void add_lookups (hb_ot_map_t &m,
|
||||
hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj);
|
||||
|
||||
struct feature_info_t {
|
||||
hb_tag_t tag;
|
||||
unsigned int seq; /* sequence#, used for stable sorting only */
|
||||
unsigned int max_value;
|
||||
hb_ot_map_feature_flags_t flags;
|
||||
unsigned int default_value; /* for non-global features, what should the unset glyphs take */
|
||||
unsigned int stage[2]; /* GSUB/GPOS */
|
||||
|
||||
static int cmp (const feature_info_t *a, const feature_info_t *b)
|
||||
{ return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) :
|
||||
(a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); }
|
||||
};
|
||||
|
||||
struct stage_info_t {
|
||||
unsigned int index;
|
||||
hb_ot_map_t::pause_func_t pause_func;
|
||||
};
|
||||
|
||||
HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
|
||||
|
||||
public:
|
||||
|
||||
hb_face_t *face;
|
||||
hb_segment_properties_t props;
|
||||
|
||||
hb_tag_t chosen_script[2];
|
||||
bool found_script[2];
|
||||
unsigned int script_index[2], language_index[2];
|
||||
|
||||
private:
|
||||
|
||||
unsigned int current_stage[2]; /* GSUB/GPOS */
|
||||
hb_prealloced_array_t<feature_info_t, 32> feature_infos;
|
||||
hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* HB_OT_MAP_PRIVATE_HH */
|
||||
328
gfx/harfbuzz/src/hb-ot-map.cc
Normal file
328
gfx/harfbuzz/src/hb-ot-map.cc
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright © 2009,2010 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2013 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.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ot-map-private.hh"
|
||||
|
||||
#include "hb-ot-layout-private.hh"
|
||||
|
||||
|
||||
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
|
||||
{
|
||||
for (unsigned int i = 0; i < lookups[table_index].len; i++)
|
||||
hb_set_add (lookups_out, lookups[table_index][i].index);
|
||||
}
|
||||
|
||||
|
||||
hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
|
||||
const hb_segment_properties_t *props_)
|
||||
{
|
||||
memset (this, 0, sizeof (*this));
|
||||
|
||||
face = face_;
|
||||
props = *props_;
|
||||
|
||||
|
||||
/* Fetch script/language indices for GSUB/GPOS. We need these later to skip
|
||||
* features not available in either table and not waste precious bits for them. */
|
||||
|
||||
hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
|
||||
hb_tag_t language_tag;
|
||||
|
||||
hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
|
||||
language_tag = hb_ot_tag_from_language (props.language);
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
||||
hb_tag_t table_tag = table_tags[table_index];
|
||||
found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
|
||||
hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
|
||||
}
|
||||
}
|
||||
|
||||
void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags)
|
||||
{
|
||||
feature_info_t *info = feature_infos.push();
|
||||
if (unlikely (!info)) return;
|
||||
if (unlikely (!tag)) return;
|
||||
info->tag = tag;
|
||||
info->seq = feature_infos.len;
|
||||
info->max_value = value;
|
||||
info->flags = flags;
|
||||
info->default_value = (flags & F_GLOBAL) ? value : 0;
|
||||
info->stage[0] = current_stage[0];
|
||||
info->stage[1] = current_stage[1];
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
|
||||
hb_face_t *face,
|
||||
unsigned int table_index,
|
||||
unsigned int feature_index,
|
||||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwj)
|
||||
{
|
||||
unsigned int lookup_indices[32];
|
||||
unsigned int offset, len;
|
||||
unsigned int table_lookup_count;
|
||||
|
||||
table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]);
|
||||
|
||||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (lookup_indices);
|
||||
hb_ot_layout_feature_with_variations_get_lookups (face,
|
||||
table_tags[table_index],
|
||||
feature_index,
|
||||
variations_index,
|
||||
offset, &len,
|
||||
lookup_indices);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
if (lookup_indices[i] >= table_lookup_count)
|
||||
continue;
|
||||
hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push ();
|
||||
if (unlikely (!lookup))
|
||||
return;
|
||||
lookup->mask = mask;
|
||||
lookup->index = lookup_indices[i];
|
||||
lookup->auto_zwj = auto_zwj;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
} while (len == ARRAY_LENGTH (lookup_indices));
|
||||
}
|
||||
|
||||
|
||||
void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
|
||||
{
|
||||
stage_info_t *s = stages[table_index].push ();
|
||||
if (likely (s)) {
|
||||
s->index = current_stage[table_index];
|
||||
s->pause_func = pause_func;
|
||||
}
|
||||
|
||||
current_stage[table_index]++;
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||
const int *coords,
|
||||
unsigned int num_coords)
|
||||
{
|
||||
m.global_mask = 1;
|
||||
|
||||
unsigned int required_feature_index[2];
|
||||
hb_tag_t required_feature_tag[2];
|
||||
/* We default to applying required feature in stage 0. If the required
|
||||
* feature has a tag that is known to the shaper, we apply required feature
|
||||
* in the stage for that tag.
|
||||
*/
|
||||
unsigned int required_feature_stage[2] = {0, 0};
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
m.chosen_script[table_index] = chosen_script[table_index];
|
||||
m.found_script[table_index] = found_script[table_index];
|
||||
|
||||
hb_ot_layout_language_get_required_feature (face,
|
||||
table_tags[table_index],
|
||||
script_index[table_index],
|
||||
language_index[table_index],
|
||||
&required_feature_index[table_index],
|
||||
&required_feature_tag[table_index]);
|
||||
}
|
||||
|
||||
if (!feature_infos.len)
|
||||
return;
|
||||
|
||||
/* Sort features and merge duplicates */
|
||||
{
|
||||
feature_infos.qsort ();
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 1; i < feature_infos.len; i++)
|
||||
if (feature_infos[i].tag != feature_infos[j].tag)
|
||||
feature_infos[++j] = feature_infos[i];
|
||||
else {
|
||||
if (feature_infos[i].flags & F_GLOBAL) {
|
||||
feature_infos[j].flags |= F_GLOBAL;
|
||||
feature_infos[j].max_value = feature_infos[i].max_value;
|
||||
feature_infos[j].default_value = feature_infos[i].default_value;
|
||||
} else {
|
||||
feature_infos[j].flags &= ~F_GLOBAL;
|
||||
feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
|
||||
/* Inherit default_value from j */
|
||||
}
|
||||
feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
|
||||
feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
|
||||
feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
|
||||
}
|
||||
feature_infos.shrink (j + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Allocate bits now */
|
||||
unsigned int next_bit = 1;
|
||||
for (unsigned int i = 0; i < feature_infos.len; i++)
|
||||
{
|
||||
const feature_info_t *info = &feature_infos[i];
|
||||
|
||||
unsigned int bits_needed;
|
||||
|
||||
if ((info->flags & F_GLOBAL) && info->max_value == 1)
|
||||
/* Uses the global bit */
|
||||
bits_needed = 0;
|
||||
else
|
||||
/* Limit to 8 bits per feature. */
|
||||
bits_needed = MIN(8u, _hb_bit_storage (info->max_value));
|
||||
|
||||
if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
|
||||
continue; /* Feature disabled, or not enough bits. */
|
||||
|
||||
|
||||
hb_bool_t found = false;
|
||||
unsigned int feature_index[2];
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
if (required_feature_tag[table_index] == info->tag)
|
||||
required_feature_stage[table_index] = info->stage[table_index];
|
||||
|
||||
found |= hb_ot_layout_language_find_feature (face,
|
||||
table_tags[table_index],
|
||||
script_index[table_index],
|
||||
language_index[table_index],
|
||||
info->tag,
|
||||
&feature_index[table_index]);
|
||||
}
|
||||
if (!found && (info->flags & F_GLOBAL_SEARCH))
|
||||
{
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
found |= hb_ot_layout_table_find_feature (face,
|
||||
table_tags[table_index],
|
||||
info->tag,
|
||||
&feature_index[table_index]);
|
||||
}
|
||||
}
|
||||
if (!found && !(info->flags & F_HAS_FALLBACK))
|
||||
continue;
|
||||
|
||||
|
||||
hb_ot_map_t::feature_map_t *map = m.features.push ();
|
||||
if (unlikely (!map))
|
||||
break;
|
||||
|
||||
map->tag = info->tag;
|
||||
map->index[0] = feature_index[0];
|
||||
map->index[1] = feature_index[1];
|
||||
map->stage[0] = info->stage[0];
|
||||
map->stage[1] = info->stage[1];
|
||||
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
|
||||
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
|
||||
/* Uses the global bit */
|
||||
map->shift = 0;
|
||||
map->mask = 1;
|
||||
} else {
|
||||
map->shift = next_bit;
|
||||
map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit);
|
||||
next_bit += bits_needed;
|
||||
m.global_mask |= (info->default_value << map->shift) & map->mask;
|
||||
}
|
||||
map->_1_mask = (1u << map->shift) & map->mask;
|
||||
map->needs_fallback = !found;
|
||||
|
||||
}
|
||||
feature_infos.shrink (0); /* Done with these */
|
||||
|
||||
|
||||
add_gsub_pause (NULL);
|
||||
add_gpos_pause (NULL);
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||
{
|
||||
/* Collect lookup indices for features */
|
||||
|
||||
unsigned int variations_index;
|
||||
hb_ot_layout_table_find_feature_variations (face,
|
||||
table_tags[table_index],
|
||||
coords,
|
||||
num_coords,
|
||||
&variations_index);
|
||||
|
||||
unsigned int stage_index = 0;
|
||||
unsigned int last_num_lookups = 0;
|
||||
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
||||
{
|
||||
if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
|
||||
required_feature_stage[table_index] == stage)
|
||||
add_lookups (m, face, table_index,
|
||||
required_feature_index[table_index],
|
||||
variations_index,
|
||||
1 /* mask */,
|
||||
true /* auto_zwj */);
|
||||
|
||||
for (unsigned i = 0; i < m.features.len; i++)
|
||||
if (m.features[i].stage[table_index] == stage)
|
||||
add_lookups (m, face, table_index,
|
||||
m.features[i].index[table_index],
|
||||
variations_index,
|
||||
m.features[i].mask,
|
||||
m.features[i].auto_zwj);
|
||||
|
||||
/* Sort lookups and merge duplicates */
|
||||
if (last_num_lookups < m.lookups[table_index].len)
|
||||
{
|
||||
m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].len);
|
||||
|
||||
unsigned int j = last_num_lookups;
|
||||
for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
|
||||
if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
|
||||
m.lookups[table_index][++j] = m.lookups[table_index][i];
|
||||
else
|
||||
{
|
||||
m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
|
||||
m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
|
||||
}
|
||||
m.lookups[table_index].shrink (j + 1);
|
||||
}
|
||||
|
||||
last_num_lookups = m.lookups[table_index].len;
|
||||
|
||||
if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
|
||||
hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
|
||||
if (likely (stage_map)) {
|
||||
stage_map->last_lookup = last_num_lookups;
|
||||
stage_map->pause_func = stages[table_index][stage_index].pause_func;
|
||||
}
|
||||
|
||||
stage_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
272
gfx/harfbuzz/src/hb-ot-math.cc
Normal file
272
gfx/harfbuzz/src/hb-ot-math.cc
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright © 2016 Igalia S.L.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Igalia Author(s): Frédéric Wang
|
||||
*/
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
#include "hb-ot-layout-math-table.hh"
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
|
||||
|
||||
static inline const OT::MATH&
|
||||
_get_math (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH);
|
||||
|
||||
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
|
||||
|
||||
retry:
|
||||
const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math);
|
||||
|
||||
if (unlikely (!math))
|
||||
{
|
||||
hb_blob_t *blob = OT::Sanitizer<OT::MATH>::sanitize (face->reference_table (HB_OT_TAG_MATH));
|
||||
math = OT::Sanitizer<OT::MATH>::lock_instance (blob);
|
||||
if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math))
|
||||
{
|
||||
hb_blob_destroy (blob);
|
||||
goto retry;
|
||||
}
|
||||
layout->math_blob = blob;
|
||||
}
|
||||
|
||||
return *math;
|
||||
}
|
||||
|
||||
/*
|
||||
* OT::MATH
|
||||
*/
|
||||
|
||||
/**
|
||||
* hb_ot_math_has_data:
|
||||
* @face: #hb_face_t to test
|
||||
*
|
||||
* This function allows to verify the presence of an OpenType MATH table on the
|
||||
* face. If so, such a table will be loaded into memory and sanitized. You can
|
||||
* then safely call other functions for math layout and shaping.
|
||||
*
|
||||
* Return value: #TRUE if face has a MATH table and #FALSE otherwise
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_math_has_data (hb_face_t *face)
|
||||
{
|
||||
return &_get_math (face) != &OT::Null(OT::MATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_constant:
|
||||
* @font: #hb_font_t from which to retrieve the value
|
||||
* @constant: #hb_ot_math_constant_t the constant to retrieve
|
||||
*
|
||||
* This function returns the requested math constants as a #hb_position_t.
|
||||
* If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
|
||||
* HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
|
||||
* HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
|
||||
* actually an integer between 0 and 100 representing that percentage.
|
||||
*
|
||||
* Return value: the requested constant or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_math_get_constant (hb_font_t *font,
|
||||
hb_ot_math_constant_t constant)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_constant(constant, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_glyph_italics_correction:
|
||||
* @font: #hb_font_t from which to retrieve the value
|
||||
* @glyph: glyph index from which to retrieve the value
|
||||
*
|
||||
* Return value: the italics correction of the glyph or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_glyph_info().get_italics_correction (glyph, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_glyph_top_accent_attachment:
|
||||
* @font: #hb_font_t from which to retrieve the value
|
||||
* @glyph: glyph index from which to retrieve the value
|
||||
*
|
||||
* Return value: the top accent attachment of the glyph or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_glyph_info().get_top_accent_attachment (glyph, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_is_glyph_extended_shape:
|
||||
* @font: a #hb_font_t to test
|
||||
* @glyph: a glyph index to test
|
||||
*
|
||||
* Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
|
||||
hb_codepoint_t glyph)
|
||||
{
|
||||
const OT::MATH &math = _get_math (face);
|
||||
return math.get_math_glyph_info().is_extended_shape (glyph);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_glyph_kerning:
|
||||
* @font: #hb_font_t from which to retrieve the value
|
||||
* @glyph: glyph index from which to retrieve the value
|
||||
* @kern: the #hb_ot_math_kern_t from which to retrieve the value
|
||||
* @correction_height: the correction height to use to determine the kerning.
|
||||
*
|
||||
* This function tries to retrieve the MathKern table for the specified font,
|
||||
* glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
|
||||
* MathKern table to find one value that is greater or equal to specified
|
||||
* correction_height. If one is found the corresponding value from the list of
|
||||
* kerns is returned and otherwise the last kern value is returned.
|
||||
*
|
||||
* Return value: requested kerning or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_math_get_glyph_kerning (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_ot_math_kern_t kern,
|
||||
hb_position_t correction_height)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_glyph_variants:
|
||||
* @font: #hb_font_t from which to retrieve the values
|
||||
* @glyph: index of the glyph to stretch
|
||||
* @direction: direction of the stretching
|
||||
* @start_offset: offset of the first variant to retrieve
|
||||
* @variants_count: maximum number of variants to retrieve after start_offset
|
||||
* (IN) and actual number of variants retrieved (OUT)
|
||||
* @variants: array of size at least @variants_count to store the result
|
||||
*
|
||||
* This function tries to retrieve the MathGlyphConstruction for the specified
|
||||
* font, glyph and direction. Note that only the value of
|
||||
* #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
|
||||
* of size variants as an array of hb_ot_math_glyph_variant_t structs.
|
||||
*
|
||||
* Return value: the total number of size variants available or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_math_get_glyph_variants (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
unsigned int start_offset,
|
||||
unsigned int *variants_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_variant_t *variants /* OUT */)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_variants().get_glyph_variants (glyph, direction, font,
|
||||
start_offset,
|
||||
variants_count,
|
||||
variants);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_min_connector_overlap:
|
||||
* @font: #hb_font_t from which to retrieve the value
|
||||
* @direction: direction of the stretching
|
||||
*
|
||||
* This function tries to retrieve the MathVariants table for the specified
|
||||
* font and returns the minimum overlap of connecting glyphs to draw a glyph
|
||||
* assembly in the specified direction. Note that only the value of
|
||||
* #HB_DIRECTION_IS_HORIZONTAL is considered.
|
||||
*
|
||||
* Return value: requested min connector overlap or 0
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
|
||||
hb_direction_t direction)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_variants().get_min_connector_overlap (direction, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_math_get_glyph_assembly:
|
||||
* @font: #hb_font_t from which to retrieve the values
|
||||
* @glyph: index of the glyph to stretch
|
||||
* @direction: direction of the stretching
|
||||
* @start_offset: offset of the first glyph part to retrieve
|
||||
* @parts_count: maximum number of glyph parts to retrieve after start_offset
|
||||
* (IN) and actual number of parts retrieved (OUT)
|
||||
* @parts: array of size at least @parts_count to store the result
|
||||
* @italics_correction: italic correction of the glyph assembly
|
||||
*
|
||||
* This function tries to retrieve the GlyphAssembly for the specified font,
|
||||
* glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
|
||||
* is considered. It provides the information necessary to draw the glyph
|
||||
* assembly as an array of #hb_ot_math_glyph_part_t.
|
||||
*
|
||||
* Return value: the total number of parts in the glyph assembly
|
||||
*
|
||||
* Since: 1.3.3
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_math_get_glyph_assembly (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
unsigned int start_offset,
|
||||
unsigned int *parts_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_part_t *parts, /* OUT */
|
||||
hb_position_t *italics_correction /* OUT */)
|
||||
{
|
||||
const OT::MATH &math = _get_math (font->face);
|
||||
return math.get_math_variants().get_glyph_parts (glyph, direction, font,
|
||||
start_offset,
|
||||
parts_count,
|
||||
parts,
|
||||
italics_correction);
|
||||
}
|
||||
209
gfx/harfbuzz/src/hb-ot-math.h
Normal file
209
gfx/harfbuzz/src/hb-ot-math.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright © 2016 Igalia S.L.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Igalia Author(s): Frédéric Wang
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_MATH_H
|
||||
#define HB_OT_MATH_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* MATH
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_MATH HB_TAG('M','A','T','H')
|
||||
|
||||
/* Use with hb_buffer_set_script() for math shaping. */
|
||||
#define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h')
|
||||
|
||||
/* Types */
|
||||
|
||||
/**
|
||||
* hb_ot_math_constant_t:
|
||||
*
|
||||
* Since: 1.3.3
|
||||
*/
|
||||
typedef enum {
|
||||
HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN = 0,
|
||||
HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN = 1,
|
||||
HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT = 2,
|
||||
HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT = 3,
|
||||
HB_OT_MATH_CONSTANT_MATH_LEADING = 4,
|
||||
HB_OT_MATH_CONSTANT_AXIS_HEIGHT = 5,
|
||||
HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT = 6,
|
||||
HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT = 7,
|
||||
HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN = 8,
|
||||
HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX = 9,
|
||||
HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN = 10,
|
||||
HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP = 11,
|
||||
HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED = 12,
|
||||
HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN = 13,
|
||||
HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX = 14,
|
||||
HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN = 15,
|
||||
HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT = 16,
|
||||
HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT = 17,
|
||||
HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN = 18,
|
||||
HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN = 19,
|
||||
HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN = 20,
|
||||
HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN = 21,
|
||||
HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP = 22,
|
||||
HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP = 23,
|
||||
HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN = 24,
|
||||
HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN = 25,
|
||||
HB_OT_MATH_CONSTANT_STACK_GAP_MIN = 26,
|
||||
HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN = 27,
|
||||
HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP = 28,
|
||||
HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN = 29,
|
||||
HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN = 30,
|
||||
HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN = 31,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP = 32,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP = 33,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN = 34,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN = 35,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN = 36,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN = 37,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS = 38,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN = 39,
|
||||
HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN = 40,
|
||||
HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP = 41,
|
||||
HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP = 42,
|
||||
HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP = 43,
|
||||
HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS = 44,
|
||||
HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER = 45,
|
||||
HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP = 46,
|
||||
HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS = 47,
|
||||
HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER = 48,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP = 49,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP = 50,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS = 51,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER = 52,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE = 53,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE = 54,
|
||||
HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT = 55
|
||||
} hb_ot_math_constant_t;
|
||||
|
||||
/**
|
||||
* hb_ot_math_kern_t:
|
||||
*
|
||||
* Since: 1.3.3
|
||||
*/
|
||||
typedef enum {
|
||||
HB_OT_MATH_KERN_TOP_RIGHT = 0,
|
||||
HB_OT_MATH_KERN_TOP_LEFT = 1,
|
||||
HB_OT_MATH_KERN_BOTTOM_RIGHT = 2,
|
||||
HB_OT_MATH_KERN_BOTTOM_LEFT = 3
|
||||
} hb_ot_math_kern_t;
|
||||
|
||||
/**
|
||||
* hb_ot_math_glyph_variant_t:
|
||||
*
|
||||
* Since: 1.3.3
|
||||
*/
|
||||
typedef struct hb_ot_math_glyph_variant_t {
|
||||
hb_codepoint_t glyph;
|
||||
hb_position_t advance;
|
||||
} hb_ot_math_glyph_variant_t;
|
||||
|
||||
/**
|
||||
* hb_ot_math_glyph_part_flags_t:
|
||||
*
|
||||
* Since: 1.3.3
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
HB_MATH_GLYPH_PART_FLAG_EXTENDER = 0x00000001u /* Extender glyph */
|
||||
} hb_ot_math_glyph_part_flags_t;
|
||||
|
||||
/**
|
||||
* hb_ot_math_glyph_part_t:
|
||||
*
|
||||
* Since: 1.3.3
|
||||
*/
|
||||
typedef struct hb_ot_math_glyph_part_t {
|
||||
hb_codepoint_t glyph;
|
||||
hb_position_t start_connector_length;
|
||||
hb_position_t end_connector_length;
|
||||
hb_position_t full_advance;
|
||||
hb_ot_math_glyph_part_flags_t flags;
|
||||
} hb_ot_math_glyph_part_t;
|
||||
|
||||
/* Methods */
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_math_has_data (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_math_get_constant (hb_font_t *font,
|
||||
hb_ot_math_constant_t constant);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
|
||||
hb_codepoint_t glyph);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_math_get_glyph_kerning (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_ot_math_kern_t kern,
|
||||
hb_position_t correction_height);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_math_get_glyph_variants (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
unsigned int start_offset,
|
||||
unsigned int *variants_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_variant_t *variants /* OUT */);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
|
||||
hb_direction_t direction);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_math_get_glyph_assembly (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_direction_t direction,
|
||||
unsigned int start_offset,
|
||||
unsigned int *parts_count, /* IN/OUT */
|
||||
hb_ot_math_glyph_part_t *parts, /* OUT */
|
||||
hb_position_t *italics_correction /* OUT */);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_MATH_H */
|
||||
72
gfx/harfbuzz/src/hb-ot-maxp-table.hh
Normal file
72
gfx/harfbuzz/src/hb-ot-maxp-table.hh
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_MAXP_TABLE_HH
|
||||
#define HB_OT_MAXP_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* maxp -- The Maximum Profile Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
|
||||
|
||||
struct maxp
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_maxp;
|
||||
|
||||
inline unsigned int get_num_glyphs (void) const
|
||||
{
|
||||
return numGlyphs;
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
/* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
|
||||
* 0x00005000u or 0x00010000u. */
|
||||
USHORT numGlyphs; /* The number of glyphs in the font. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_MAXP_TABLE_HH */
|
||||
136
gfx/harfbuzz/src/hb-ot-name-table.hh
Normal file
136
gfx/harfbuzz/src/hb-ot-name-table.hh
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_NAME_TABLE_HH
|
||||
#define HB_OT_NAME_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* name -- The Naming Table
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_name HB_TAG('n','a','m','e')
|
||||
|
||||
|
||||
struct NameRecord
|
||||
{
|
||||
static int cmp (const NameRecord *a, const NameRecord *b)
|
||||
{
|
||||
int ret;
|
||||
ret = b->platformID.cmp (a->platformID);
|
||||
if (ret) return ret;
|
||||
ret = b->encodingID.cmp (a->encodingID);
|
||||
if (ret) return ret;
|
||||
ret = b->languageID.cmp (a->languageID);
|
||||
if (ret) return ret;
|
||||
ret = b->nameID.cmp (a->nameID);
|
||||
if (ret) return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* We can check from base all the way up to the end of string... */
|
||||
return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
|
||||
}
|
||||
|
||||
USHORT platformID; /* Platform ID. */
|
||||
USHORT encodingID; /* Platform-specific encoding ID. */
|
||||
USHORT languageID; /* Language ID. */
|
||||
USHORT nameID; /* Name ID. */
|
||||
USHORT length; /* String length (in bytes). */
|
||||
USHORT offset; /* String offset from start of storage area (in bytes). */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
struct name
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_name;
|
||||
|
||||
inline unsigned int get_name (unsigned int platform_id,
|
||||
unsigned int encoding_id,
|
||||
unsigned int language_id,
|
||||
unsigned int name_id,
|
||||
void *buffer,
|
||||
unsigned int buffer_length) const
|
||||
{
|
||||
NameRecord key;
|
||||
key.platformID.set (platform_id);
|
||||
key.encodingID.set (encoding_id);
|
||||
key.languageID.set (language_id);
|
||||
key.nameID.set (name_id);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
|
||||
|
||||
if (!match)
|
||||
return 0;
|
||||
|
||||
unsigned int length = MIN (buffer_length, (unsigned int) match->length);
|
||||
memcpy (buffer, (char *) this + stringOffset + match->offset, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
inline unsigned int get_size (void) const
|
||||
{ return min_size + count * nameRecord[0].min_size; }
|
||||
|
||||
inline bool sanitize_records (hb_sanitize_context_t *c) const {
|
||||
TRACE_SANITIZE (this);
|
||||
char *string_pool = (char *) this + stringOffset;
|
||||
unsigned int _count = count;
|
||||
for (unsigned int i = 0; i < _count; i++)
|
||||
if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (format == 0 || format == 1) &&
|
||||
c->check_array (nameRecord, nameRecord[0].static_size, count) &&
|
||||
sanitize_records (c));
|
||||
}
|
||||
|
||||
/* We only implement format 0 for now. */
|
||||
USHORT format; /* Format selector (=0/1). */
|
||||
USHORT count; /* Number of name records. */
|
||||
Offset<> stringOffset; /* Offset to start of string storage (from start of table). */
|
||||
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, nameRecord);
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_NAME_TABLE_HH */
|
||||
105
gfx/harfbuzz/src/hb-ot-os2-table.hh
Normal file
105
gfx/harfbuzz/src/hb-ot-os2-table.hh
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_OS2_TABLE_HH
|
||||
#define HB_OT_OS2_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
/*
|
||||
* OS/2 and Windows Metrics
|
||||
* http://www.microsoft.com/typography/otspec/os2.htm
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_os2 HB_TAG('O','S','/','2')
|
||||
|
||||
struct os2
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_os2;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
public:
|
||||
USHORT version;
|
||||
|
||||
/* Version 0 */
|
||||
SHORT xAvgCharWidth;
|
||||
USHORT usWeightClass;
|
||||
USHORT usWidthClass;
|
||||
USHORT fsType;
|
||||
SHORT ySubscriptXSize;
|
||||
SHORT ySubscriptYSize;
|
||||
SHORT ySubscriptXOffset;
|
||||
SHORT ySubscriptYOffset;
|
||||
SHORT ySuperscriptXSize;
|
||||
SHORT ySuperscriptYSize;
|
||||
SHORT ySuperscriptXOffset;
|
||||
SHORT ySuperscriptYOffset;
|
||||
SHORT yStrikeoutSize;
|
||||
SHORT yStrikeoutPosition;
|
||||
SHORT sFamilyClass;
|
||||
BYTE panose[10];
|
||||
ULONG ulUnicodeRange[4];
|
||||
Tag achVendID;
|
||||
USHORT fsSelection;
|
||||
USHORT usFirstCharIndex;
|
||||
USHORT usLastCharIndex;
|
||||
SHORT sTypoAscender;
|
||||
SHORT sTypoDescender;
|
||||
SHORT sTypoLineGap;
|
||||
USHORT usWinAscent;
|
||||
USHORT usWinDescent;
|
||||
|
||||
/* Version 1 */
|
||||
//ULONG ulCodePageRange1;
|
||||
//ULONG ulCodePageRange2;
|
||||
|
||||
/* Version 2 */
|
||||
//SHORT sxHeight;
|
||||
//SHORT sCapHeight;
|
||||
//USHORT usDefaultChar;
|
||||
//USHORT usBreakChar;
|
||||
//USHORT usMaxContext;
|
||||
|
||||
/* Version 5 */
|
||||
//USHORT usLowerOpticalPointSize;
|
||||
//USHORT usUpperOpticalPointSize;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (78);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_OS2_TABLE_HH */
|
||||
119
gfx/harfbuzz/src/hb-ot-post-table.hh
Normal file
119
gfx/harfbuzz/src/hb-ot-post-table.hh
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright © 2016 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_POST_TABLE_HH
|
||||
#define HB_OT_POST_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* post -- PostScript
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_post HB_TAG('p','o','s','t')
|
||||
|
||||
|
||||
struct postV2Tail
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (numberOfGlyphs.sanitize (c) &&
|
||||
c->check_array (glyphNameIndex, sizeof (USHORT), numberOfGlyphs));
|
||||
}
|
||||
|
||||
USHORT numberOfGlyphs; /* Number of glyphs (this should be the
|
||||
* same as numGlyphs in 'maxp' table). */
|
||||
USHORT glyphNameIndex[VAR]; /* This is not an offset, but is the
|
||||
* ordinal number of the glyph in 'post'
|
||||
* string tables. */
|
||||
BYTE namesX[VAR]; /* Glyph names with length bytes [variable]
|
||||
* (a Pascal string). */
|
||||
|
||||
DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
|
||||
};
|
||||
|
||||
struct post
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_post;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (this)))
|
||||
return_trace (false);
|
||||
if (version.to_int () == 0x00020000)
|
||||
{
|
||||
const postV2Tail &v2 = StructAfter<postV2Tail>(*this);
|
||||
return_trace (v2.sanitize (c));
|
||||
}
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
public:
|
||||
FixedVersion<>version; /* 0x00010000 for version 1.0
|
||||
* 0x00020000 for version 2.0
|
||||
* 0x00025000 for version 2.5 (deprecated)
|
||||
* 0x00030000 for version 3.0 */
|
||||
Fixed italicAngle; /* Italic angle in counter-clockwise degrees
|
||||
* from the vertical. Zero for upright text,
|
||||
* negative for text that leans to the right
|
||||
* (forward). */
|
||||
FWORD underlinePosition; /* This is the suggested distance of the top
|
||||
* of the underline from the baseline
|
||||
* (negative values indicate below baseline).
|
||||
* The PostScript definition of this FontInfo
|
||||
* dictionary key (the y coordinate of the
|
||||
* center of the stroke) is not used for
|
||||
* historical reasons. The value of the
|
||||
* PostScript key may be calculated by
|
||||
* subtracting half the underlineThickness
|
||||
* from the value of this field. */
|
||||
FWORD underlineThickness; /* Suggested values for the underline
|
||||
thickness. */
|
||||
ULONG isFixedPitch; /* Set to 0 if the font is proportionally
|
||||
* spaced, non-zero if the font is not
|
||||
* proportionally spaced (i.e. monospaced). */
|
||||
ULONG minMemType42; /* Minimum memory usage when an OpenType font
|
||||
* is downloaded. */
|
||||
ULONG maxMemType42; /* Maximum memory usage when an OpenType font
|
||||
* is downloaded. */
|
||||
ULONG minMemType1; /* Minimum memory usage when an OpenType font
|
||||
* is downloaded as a Type 1 font. */
|
||||
ULONG maxMemType1; /* Maximum memory usage when an OpenType font
|
||||
* is downloaded as a Type 1 font. */
|
||||
/*postV2Tail v2[VAR];*/
|
||||
DEFINE_SIZE_STATIC (32);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_POST_TABLE_HH */
|
||||
354
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh
Normal file
354
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright © 2012 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_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
|
||||
|
||||
/* Features ordered the same as the entries in shaping_table rows,
|
||||
* followed by rlig. Don't change. */
|
||||
static const hb_tag_t arabic_fallback_features[] =
|
||||
{
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
HB_TAG('i','s','o','l'),
|
||||
HB_TAG('r','l','i','g'),
|
||||
};
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
unsigned int num_glyphs = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++)
|
||||
{
|
||||
hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index];
|
||||
hb_codepoint_t u_glyph, s_glyph;
|
||||
|
||||
if (!s ||
|
||||
!hb_font_get_glyph (font, u, 0, &u_glyph) ||
|
||||
!hb_font_get_glyph (font, s, 0, &s_glyph) ||
|
||||
u_glyph == s_glyph ||
|
||||
u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
|
||||
continue;
|
||||
|
||||
glyphs[num_glyphs].set (u_glyph);
|
||||
substitutes[num_glyphs].set (s_glyph);
|
||||
|
||||
num_glyphs++;
|
||||
}
|
||||
|
||||
if (!num_glyphs)
|
||||
return NULL;
|
||||
|
||||
/* Bubble-sort or something equally good!
|
||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||
hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
|
||||
|
||||
OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
|
||||
OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
|
||||
|
||||
/* Each glyph takes four bytes max, and there's some overhead. */
|
||||
char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_single (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
glyphs_supplier,
|
||||
substitutes_supplier,
|
||||
num_glyphs);
|
||||
c.end_serialize ();
|
||||
/* TODO sanitize the results? */
|
||||
|
||||
return ret ? c.copy<OT::SubstLookup> () : NULL;
|
||||
}
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font)
|
||||
{
|
||||
OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
||||
unsigned int num_first_glyphs = 0;
|
||||
|
||||
/* We know that all our ligatures are 2-component */
|
||||
OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
||||
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
|
||||
OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
||||
unsigned int num_ligatures = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
|
||||
/* Sort out the first-glyphs */
|
||||
for (unsigned int first_glyph_idx = 0; first_glyph_idx < ARRAY_LENGTH (first_glyphs); first_glyph_idx++)
|
||||
{
|
||||
hb_codepoint_t first_u = ligature_table[first_glyph_idx].first;
|
||||
hb_codepoint_t first_glyph;
|
||||
if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
|
||||
continue;
|
||||
first_glyphs[num_first_glyphs].set (first_glyph);
|
||||
ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
|
||||
first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
|
||||
num_first_glyphs++;
|
||||
}
|
||||
hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
|
||||
|
||||
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
|
||||
for (unsigned int i = 0; i < num_first_glyphs; i++)
|
||||
{
|
||||
unsigned int first_glyph_idx = first_glyphs_indirection[i];
|
||||
|
||||
for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
|
||||
{
|
||||
hb_codepoint_t second_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
|
||||
hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
|
||||
hb_codepoint_t second_glyph, ligature_glyph;
|
||||
if (!second_u ||
|
||||
!hb_font_get_glyph (font, second_u, 0, &second_glyph) ||
|
||||
!hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
|
||||
continue;
|
||||
|
||||
ligature_per_first_glyph_count_list[i]++;
|
||||
|
||||
ligature_list[num_ligatures].set (ligature_glyph);
|
||||
component_count_list[num_ligatures] = 2;
|
||||
component_list[num_ligatures].set (second_glyph);
|
||||
num_ligatures++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_ligatures)
|
||||
return NULL;
|
||||
|
||||
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
||||
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
||||
OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
||||
OT::Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
|
||||
OT::Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
|
||||
|
||||
/* 16 bytes per ligature ought to be enough... */
|
||||
char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_ligature (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
first_glyphs_supplier,
|
||||
ligature_per_first_glyph_count_supplier,
|
||||
num_first_glyphs,
|
||||
ligatures_supplier,
|
||||
component_count_supplier,
|
||||
component_supplier);
|
||||
|
||||
c.end_serialize ();
|
||||
/* TODO sanitize the results? */
|
||||
|
||||
return ret ? c.copy<OT::SubstLookup> () : NULL;
|
||||
}
|
||||
|
||||
static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
if (feature_index < 4)
|
||||
return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
|
||||
else
|
||||
return arabic_fallback_synthesize_lookup_ligature (plan, font);
|
||||
}
|
||||
|
||||
#define ARABIC_FALLBACK_MAX_LOOKUPS 5
|
||||
|
||||
struct arabic_fallback_plan_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
unsigned int num_lookups;
|
||||
bool free_lookups;
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
|
||||
|
||||
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
|
||||
#define HB_WITH_WIN1256
|
||||
#endif
|
||||
|
||||
#ifdef HB_WITH_WIN1256
|
||||
#include "hb-ot-shape-complex-arabic-win1256.hh"
|
||||
#endif
|
||||
|
||||
struct ManifestLookup {
|
||||
OT::Tag tag;
|
||||
OT::OffsetTo<OT::SubstLookup> lookupOffset;
|
||||
};
|
||||
typedef OT::ArrayOf<ManifestLookup> Manifest;
|
||||
|
||||
static bool
|
||||
arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
|
||||
const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font)
|
||||
{
|
||||
#ifdef HB_WITH_WIN1256
|
||||
/* Does this font look like it's Windows-1256-encoded? */
|
||||
hb_codepoint_t g;
|
||||
if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
|
||||
hb_font_get_glyph (font, 0x0644u, 0, &g) && g == 225 /* LAM */ &&
|
||||
hb_font_get_glyph (font, 0x0649u, 0, &g) && g == 236 /* ALEF MAKSURA */ &&
|
||||
hb_font_get_glyph (font, 0x064Au, 0, &g) && g == 237 /* YEH */ &&
|
||||
hb_font_get_glyph (font, 0x0652u, 0, &g) && g == 250 /* SUKUN */))
|
||||
return false;
|
||||
|
||||
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
|
||||
ASSERT_STATIC (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
|
||||
<= ARABIC_FALLBACK_MAX_LOOKUPS);
|
||||
/* TODO sanitize the table? */
|
||||
|
||||
unsigned j = 0;
|
||||
unsigned int count = manifest.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
fallback_plan->mask_array[j] = plan->map.get_1_mask (manifest[i].tag);
|
||||
if (fallback_plan->mask_array[j])
|
||||
{
|
||||
fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest+manifest[i].lookupOffset));
|
||||
if (fallback_plan->lookup_array[j])
|
||||
{
|
||||
fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fallback_plan->num_lookups = j;
|
||||
fallback_plan->free_lookups = false;
|
||||
|
||||
return j > 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
|
||||
const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font)
|
||||
{
|
||||
ASSERT_STATIC (ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS);
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
|
||||
{
|
||||
fallback_plan->mask_array[j] = plan->map.get_1_mask (arabic_fallback_features[i]);
|
||||
if (fallback_plan->mask_array[j])
|
||||
{
|
||||
fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
|
||||
if (fallback_plan->lookup_array[j])
|
||||
{
|
||||
fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fallback_plan->num_lookups = j;
|
||||
fallback_plan->free_lookups = true;
|
||||
|
||||
return j > 0;
|
||||
}
|
||||
|
||||
static arabic_fallback_plan_t *
|
||||
arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font)
|
||||
{
|
||||
arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
|
||||
if (unlikely (!fallback_plan))
|
||||
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
||||
|
||||
fallback_plan->num_lookups = 0;
|
||||
fallback_plan->free_lookups = false;
|
||||
|
||||
/* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
|
||||
* in case the font has cmap entries for the presentation-forms characters. */
|
||||
if (arabic_fallback_plan_init_unicode (fallback_plan, plan, font))
|
||||
return fallback_plan;
|
||||
|
||||
/* See if this looks like a Windows-1256-encoded font. If it does, use a
|
||||
* hand-coded GSUB table. */
|
||||
if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
|
||||
return fallback_plan;
|
||||
|
||||
free (fallback_plan);
|
||||
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
|
||||
{
|
||||
if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
||||
if (fallback_plan->lookup_array[i])
|
||||
{
|
||||
fallback_plan->accel_array[i].fini ();
|
||||
if (fallback_plan->free_lookups)
|
||||
free (fallback_plan->lookup_array[i]);
|
||||
}
|
||||
|
||||
free (fallback_plan);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
OT::hb_apply_context_t c (0, font, buffer);
|
||||
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
||||
if (fallback_plan->lookup_array[i]) {
|
||||
c.set_lookup_mask (fallback_plan->mask_array[i]);
|
||||
hb_ot_layout_substitute_lookup (&c,
|
||||
*fallback_plan->lookup_array[i],
|
||||
fallback_plan->accel_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
|
||||
50
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-private.hh
Normal file
50
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-private.hh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright © 2015 Mozilla Foundation.
|
||||
* Copyright © 2015 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.
|
||||
*
|
||||
* Mozilla Author(s): Jonathan Kew
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
struct arabic_shape_plan_t;
|
||||
|
||||
HB_INTERNAL void *
|
||||
data_create_arabic (const hb_ot_shape_plan_t *plan);
|
||||
|
||||
HB_INTERNAL void
|
||||
data_destroy_arabic (void *data);
|
||||
|
||||
HB_INTERNAL void
|
||||
setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_script_t script);
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */
|
||||
395
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
Normal file
395
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
/* == Start of generated table == */
|
||||
/*
|
||||
* The following table is generated by running:
|
||||
*
|
||||
* ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
|
||||
*
|
||||
* on files with these headers:
|
||||
*
|
||||
* # ArabicShaping-9.0.0.txt
|
||||
* # Date: 2016-02-24, 22:25:00 GMT [RP]
|
||||
* # Blocks-9.0.0.txt
|
||||
* # Date: 2016-02-05, 23:48:00 GMT [KW]
|
||||
* UnicodeData.txt does not have a header.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
|
||||
|
||||
|
||||
#define X JOINING_TYPE_X
|
||||
#define R JOINING_TYPE_R
|
||||
#define T JOINING_TYPE_T
|
||||
#define U JOINING_TYPE_U
|
||||
#define A JOINING_GROUP_ALAPH
|
||||
#define DR JOINING_GROUP_DALATH_RISH
|
||||
#define L JOINING_TYPE_L
|
||||
#define C JOINING_TYPE_C
|
||||
#define D JOINING_TYPE_D
|
||||
|
||||
static const uint8_t joining_table[] =
|
||||
{
|
||||
|
||||
#define joining_offset_0x0600u 0
|
||||
|
||||
/* Arabic */
|
||||
|
||||
/* 0600 */ U,U,U,U,U,U,X,X,U,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 0620 */ D,U,R,R,R,R,D,R,D,R,D,D,D,D,D,R,R,R,R,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 0640 */ C,D,D,D,D,D,D,D,R,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 0660 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,D,D,X,R,R,R,U,R,R,R,D,D,D,D,D,D,D,D,
|
||||
/* 0680 */ D,D,D,D,D,D,D,D,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,D,D,D,D,D,D,
|
||||
/* 06A0 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 06C0 */ R,D,D,R,R,R,R,R,R,R,R,R,D,R,D,R,D,D,R,R,X,R,X,X,X,X,X,X,X,U,X,X,
|
||||
/* 06E0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,R,R,X,X,X,X,X,X,X,X,X,X,D,D,D,X,X,D,
|
||||
|
||||
/* Syriac */
|
||||
|
||||
/* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
|
||||
/* 0720 */ D,D,D,D,D,D,D,D,R,D,DR,D,R,D,D,DR,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 0740 */ X,X,X,X,X,X,X,X,X,X,X,X,X,R,D,D,
|
||||
|
||||
/* Arabic Supplement */
|
||||
|
||||
/* 0740 */ D,D,D,D,D,D,D,D,D,R,R,R,D,D,D,D,
|
||||
/* 0760 */ D,D,D,D,D,D,D,D,D,D,D,R,R,D,D,D,D,R,D,R,R,D,D,D,R,R,D,D,D,D,D,D,
|
||||
|
||||
/* FILLER */
|
||||
|
||||
/* 0780 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 07A0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
|
||||
/* NKo */
|
||||
|
||||
/* 07C0 */ X,X,X,X,X,X,X,X,X,X,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 07E0 */ D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,C,X,X,X,X,X,
|
||||
|
||||
/* FILLER */
|
||||
|
||||
/* 0800 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 0820 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
|
||||
/* Mandaic */
|
||||
|
||||
/* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X,
|
||||
/* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
|
||||
/* Arabic Extended-A */
|
||||
|
||||
/* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,X,X,
|
||||
/* 08C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 08E0 */ X,X,U,
|
||||
|
||||
#define joining_offset_0x1806u 739
|
||||
|
||||
/* Mongolian */
|
||||
|
||||
/* 1800 */ U,D,X,X,C,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 1820 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 1840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,
|
||||
/* 1880 */ U,U,U,U,U,T,T,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 18A0 */ D,D,D,D,D,D,D,D,D,X,D,
|
||||
|
||||
#define joining_offset_0x200cu 904
|
||||
|
||||
/* General Punctuation */
|
||||
|
||||
/* 2000 */ U,C,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 2020 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 2040 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 2060 */ X,X,X,X,X,X,U,U,U,U,
|
||||
|
||||
#define joining_offset_0xa840u 998
|
||||
|
||||
/* Phags-pa */
|
||||
|
||||
/* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U,
|
||||
|
||||
#define joining_offset_0x10ac0u 1050
|
||||
|
||||
/* Manichaean */
|
||||
|
||||
/* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D,
|
||||
/* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R,
|
||||
|
||||
#define joining_offset_0x10b80u 1098
|
||||
|
||||
/* Psalter Pahlavi */
|
||||
|
||||
/* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
|
||||
/* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U,
|
||||
|
||||
#define joining_offset_0x1e900u 1146
|
||||
|
||||
/* Adlam */
|
||||
|
||||
/* 1E900 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
|
||||
/* 1E940 */ D,D,D,D,
|
||||
|
||||
}; /* Table items: 1214; occupancy: 54% */
|
||||
|
||||
|
||||
static unsigned int
|
||||
joining_type (hb_codepoint_t u)
|
||||
{
|
||||
switch (u >> 12)
|
||||
{
|
||||
case 0x0u:
|
||||
if (hb_in_range (u, 0x0600u, 0x08E2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u];
|
||||
break;
|
||||
|
||||
case 0x1u:
|
||||
if (hb_in_range (u, 0x1806u, 0x18AAu)) return joining_table[u - 0x1806u + joining_offset_0x1806u];
|
||||
break;
|
||||
|
||||
case 0x2u:
|
||||
if (hb_in_range (u, 0x200Cu, 0x2069u)) return joining_table[u - 0x200Cu + joining_offset_0x200cu];
|
||||
break;
|
||||
|
||||
case 0xAu:
|
||||
if (hb_in_range (u, 0xA840u, 0xA873u)) return joining_table[u - 0xA840u + joining_offset_0xa840u];
|
||||
break;
|
||||
|
||||
case 0x10u:
|
||||
if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u];
|
||||
if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u];
|
||||
break;
|
||||
|
||||
case 0x1Eu:
|
||||
if (hb_in_range (u, 0x1E900u, 0x1E943u)) return joining_table[u - 0x1E900u + joining_offset_0x1e900u];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return X;
|
||||
}
|
||||
|
||||
#undef X
|
||||
#undef R
|
||||
#undef T
|
||||
#undef U
|
||||
#undef A
|
||||
#undef DR
|
||||
#undef L
|
||||
#undef C
|
||||
#undef D
|
||||
|
||||
|
||||
static const uint16_t shaping_table[][4] =
|
||||
{
|
||||
{0x0000u, 0x0000u, 0x0000u, 0xFE80u}, /* U+0621 ARABIC LETTER HAMZA ISOLATED FORM */
|
||||
{0x0000u, 0x0000u, 0xFE82u, 0xFE81u}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
|
||||
{0x0000u, 0x0000u, 0xFE84u, 0xFE83u}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
|
||||
{0x0000u, 0x0000u, 0xFE86u, 0xFE85u}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
|
||||
{0x0000u, 0x0000u, 0xFE88u, 0xFE87u}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
|
||||
{0xFE8Bu, 0xFE8Cu, 0xFE8Au, 0xFE89u}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
|
||||
{0x0000u, 0x0000u, 0xFE8Eu, 0xFE8Du}, /* U+0627 ARABIC LETTER ALEF */
|
||||
{0xFE91u, 0xFE92u, 0xFE90u, 0xFE8Fu}, /* U+0628 ARABIC LETTER BEH */
|
||||
{0x0000u, 0x0000u, 0xFE94u, 0xFE93u}, /* U+0629 ARABIC LETTER TEH MARBUTA */
|
||||
{0xFE97u, 0xFE98u, 0xFE96u, 0xFE95u}, /* U+062A ARABIC LETTER TEH */
|
||||
{0xFE9Bu, 0xFE9Cu, 0xFE9Au, 0xFE99u}, /* U+062B ARABIC LETTER THEH */
|
||||
{0xFE9Fu, 0xFEA0u, 0xFE9Eu, 0xFE9Du}, /* U+062C ARABIC LETTER JEEM */
|
||||
{0xFEA3u, 0xFEA4u, 0xFEA2u, 0xFEA1u}, /* U+062D ARABIC LETTER HAH */
|
||||
{0xFEA7u, 0xFEA8u, 0xFEA6u, 0xFEA5u}, /* U+062E ARABIC LETTER KHAH */
|
||||
{0x0000u, 0x0000u, 0xFEAAu, 0xFEA9u}, /* U+062F ARABIC LETTER DAL */
|
||||
{0x0000u, 0x0000u, 0xFEACu, 0xFEABu}, /* U+0630 ARABIC LETTER THAL */
|
||||
{0x0000u, 0x0000u, 0xFEAEu, 0xFEADu}, /* U+0631 ARABIC LETTER REH */
|
||||
{0x0000u, 0x0000u, 0xFEB0u, 0xFEAFu}, /* U+0632 ARABIC LETTER ZAIN */
|
||||
{0xFEB3u, 0xFEB4u, 0xFEB2u, 0xFEB1u}, /* U+0633 ARABIC LETTER SEEN */
|
||||
{0xFEB7u, 0xFEB8u, 0xFEB6u, 0xFEB5u}, /* U+0634 ARABIC LETTER SHEEN */
|
||||
{0xFEBBu, 0xFEBCu, 0xFEBAu, 0xFEB9u}, /* U+0635 ARABIC LETTER SAD */
|
||||
{0xFEBFu, 0xFEC0u, 0xFEBEu, 0xFEBDu}, /* U+0636 ARABIC LETTER DAD */
|
||||
{0xFEC3u, 0xFEC4u, 0xFEC2u, 0xFEC1u}, /* U+0637 ARABIC LETTER TAH */
|
||||
{0xFEC7u, 0xFEC8u, 0xFEC6u, 0xFEC5u}, /* U+0638 ARABIC LETTER ZAH */
|
||||
{0xFECBu, 0xFECCu, 0xFECAu, 0xFEC9u}, /* U+0639 ARABIC LETTER AIN */
|
||||
{0xFECFu, 0xFED0u, 0xFECEu, 0xFECDu}, /* U+063A ARABIC LETTER GHAIN */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063B */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063D */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0640 */
|
||||
{0xFED3u, 0xFED4u, 0xFED2u, 0xFED1u}, /* U+0641 ARABIC LETTER FEH */
|
||||
{0xFED7u, 0xFED8u, 0xFED6u, 0xFED5u}, /* U+0642 ARABIC LETTER QAF */
|
||||
{0xFEDBu, 0xFEDCu, 0xFEDAu, 0xFED9u}, /* U+0643 ARABIC LETTER KAF */
|
||||
{0xFEDFu, 0xFEE0u, 0xFEDEu, 0xFEDDu}, /* U+0644 ARABIC LETTER LAM */
|
||||
{0xFEE3u, 0xFEE4u, 0xFEE2u, 0xFEE1u}, /* U+0645 ARABIC LETTER MEEM */
|
||||
{0xFEE7u, 0xFEE8u, 0xFEE6u, 0xFEE5u}, /* U+0646 ARABIC LETTER NOON */
|
||||
{0xFEEBu, 0xFEECu, 0xFEEAu, 0xFEE9u}, /* U+0647 ARABIC LETTER HEH */
|
||||
{0x0000u, 0x0000u, 0xFEEEu, 0xFEEDu}, /* U+0648 ARABIC LETTER WAW */
|
||||
{0xFBE8u, 0xFBE9u, 0xFEF0u, 0xFEEFu}, /* U+0649 ARABIC LETTER */
|
||||
{0xFEF3u, 0xFEF4u, 0xFEF2u, 0xFEF1u}, /* U+064A ARABIC LETTER YEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064B */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064D */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0650 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0651 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0652 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0653 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0654 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0655 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0656 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0657 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0658 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0659 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065A */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065B */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065D */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0660 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0661 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0662 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0663 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0664 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0665 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0666 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0667 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0668 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0669 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066A */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066B */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066D */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0670 */
|
||||
{0x0000u, 0x0000u, 0xFB51u, 0xFB50u}, /* U+0671 ARABIC LETTER ALEF WASLA */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0672 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0673 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0674 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0675 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0676 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0xFBDDu}, /* U+0677 ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0678 */
|
||||
{0xFB68u, 0xFB69u, 0xFB67u, 0xFB66u}, /* U+0679 ARABIC LETTER TTEH */
|
||||
{0xFB60u, 0xFB61u, 0xFB5Fu, 0xFB5Eu}, /* U+067A ARABIC LETTER TTEHEH */
|
||||
{0xFB54u, 0xFB55u, 0xFB53u, 0xFB52u}, /* U+067B ARABIC LETTER BEEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+067C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+067D */
|
||||
{0xFB58u, 0xFB59u, 0xFB57u, 0xFB56u}, /* U+067E ARABIC LETTER PEH */
|
||||
{0xFB64u, 0xFB65u, 0xFB63u, 0xFB62u}, /* U+067F ARABIC LETTER TEHEH */
|
||||
{0xFB5Cu, 0xFB5Du, 0xFB5Bu, 0xFB5Au}, /* U+0680 ARABIC LETTER BEHEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0681 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0682 */
|
||||
{0xFB78u, 0xFB79u, 0xFB77u, 0xFB76u}, /* U+0683 ARABIC LETTER NYEH */
|
||||
{0xFB74u, 0xFB75u, 0xFB73u, 0xFB72u}, /* U+0684 ARABIC LETTER DYEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0685 */
|
||||
{0xFB7Cu, 0xFB7Du, 0xFB7Bu, 0xFB7Au}, /* U+0686 ARABIC LETTER TCHEH */
|
||||
{0xFB80u, 0xFB81u, 0xFB7Fu, 0xFB7Eu}, /* U+0687 ARABIC LETTER TCHEHEH */
|
||||
{0x0000u, 0x0000u, 0xFB89u, 0xFB88u}, /* U+0688 ARABIC LETTER DDAL */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0689 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068A */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068B */
|
||||
{0x0000u, 0x0000u, 0xFB85u, 0xFB84u}, /* U+068C ARABIC LETTER DAHAL */
|
||||
{0x0000u, 0x0000u, 0xFB83u, 0xFB82u}, /* U+068D ARABIC LETTER DDAHAL */
|
||||
{0x0000u, 0x0000u, 0xFB87u, 0xFB86u}, /* U+068E ARABIC LETTER DUL */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0690 */
|
||||
{0x0000u, 0x0000u, 0xFB8Du, 0xFB8Cu}, /* U+0691 ARABIC LETTER RREH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0692 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0693 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0694 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0695 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0696 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0697 */
|
||||
{0x0000u, 0x0000u, 0xFB8Bu, 0xFB8Au}, /* U+0698 ARABIC LETTER JEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0699 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069A */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069B */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069C */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069D */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069F */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A0 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A1 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A2 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A3 */
|
||||
{0xFB6Cu, 0xFB6Du, 0xFB6Bu, 0xFB6Au}, /* U+06A4 ARABIC LETTER VEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A5 */
|
||||
{0xFB70u, 0xFB71u, 0xFB6Fu, 0xFB6Eu}, /* U+06A6 ARABIC LETTER PEHEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A7 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A8 */
|
||||
{0xFB90u, 0xFB91u, 0xFB8Fu, 0xFB8Eu}, /* U+06A9 ARABIC LETTER KEHEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AA */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AB */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AC */
|
||||
{0xFBD5u, 0xFBD6u, 0xFBD4u, 0xFBD3u}, /* U+06AD ARABIC LETTER NG */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AE */
|
||||
{0xFB94u, 0xFB95u, 0xFB93u, 0xFB92u}, /* U+06AF ARABIC LETTER GAF */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B0 */
|
||||
{0xFB9Cu, 0xFB9Du, 0xFB9Bu, 0xFB9Au}, /* U+06B1 ARABIC LETTER NGOEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B2 */
|
||||
{0xFB98u, 0xFB99u, 0xFB97u, 0xFB96u}, /* U+06B3 ARABIC LETTER GUEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B4 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B5 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B6 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B7 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B8 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B9 */
|
||||
{0x0000u, 0x0000u, 0xFB9Fu, 0xFB9Eu}, /* U+06BA ARABIC LETTER NOON GHUNNA */
|
||||
{0xFBA2u, 0xFBA3u, 0xFBA1u, 0xFBA0u}, /* U+06BB ARABIC LETTER RNOON */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BC */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BD */
|
||||
{0xFBACu, 0xFBADu, 0xFBABu, 0xFBAAu}, /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BF */
|
||||
{0x0000u, 0x0000u, 0xFBA5u, 0xFBA4u}, /* U+06C0 ARABIC LETTER HEH WITH YEH ABOVE */
|
||||
{0xFBA8u, 0xFBA9u, 0xFBA7u, 0xFBA6u}, /* U+06C1 ARABIC LETTER HEH GOAL */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C2 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C3 */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C4 */
|
||||
{0x0000u, 0x0000u, 0xFBE1u, 0xFBE0u}, /* U+06C5 ARABIC LETTER KIRGHIZ OE */
|
||||
{0x0000u, 0x0000u, 0xFBDAu, 0xFBD9u}, /* U+06C6 ARABIC LETTER OE */
|
||||
{0x0000u, 0x0000u, 0xFBD8u, 0xFBD7u}, /* U+06C7 ARABIC LETTER U */
|
||||
{0x0000u, 0x0000u, 0xFBDCu, 0xFBDBu}, /* U+06C8 ARABIC LETTER YU */
|
||||
{0x0000u, 0x0000u, 0xFBE3u, 0xFBE2u}, /* U+06C9 ARABIC LETTER KIRGHIZ YU */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CA */
|
||||
{0x0000u, 0x0000u, 0xFBDFu, 0xFBDEu}, /* U+06CB ARABIC LETTER VE */
|
||||
{0xFBFEu, 0xFBFFu, 0xFBFDu, 0xFBFCu}, /* U+06CC ARABIC LETTER FARSI YEH */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CD */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CE */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CF */
|
||||
{0xFBE6u, 0xFBE7u, 0xFBE5u, 0xFBE4u}, /* U+06D0 ARABIC LETTER E */
|
||||
{0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06D1 */
|
||||
{0x0000u, 0x0000u, 0xFBAFu, 0xFBAEu}, /* U+06D2 ARABIC LETTER YEH BARREE */
|
||||
{0x0000u, 0x0000u, 0xFBB1u, 0xFBB0u}, /* U+06D3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
|
||||
};
|
||||
|
||||
#define SHAPING_TABLE_FIRST 0x0621u
|
||||
#define SHAPING_TABLE_LAST 0x06D3u
|
||||
|
||||
|
||||
static const struct ligature_set_t {
|
||||
uint16_t first;
|
||||
struct ligature_pairs_t {
|
||||
uint16_t second;
|
||||
uint16_t ligature;
|
||||
} ligatures[4];
|
||||
} ligature_table[] =
|
||||
{
|
||||
{ 0xFEDFu, {
|
||||
{ 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
|
||||
{ 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
|
||||
{ 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
|
||||
{ 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
|
||||
}},
|
||||
{ 0xFEE0u, {
|
||||
{ 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
|
||||
{ 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
|
||||
{ 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
|
||||
{ 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
|
||||
}},
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
|
||||
|
||||
/* == End of generated table == */
|
||||
323
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
Normal file
323
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright © 2014 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_SHAPE_COMPLEX_ARABIC_WIN1256_HH
|
||||
|
||||
|
||||
/*
|
||||
* The macros in the first part of this file are generic macros that can
|
||||
* be used to define the bytes for OpenType table data in code in a
|
||||
* readable manner. We can move the macros to reside with their respective
|
||||
* struct types, but since we only use these to define one data table, the
|
||||
* Windows-1256 Arabic shaping table in this file, we keep them here.
|
||||
*/
|
||||
|
||||
|
||||
/* First we measure, then we cut. */
|
||||
#ifndef OT_MEASURE
|
||||
#define OT_MEASURE
|
||||
#define OT_TABLE_START static const struct TABLE_NAME {
|
||||
#define OT_TABLE_END }
|
||||
#define OT_LABEL_START(Name) unsigned char Name[
|
||||
#define OT_LABEL_END ];
|
||||
#define OT_BYTE(u8) +1/*byte*/
|
||||
#define OT_USHORT(u16) +2/*bytes*/
|
||||
#else
|
||||
#undef OT_MEASURE
|
||||
#define OT_TABLE_START TABLE_NAME = {
|
||||
#define OT_TABLE_END };
|
||||
#define OT_LABEL_START(Name) {
|
||||
#define OT_LABEL_END },
|
||||
#define OT_BYTE(u8) (u8),
|
||||
#define OT_USHORT(u16) (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
|
||||
#define OT_COUNT(Name, ItemSize) ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
|
||||
/ (unsigned int)(ItemSize) \
|
||||
/* OT_ASSERT it's divisible (and positive). */)
|
||||
#define OT_DISTANCE(From,To) ((unsigned int) \
|
||||
((char*)(&((struct TABLE_NAME*)0)->To) - \
|
||||
(char*)(&((struct TABLE_NAME*)0)->From)) \
|
||||
/* OT_ASSERT it's positive. */)
|
||||
#endif
|
||||
|
||||
|
||||
#define OT_LABEL(Name) \
|
||||
OT_LABEL_END \
|
||||
OT_LABEL_START(Name)
|
||||
|
||||
/* Whenever we receive an argument that is a list, it will expand to
|
||||
* contain commas. That cannot be passed to another macro because the
|
||||
* commas will throw off the preprocessor. The solution is to wrap
|
||||
* the passed-in argument in OT_LIST() before passing to the next macro.
|
||||
* Unfortunately this trick requires vararg macros. */
|
||||
#define OT_LIST(...) __VA_ARGS__
|
||||
|
||||
|
||||
/*
|
||||
* Basic Types
|
||||
*/
|
||||
|
||||
#define OT_TAG(a,b,c,d) \
|
||||
OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
|
||||
|
||||
#define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
|
||||
OT_USHORT(OT_DISTANCE(From, To))
|
||||
|
||||
#define OT_GLYPHID /* GlyphID */ \
|
||||
OT_USHORT
|
||||
|
||||
#define OT_UARRAY(Name, Items) \
|
||||
OT_LABEL_START(Name) \
|
||||
OT_USHORT(OT_COUNT(Name##Data, 2)) \
|
||||
OT_LABEL(Name##Data) \
|
||||
Items \
|
||||
OT_LABEL_END
|
||||
|
||||
#define OT_UHEADLESSARRAY(Name, Items) \
|
||||
OT_LABEL_START(Name) \
|
||||
OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \
|
||||
OT_LABEL(Name##Data) \
|
||||
Items \
|
||||
OT_LABEL_END
|
||||
|
||||
|
||||
/*
|
||||
* Common Types
|
||||
*/
|
||||
|
||||
#define OT_LOOKUP_FLAG_IGNORE_MARKS 0x08u
|
||||
|
||||
#define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
|
||||
OT_LABEL_START(Name) \
|
||||
OT_USHORT(LookupType) \
|
||||
OT_USHORT(LookupFlag) \
|
||||
OT_LABEL_END \
|
||||
OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
|
||||
|
||||
#define OT_SUBLOOKUP(Name, SubFormat, Items) \
|
||||
OT_LABEL_START(Name) \
|
||||
OT_USHORT(SubFormat) \
|
||||
Items
|
||||
|
||||
#define OT_COVERAGE1(Name, Items) \
|
||||
OT_LABEL_START(Name) \
|
||||
OT_USHORT(1) \
|
||||
OT_LABEL_END \
|
||||
OT_UARRAY(Name##Glyphs, OT_LIST(Items))
|
||||
|
||||
|
||||
/*
|
||||
* GSUB
|
||||
*/
|
||||
|
||||
#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u
|
||||
#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u
|
||||
|
||||
#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
|
||||
OT_SUBLOOKUP(Name, 2, \
|
||||
OT_OFFSET(Name, Name##Coverage) \
|
||||
OT_LABEL_END \
|
||||
OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
|
||||
) \
|
||||
OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
|
||||
/* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */
|
||||
|
||||
#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
|
||||
OT_SUBLOOKUP(Name, 1, \
|
||||
OT_OFFSET(Name, Name##Coverage) \
|
||||
OT_LABEL_END \
|
||||
OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
|
||||
) \
|
||||
OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
|
||||
/* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */
|
||||
|
||||
#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
|
||||
OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))
|
||||
|
||||
#define OT_LIGATURE(Name, Components, LigGlyph) \
|
||||
OT_LABEL_START(Name) \
|
||||
LigGlyph \
|
||||
OT_LABEL_END \
|
||||
OT_UHEADLESSARRAY(Name##ComponentsArray, OT_LIST(Components))
|
||||
|
||||
/*
|
||||
*
|
||||
* Start of Windows-1256 shaping table.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Table name. */
|
||||
#define TABLE_NAME arabic_win1256_gsub_lookups
|
||||
|
||||
/* Table manifest. */
|
||||
#define MANIFEST(Items) \
|
||||
OT_LABEL_START(manifest) \
|
||||
OT_USHORT(OT_COUNT(manifestData, 6)) \
|
||||
OT_LABEL(manifestData) \
|
||||
Items \
|
||||
OT_LABEL_END
|
||||
|
||||
#define MANIFEST_LOOKUP(Tag, Name) \
|
||||
Tag \
|
||||
OT_OFFSET(manifest, Name)
|
||||
|
||||
/* Shorthand. */
|
||||
#define G OT_GLYPHID
|
||||
|
||||
/*
|
||||
* Table Start
|
||||
*/
|
||||
OT_TABLE_START
|
||||
|
||||
|
||||
/*
|
||||
* Manifest
|
||||
*/
|
||||
MANIFEST(
|
||||
MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligLookup)
|
||||
MANIFEST_LOOKUP(OT_TAG('i','n','i','t'), initLookup)
|
||||
MANIFEST_LOOKUP(OT_TAG('m','e','d','i'), mediLookup)
|
||||
MANIFEST_LOOKUP(OT_TAG('f','i','n','a'), finaLookup)
|
||||
MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligMarksLookup)
|
||||
)
|
||||
|
||||
/*
|
||||
* Lookups
|
||||
*/
|
||||
OT_LOOKUP(initLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||
OT_OFFSET(initLookup, initmediSubLookup)
|
||||
OT_OFFSET(initLookup, initSubLookup)
|
||||
)
|
||||
OT_LOOKUP(mediLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||
OT_OFFSET(mediLookup, initmediSubLookup)
|
||||
OT_OFFSET(mediLookup, mediSubLookup)
|
||||
OT_OFFSET(mediLookup, medifinaLamAlefSubLookup)
|
||||
)
|
||||
OT_LOOKUP(finaLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||
OT_OFFSET(finaLookup, finaSubLookup)
|
||||
/* We don't need this one currently as the sequence inherits masks
|
||||
* from the first item. Just in case we change that in the future
|
||||
* to be smart about Arabic masks when ligating... */
|
||||
OT_OFFSET(finaLookup, medifinaLamAlefSubLookup)
|
||||
)
|
||||
OT_LOOKUP(rligLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||
OT_OFFSET(rligLookup, lamAlefLigaturesSubLookup)
|
||||
)
|
||||
OT_LOOKUP(rligMarksLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, 0,
|
||||
OT_OFFSET(rligMarksLookup, shaddaLigaturesSubLookup)
|
||||
)
|
||||
|
||||
/*
|
||||
* init/medi/fina forms
|
||||
*/
|
||||
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initmediSubLookup,
|
||||
G(198) G(200) G(201) G(202) G(203) G(204) G(205) G(206) G(211)
|
||||
G(212) G(213) G(214) G(223) G(225) G(227) G(228) G(236) G(237),
|
||||
G(162) G(4) G(5) G(5) G(6) G(7) G(9) G(11) G(13)
|
||||
G(14) G(15) G(26) G(140) G(141) G(142) G(143) G(154) G(154)
|
||||
)
|
||||
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initSubLookup,
|
||||
G(218) G(219) G(221) G(222) G(229),
|
||||
G(27) G(30) G(128) G(131) G(144)
|
||||
)
|
||||
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(mediSubLookup,
|
||||
G(218) G(219) G(221) G(222) G(229),
|
||||
G(28) G(31) G(129) G(138) G(149)
|
||||
)
|
||||
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(finaSubLookup,
|
||||
G(194) G(195) G(197) G(198) G(199) G(201) G(204) G(205) G(206)
|
||||
G(218) G(219) G(229) G(236) G(237),
|
||||
G(2) G(1) G(3) G(181) G(0) G(159) G(8) G(10) G(12)
|
||||
G(29) G(127) G(152) G(160) G(156)
|
||||
)
|
||||
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(medifinaLamAlefSubLookup,
|
||||
G(165) G(178) G(180) G(252),
|
||||
G(170) G(179) G(185) G(255)
|
||||
)
|
||||
|
||||
/*
|
||||
* Lam+Alef ligatures
|
||||
*/
|
||||
OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(lamAlefLigaturesSubLookup,
|
||||
G(225),
|
||||
OT_OFFSET(lamAlefLigaturesSubLookup, lamLigatureSet)
|
||||
)
|
||||
OT_LIGATURE_SET(lamLigatureSet,
|
||||
OT_OFFSET(lamLigatureSet, lamInitLigature1)
|
||||
OT_OFFSET(lamLigatureSet, lamInitLigature2)
|
||||
OT_OFFSET(lamLigatureSet, lamInitLigature3)
|
||||
OT_OFFSET(lamLigatureSet, lamInitLigature4)
|
||||
)
|
||||
OT_LIGATURE(lamInitLigature1, G(199), G(165))
|
||||
OT_LIGATURE(lamInitLigature2, G(195), G(178))
|
||||
OT_LIGATURE(lamInitLigature3, G(194), G(180))
|
||||
OT_LIGATURE(lamInitLigature4, G(197), G(252))
|
||||
|
||||
/*
|
||||
* Shadda ligatures
|
||||
*/
|
||||
OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(shaddaLigaturesSubLookup,
|
||||
G(248),
|
||||
OT_OFFSET(shaddaLigaturesSubLookup, shaddaLigatureSet)
|
||||
)
|
||||
OT_LIGATURE_SET(shaddaLigatureSet,
|
||||
OT_OFFSET(shaddaLigatureSet, shaddaLigature1)
|
||||
OT_OFFSET(shaddaLigatureSet, shaddaLigature2)
|
||||
OT_OFFSET(shaddaLigatureSet, shaddaLigature3)
|
||||
)
|
||||
OT_LIGATURE(shaddaLigature1, G(243), G(172))
|
||||
OT_LIGATURE(shaddaLigature2, G(245), G(173))
|
||||
OT_LIGATURE(shaddaLigature3, G(246), G(175))
|
||||
|
||||
/*
|
||||
* Table end
|
||||
*/
|
||||
OT_TABLE_END
|
||||
|
||||
|
||||
/*
|
||||
* Clean up
|
||||
*/
|
||||
#undef OT_TABLE_START
|
||||
#undef OT_TABLE_END
|
||||
#undef OT_LABEL_START
|
||||
#undef OT_LABEL_END
|
||||
#undef OT_BYTE
|
||||
#undef OT_USHORT
|
||||
#undef OT_DISTANCE
|
||||
#undef OT_COUNT
|
||||
|
||||
/*
|
||||
* Include a second time to get the table data...
|
||||
*/
|
||||
#if 0
|
||||
#include "hb-private.hh" /* Make check-includes.sh happy. */
|
||||
#endif
|
||||
#ifdef OT_MEASURE
|
||||
#include "hb-ot-shape-complex-arabic-win1256.hh"
|
||||
#endif
|
||||
|
||||
#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
|
||||
624
gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc
Normal file
624
gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc
Normal file
|
|
@ -0,0 +1,624 @@
|
|||
/*
|
||||
* Copyright © 2010,2012 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
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-private.hh"
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_ARABIC
|
||||
#define HB_DEBUG_ARABIC (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* buffer var allocations */
|
||||
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
|
||||
|
||||
#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
|
||||
|
||||
/* See:
|
||||
* https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
|
||||
#define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \
|
||||
(FLAG_SAFE (gen_cat) & \
|
||||
(FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \
|
||||
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \
|
||||
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |*/ \
|
||||
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |*/ \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL) | \
|
||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL)))
|
||||
|
||||
|
||||
/*
|
||||
* Joining types:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bits used in the joining tables
|
||||
*/
|
||||
enum hb_arabic_joining_type_t {
|
||||
JOINING_TYPE_U = 0,
|
||||
JOINING_TYPE_L = 1,
|
||||
JOINING_TYPE_R = 2,
|
||||
JOINING_TYPE_D = 3,
|
||||
JOINING_TYPE_C = JOINING_TYPE_D,
|
||||
JOINING_GROUP_ALAPH = 4,
|
||||
JOINING_GROUP_DALATH_RISH = 5,
|
||||
NUM_STATE_MACHINE_COLS = 6,
|
||||
|
||||
JOINING_TYPE_T = 7,
|
||||
JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */
|
||||
};
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-table.hh"
|
||||
|
||||
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
|
||||
{
|
||||
unsigned int j_type = joining_type(u);
|
||||
if (likely (j_type != JOINING_TYPE_X))
|
||||
return j_type;
|
||||
|
||||
return (FLAG_SAFE(gen_cat) &
|
||||
(FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
|
||||
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
|
||||
FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))
|
||||
) ? JOINING_TYPE_T : JOINING_TYPE_U;
|
||||
}
|
||||
|
||||
#define FEATURE_IS_SYRIAC(tag) hb_in_range<unsigned char> ((unsigned char) (tag), '2', '3')
|
||||
|
||||
static const hb_tag_t arabic_features[] =
|
||||
{
|
||||
HB_TAG('i','s','o','l'),
|
||||
HB_TAG('f','i','n','a'),
|
||||
HB_TAG('f','i','n','2'),
|
||||
HB_TAG('f','i','n','3'),
|
||||
HB_TAG('m','e','d','i'),
|
||||
HB_TAG('m','e','d','2'),
|
||||
HB_TAG('i','n','i','t'),
|
||||
HB_TAG_NONE
|
||||
};
|
||||
|
||||
|
||||
/* Same order as the feature array */
|
||||
enum arabic_action_t {
|
||||
ISOL,
|
||||
FINA,
|
||||
FIN2,
|
||||
FIN3,
|
||||
MEDI,
|
||||
MED2,
|
||||
INIT,
|
||||
|
||||
NONE,
|
||||
|
||||
ARABIC_NUM_FEATURES = NONE,
|
||||
|
||||
/* We abuse the same byte for other things... */
|
||||
STCH_FIXED,
|
||||
STCH_REPEATING,
|
||||
};
|
||||
|
||||
static const struct arabic_state_table_entry {
|
||||
uint8_t prev_action;
|
||||
uint8_t curr_action;
|
||||
uint16_t next_state;
|
||||
} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
|
||||
{
|
||||
/* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
|
||||
|
||||
/* State 0: prev was U, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
|
||||
|
||||
/* State 1: prev was R or ISOL/ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
|
||||
|
||||
/* State 2: prev was D/L in ISOL form, willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
|
||||
|
||||
/* State 3: prev was D in FINA form, willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
|
||||
|
||||
/* State 4: prev was FINA ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
|
||||
|
||||
/* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
|
||||
|
||||
/* State 6: prev was DALATH/RISH, not willing to join. */
|
||||
{ {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
nuke_joiners (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
record_stch (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
static void
|
||||
collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
/* We apply features according to the Arabic spec, with pauses
|
||||
* in between most.
|
||||
*
|
||||
* The pause between init/medi/... and rlig is required. See eg:
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184
|
||||
*
|
||||
* The pauses between init/medi/... themselves are not necessarily
|
||||
* needed as only one of those features is applied to any character.
|
||||
* The only difference it makes is when fonts have contextual
|
||||
* substitutions. We now follow the order of the spec, which makes
|
||||
* for better experience if that's what Uniscribe is doing.
|
||||
*
|
||||
* At least for Arabic, looks like Uniscribe has a pause between
|
||||
* rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't
|
||||
* work. However, testing shows that rlig and calt are applied
|
||||
* together for Mongolian in Uniscribe. As such, we only add a
|
||||
* pause for Arabic, not other scripts.
|
||||
*/
|
||||
|
||||
map->add_gsub_pause (nuke_joiners);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('s','t','c','h'));
|
||||
map->add_gsub_pause (record_stch);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
|
||||
map->add_gsub_pause (NULL);
|
||||
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
||||
{
|
||||
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
|
||||
map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
|
||||
map->add_gsub_pause (NULL);
|
||||
}
|
||||
|
||||
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
|
||||
if (plan->props.script == HB_SCRIPT_ARABIC)
|
||||
map->add_gsub_pause (arabic_fallback_shape);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
|
||||
/* The spec includes 'cswh'. Earlier versions of Windows
|
||||
* used to enable this by default, but testing suggests
|
||||
* that Windows 8 and later do not enable it by default,
|
||||
* and spec now says 'Off by default'.
|
||||
* We disabled this in ae23c24c32.
|
||||
* Note that IranNastaliq uses this feature extensively
|
||||
* to fixup broken glyph sequences. Oh well...
|
||||
* Test case: U+0643,U+0640,U+0631. */
|
||||
//map->add_gsub_pause (NULL);
|
||||
//map->add_global_bool_feature (HB_TAG('c','s','w','h'));
|
||||
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
|
||||
}
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-fallback.hh"
|
||||
|
||||
struct arabic_shape_plan_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
/* The "+ 1" in the next array is to accommodate for the "NONE" command,
|
||||
* which is not an OpenType feature, but this simplifies the code by not
|
||||
* having to do a "if (... < NONE) ..." and just rely on the fact that
|
||||
* mask_array[NONE] == 0. */
|
||||
hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
|
||||
|
||||
arabic_fallback_plan_t *fallback_plan;
|
||||
|
||||
unsigned int do_fallback : 1;
|
||||
unsigned int has_stch : 1;
|
||||
};
|
||||
|
||||
void *
|
||||
data_create_arabic (const hb_ot_shape_plan_t *plan)
|
||||
{
|
||||
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
|
||||
if (unlikely (!arabic_plan))
|
||||
return NULL;
|
||||
|
||||
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
|
||||
arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h'));
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
|
||||
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
|
||||
arabic_plan->do_fallback = arabic_plan->do_fallback &&
|
||||
(FEATURE_IS_SYRIAC (arabic_features[i]) ||
|
||||
plan->map.needs_fallback (arabic_features[i]));
|
||||
}
|
||||
|
||||
return arabic_plan;
|
||||
}
|
||||
|
||||
void
|
||||
data_destroy_arabic (void *data)
|
||||
{
|
||||
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data;
|
||||
|
||||
arabic_fallback_plan_destroy (arabic_plan->fallback_plan);
|
||||
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_joining (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int prev = (unsigned int) -1, state = 0;
|
||||
|
||||
/* Check pre-context */
|
||||
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T))
|
||||
continue;
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
state = entry->next_state;
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (info[i].codepoint, _hb_glyph_info_get_general_category (&info[i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T)) {
|
||||
info[i].arabic_shaping_action() = NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
|
||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
|
||||
info[i].arabic_shaping_action() = entry->curr_action;
|
||||
|
||||
prev = i;
|
||||
state = entry->next_state;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < buffer->context_len[1]; i++)
|
||||
{
|
||||
unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
|
||||
|
||||
if (unlikely (this_type == JOINING_TYPE_T))
|
||||
continue;
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mongolian_variation_selectors (hb_buffer_t *buffer)
|
||||
{
|
||||
/* Copy arabic_shaping_action() from base to Mongolian variation selectors. */
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
if (unlikely (hb_in_range (info[i].codepoint, 0x180Bu, 0x180Du)))
|
||||
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
|
||||
}
|
||||
|
||||
void
|
||||
setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_script_t script)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||
|
||||
arabic_joining (buffer);
|
||||
if (script == HB_SCRIPT_MONGOLIAN)
|
||||
mongolian_variation_selectors (buffer);
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()];
|
||||
}
|
||||
|
||||
static void
|
||||
setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_is_zwj (&info[i]))
|
||||
_hb_glyph_info_flip_joiners (&info[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||
|
||||
if (!arabic_plan->do_fallback)
|
||||
return;
|
||||
|
||||
retry:
|
||||
arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
|
||||
if (unlikely (!fallback_plan))
|
||||
{
|
||||
/* This sucks. We need a font to build the fallback plan... */
|
||||
fallback_plan = arabic_fallback_plan_create (plan, font);
|
||||
if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, NULL, fallback_plan))) {
|
||||
arabic_fallback_plan_destroy (fallback_plan);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
arabic_fallback_plan_shape (fallback_plan, font, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stretch feature: "stch".
|
||||
* See example here:
|
||||
* https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm
|
||||
* We implement this in a generic way, such that the Arabic subtending
|
||||
* marks can use it as well.
|
||||
*/
|
||||
|
||||
static void
|
||||
record_stch (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||
if (!arabic_plan->has_stch)
|
||||
return;
|
||||
|
||||
/* 'stch' feature was just applied. Look for anything that multiplied,
|
||||
* and record it for stch treatment later. Note that rtlm, frac, etc
|
||||
* are applied before stch, but we assume that they didn't result in
|
||||
* anything multiplying into 5 pieces, so it's safe-ish... */
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (_hb_glyph_info_multiplied (&info[i])))
|
||||
{
|
||||
unsigned int comp = _hb_glyph_info_get_lig_comp (&info[i]);
|
||||
info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED;
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
apply_stch (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
|
||||
return;
|
||||
|
||||
/* The Arabic shaper currently always processes in RTL mode, so we should
|
||||
* stretch / position the stretched pieces to the left / preceding glyphs. */
|
||||
|
||||
/* We do a two pass implementation:
|
||||
* First pass calculates the exact number of extra glyphs we need,
|
||||
* We then enlarge buffer to have that much room,
|
||||
* Second pass applies the stretch, copying things to the end of buffer.
|
||||
*/
|
||||
|
||||
int sign = font->x_scale < 0 ? -1 : +1;
|
||||
unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
|
||||
typedef enum { MEASURE, CUT } step_t;
|
||||
|
||||
for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1))
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
unsigned int new_len = count + extra_glyphs_needed; // write head during CUT
|
||||
unsigned int j = new_len;
|
||||
for (unsigned int i = count; i; i--)
|
||||
{
|
||||
if (!hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
|
||||
{
|
||||
if (step == CUT)
|
||||
{
|
||||
--j;
|
||||
info[j] = info[i - 1];
|
||||
pos[j] = pos[i - 1];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Yay, justification! */
|
||||
|
||||
hb_position_t w_total = 0; // Total to be filled
|
||||
hb_position_t w_fixed = 0; // Sum of fixed tiles
|
||||
hb_position_t w_repeating = 0; // Sum of repeating tiles
|
||||
int n_fixed = 0;
|
||||
int n_repeating = 0;
|
||||
|
||||
unsigned int end = i;
|
||||
while (i &&
|
||||
hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
|
||||
{
|
||||
i--;
|
||||
hb_position_t width = font->get_glyph_h_advance (info[i].codepoint);
|
||||
if (info[i].arabic_shaping_action() == STCH_FIXED)
|
||||
{
|
||||
w_fixed += width;
|
||||
n_fixed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
w_repeating += width;
|
||||
n_repeating++;
|
||||
}
|
||||
}
|
||||
unsigned int start = i;
|
||||
unsigned int context = i;
|
||||
while (context &&
|
||||
!hb_in_range<unsigned> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) &&
|
||||
(_hb_glyph_info_is_default_ignorable (&info[context - 1]) ||
|
||||
HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_category (&info[context - 1]))))
|
||||
{
|
||||
context--;
|
||||
w_total += pos[context].x_advance;
|
||||
}
|
||||
i++; // Don't touch i again.
|
||||
|
||||
DEBUG_MSG (ARABIC, NULL, "%s stretch at (%d,%d,%d)",
|
||||
step == MEASURE ? "measuring" : "cutting", context, start, end);
|
||||
DEBUG_MSG (ARABIC, NULL, "rest of word: count=%d width %d", start - context, w_total);
|
||||
DEBUG_MSG (ARABIC, NULL, "fixed tiles: count=%d width=%d", n_fixed, w_fixed);
|
||||
DEBUG_MSG (ARABIC, NULL, "repeating tiles: count=%d width=%d", n_repeating, w_repeating);
|
||||
|
||||
/* Number of additional times to repeat each repeating tile. */
|
||||
int n_copies = 0;
|
||||
|
||||
hb_position_t w_remaining = w_total - w_fixed;
|
||||
if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0)
|
||||
n_copies = (sign * w_remaining) / (sign * w_repeating) - 1;
|
||||
|
||||
/* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */
|
||||
hb_position_t extra_repeat_overlap = 0;
|
||||
hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
|
||||
if (shortfall > 0)
|
||||
{
|
||||
++n_copies;
|
||||
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
|
||||
if (excess > 0)
|
||||
extra_repeat_overlap = excess / (n_copies * n_repeating);
|
||||
}
|
||||
|
||||
if (step == MEASURE)
|
||||
{
|
||||
extra_glyphs_needed += n_copies * n_repeating;
|
||||
DEBUG_MSG (ARABIC, NULL, "will add extra %d copies of repeating tiles", n_copies);
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_position_t x_offset = 0;
|
||||
for (unsigned int k = end; k > start; k--)
|
||||
{
|
||||
hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint);
|
||||
|
||||
unsigned int repeat = 1;
|
||||
if (info[k - 1].arabic_shaping_action() == STCH_REPEATING)
|
||||
repeat += n_copies;
|
||||
|
||||
DEBUG_MSG (ARABIC, NULL, "appending %d copies of glyph %d; j=%d",
|
||||
repeat, info[k - 1].codepoint, j);
|
||||
for (unsigned int n = 0; n < repeat; n++)
|
||||
{
|
||||
x_offset -= width;
|
||||
if (n > 0)
|
||||
x_offset += extra_repeat_overlap;
|
||||
pos[k - 1].x_offset = x_offset;
|
||||
/* Append copy. */
|
||||
--j;
|
||||
info[j] = info[k - 1];
|
||||
pos[j] = pos[k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (step == MEASURE)
|
||||
{
|
||||
if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (j == 0);
|
||||
buffer->len = new_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
apply_stch (plan, buffer, font);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||
}
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||
{
|
||||
"arabic",
|
||||
collect_features_arabic,
|
||||
NULL, /* override_features */
|
||||
data_create_arabic,
|
||||
data_destroy_arabic,
|
||||
NULL, /* preprocess_text */
|
||||
postprocess_glyphs_arabic,
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
setup_masks_arabic,
|
||||
NULL, /* disable_otl */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||
true, /* fallback_position */
|
||||
};
|
||||
46
gfx/harfbuzz/src/hb-ot-shape-complex-default.cc
Normal file
46
gfx/harfbuzz/src/hb-ot-shape-complex-default.cc
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright © 2010,2012 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
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
|
||||
{
|
||||
"default",
|
||||
NULL, /* collect_features */
|
||||
NULL, /* override_features */
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
NULL, /* preprocess_text */
|
||||
NULL, /* postprocess_glyphs */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
NULL, /* setup_masks */
|
||||
NULL, /* disable_otl */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||
true, /* fallback_position */
|
||||
};
|
||||
425
gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc
Normal file
425
gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
/*
|
||||
* Copyright © 2013 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
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
/* Hangul shaper */
|
||||
|
||||
|
||||
/* Same order as the feature array below */
|
||||
enum {
|
||||
NONE,
|
||||
|
||||
LJMO,
|
||||
VJMO,
|
||||
TJMO,
|
||||
|
||||
FIRST_HANGUL_FEATURE = LJMO,
|
||||
HANGUL_FEATURE_COUNT = TJMO + 1
|
||||
};
|
||||
|
||||
static const hb_tag_t hangul_features[HANGUL_FEATURE_COUNT] =
|
||||
{
|
||||
HB_TAG_NONE,
|
||||
HB_TAG('l','j','m','o'),
|
||||
HB_TAG('v','j','m','o'),
|
||||
HB_TAG('t','j','m','o')
|
||||
};
|
||||
|
||||
static void
|
||||
collect_features_hangul (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
|
||||
map->add_feature (hangul_features[i], 1, F_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
override_features_hangul (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
/* Uniscribe does not apply 'calt' for Hangul, and certain fonts
|
||||
* (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
|
||||
* in calt, which is not desirable. */
|
||||
plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
|
||||
}
|
||||
|
||||
struct hangul_shape_plan_t
|
||||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
hb_mask_t mask_array[HANGUL_FEATURE_COUNT];
|
||||
};
|
||||
|
||||
static void *
|
||||
data_create_hangul (const hb_ot_shape_plan_t *plan)
|
||||
{
|
||||
hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
|
||||
if (unlikely (!hangul_plan))
|
||||
return NULL;
|
||||
|
||||
for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
|
||||
hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
|
||||
|
||||
return hangul_plan;
|
||||
}
|
||||
|
||||
static void
|
||||
data_destroy_hangul (void *data)
|
||||
{
|
||||
free (data);
|
||||
}
|
||||
|
||||
/* Constants for algorithmic hangul syllable [de]composition. */
|
||||
#define LBase 0x1100u
|
||||
#define VBase 0x1161u
|
||||
#define TBase 0x11A7u
|
||||
#define LCount 19u
|
||||
#define VCount 21u
|
||||
#define TCount 28u
|
||||
#define SBase 0xAC00u
|
||||
#define NCount (VCount * TCount)
|
||||
#define SCount (LCount * NCount)
|
||||
|
||||
#define isCombiningL(u) (hb_in_range ((u), LBase, LBase+LCount-1))
|
||||
#define isCombiningV(u) (hb_in_range ((u), VBase, VBase+VCount-1))
|
||||
#define isCombiningT(u) (hb_in_range ((u), TBase+1, TBase+TCount-1))
|
||||
#define isCombinedS(u) (hb_in_range ((u), SBase, SBase+SCount-1))
|
||||
|
||||
#define isL(u) (hb_in_ranges ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
|
||||
#define isV(u) (hb_in_ranges ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
|
||||
#define isT(u) (hb_in_ranges ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
|
||||
|
||||
#define isHangulTone(u) (hb_in_range ((u), 0x302Eu, 0x302Fu))
|
||||
|
||||
/* buffer var allocations */
|
||||
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
|
||||
|
||||
static bool
|
||||
is_zero_width_char (hb_font_t *font,
|
||||
hb_codepoint_t unicode)
|
||||
{
|
||||
hb_codepoint_t glyph;
|
||||
return hb_font_get_glyph (font, unicode, 0, &glyph) && hb_font_get_glyph_h_advance (font, glyph) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, hangul_shaping_feature);
|
||||
|
||||
/* Hangul syllables come in two shapes: LV, and LVT. Of those:
|
||||
*
|
||||
* - LV can be precomposed, or decomposed. Lets call those
|
||||
* <LV> and <L,V>,
|
||||
* - LVT can be fully precomposed, partically precomposed, or
|
||||
* fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
|
||||
*
|
||||
* The composition / decomposition is mechanical. However, not
|
||||
* all <L,V> sequences compose, and not all <LV,T> sequences
|
||||
* compose.
|
||||
*
|
||||
* Here are the specifics:
|
||||
*
|
||||
* - <L>: U+1100..115F, U+A960..A97F
|
||||
* - <V>: U+1160..11A7, U+D7B0..D7C7
|
||||
* - <T>: U+11A8..11FF, U+D7CB..D7FB
|
||||
*
|
||||
* - Only the <L,V> sequences for the 11xx ranges combine.
|
||||
* - Only <LV,T> sequences for T in U+11A8..11C3 combine.
|
||||
*
|
||||
* Here is what we want to accomplish in this shaper:
|
||||
*
|
||||
* - If the whole syllable can be precomposed, do that,
|
||||
* - Otherwise, fully decompose and apply ljmo/vjmo/tjmo features.
|
||||
* - If a valid syllable is followed by a Hangul tone mark, reorder the tone
|
||||
* mark to precede the whole syllable - unless it is a zero-width glyph, in
|
||||
* which case we leave it untouched, assuming it's designed to overstrike.
|
||||
*
|
||||
* That is, of the different possible syllables:
|
||||
*
|
||||
* <L>
|
||||
* <L,V>
|
||||
* <L,V,T>
|
||||
* <LV>
|
||||
* <LVT>
|
||||
* <LV, T>
|
||||
*
|
||||
* - <L> needs no work.
|
||||
*
|
||||
* - <LV> and <LVT> can stay the way they are if the font supports them, otherwise we
|
||||
* should fully decompose them if font supports.
|
||||
*
|
||||
* - <L,V> and <L,V,T> we should compose if the whole thing can be composed.
|
||||
*
|
||||
* - <LV,T> we should compose if the whole thing can be composed, otherwise we should
|
||||
* decompose.
|
||||
*/
|
||||
|
||||
buffer->clear_output ();
|
||||
unsigned int start = 0, end = 0; /* Extent of most recently seen syllable;
|
||||
* valid only if start < end
|
||||
*/
|
||||
unsigned int count = buffer->len;
|
||||
|
||||
for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;)
|
||||
{
|
||||
hb_codepoint_t u = buffer->cur().codepoint;
|
||||
|
||||
if (isHangulTone (u))
|
||||
{
|
||||
/*
|
||||
* We could cache the width of the tone marks and the existence of dotted-circle,
|
||||
* but the use of the Hangul tone mark characters seems to be rare enough that
|
||||
* I didn't bother for now.
|
||||
*/
|
||||
if (start < end && end == buffer->out_len)
|
||||
{
|
||||
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
|
||||
buffer->next_glyph ();
|
||||
if (!is_zero_width_char (font, u))
|
||||
{
|
||||
buffer->merge_out_clusters (start, end + 1);
|
||||
hb_glyph_info_t *info = buffer->out_info;
|
||||
hb_glyph_info_t tone = info[end];
|
||||
memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t));
|
||||
info[start] = tone;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No valid syllable as base for tone mark; try to insert dotted circle. */
|
||||
if (font->has_glyph (0x25CCu))
|
||||
{
|
||||
hb_codepoint_t chars[2];
|
||||
if (!is_zero_width_char (font, u)) {
|
||||
chars[0] = u;
|
||||
chars[1] = 0x25CCu;
|
||||
} else {
|
||||
chars[0] = 0x25CCu;
|
||||
chars[1] = u;
|
||||
}
|
||||
buffer->replace_glyphs (1, 2, chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No dotted circle available in the font; just leave tone mark untouched. */
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
}
|
||||
start = end = buffer->out_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
start = buffer->out_len; /* Remember current position as a potential syllable start;
|
||||
* will only be used if we set end to a later position.
|
||||
*/
|
||||
|
||||
if (isL (u) && buffer->idx + 1 < count)
|
||||
{
|
||||
hb_codepoint_t l = u;
|
||||
hb_codepoint_t v = buffer->cur(+1).codepoint;
|
||||
if (isV (v))
|
||||
{
|
||||
/* Have <L,V> or <L,V,T>. */
|
||||
hb_codepoint_t t = 0;
|
||||
unsigned int tindex = 0;
|
||||
if (buffer->idx + 2 < count)
|
||||
{
|
||||
t = buffer->cur(+2).codepoint;
|
||||
if (isT (t))
|
||||
tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
|
||||
else
|
||||
t = 0; /* The next character was not a trailing jamo. */
|
||||
}
|
||||
|
||||
/* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
|
||||
if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
|
||||
{
|
||||
/* Try to compose; if this succeeds, end is set to start+1. */
|
||||
hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
|
||||
if (font->has_glyph (s))
|
||||
{
|
||||
buffer->replace_glyphs (t ? 3 : 2, 1, &s);
|
||||
if (unlikely (buffer->in_error))
|
||||
return;
|
||||
end = start + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* We didn't compose, either because it's an Old Hangul syllable without a
|
||||
* precomposed character in Unicode, or because the font didn't support the
|
||||
* necessary precomposed glyph.
|
||||
* Set jamo features on the individual glyphs, and advance past them.
|
||||
*/
|
||||
buffer->cur().hangul_shaping_feature() = LJMO;
|
||||
buffer->next_glyph ();
|
||||
buffer->cur().hangul_shaping_feature() = VJMO;
|
||||
buffer->next_glyph ();
|
||||
if (t)
|
||||
{
|
||||
buffer->cur().hangul_shaping_feature() = TJMO;
|
||||
buffer->next_glyph ();
|
||||
end = start + 3;
|
||||
}
|
||||
else
|
||||
end = start + 2;
|
||||
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
|
||||
buffer->merge_out_clusters (start, end);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else if (isCombinedS (u))
|
||||
{
|
||||
/* Have <LV>, <LVT>, or <LV,T> */
|
||||
hb_codepoint_t s = u;
|
||||
bool has_glyph = font->has_glyph (s);
|
||||
unsigned int lindex = (s - SBase) / NCount;
|
||||
unsigned int nindex = (s - SBase) % NCount;
|
||||
unsigned int vindex = nindex / TCount;
|
||||
unsigned int tindex = nindex % TCount;
|
||||
|
||||
if (!tindex &&
|
||||
buffer->idx + 1 < count &&
|
||||
isCombiningT (buffer->cur(+1).codepoint))
|
||||
{
|
||||
/* <LV,T>, try to combine. */
|
||||
unsigned int new_tindex = buffer->cur(+1).codepoint - TBase;
|
||||
hb_codepoint_t new_s = s + new_tindex;
|
||||
if (font->has_glyph (new_s))
|
||||
{
|
||||
buffer->replace_glyphs (2, 1, &new_s);
|
||||
if (unlikely (buffer->in_error))
|
||||
return;
|
||||
end = start + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, decompose if font doesn't support <LV> or <LVT>,
|
||||
* or if having non-combining <LV,T>. Note that we already handled
|
||||
* combining <LV,T> above. */
|
||||
if (!has_glyph ||
|
||||
(!tindex &&
|
||||
buffer->idx + 1 < count &&
|
||||
isT (buffer->cur(+1).codepoint)))
|
||||
{
|
||||
hb_codepoint_t decomposed[3] = {LBase + lindex,
|
||||
VBase + vindex,
|
||||
TBase + tindex};
|
||||
if (font->has_glyph (decomposed[0]) &&
|
||||
font->has_glyph (decomposed[1]) &&
|
||||
(!tindex || font->has_glyph (decomposed[2])))
|
||||
{
|
||||
unsigned int s_len = tindex ? 3 : 2;
|
||||
buffer->replace_glyphs (1, s_len, decomposed);
|
||||
if (unlikely (buffer->in_error))
|
||||
return;
|
||||
|
||||
/* We decomposed S: apply jamo features to the individual glyphs
|
||||
* that are now in buffer->out_info.
|
||||
*/
|
||||
hb_glyph_info_t *info = buffer->out_info;
|
||||
|
||||
/* If we decomposed an LV because of a non-combining T following,
|
||||
* we want to include this T in the syllable.
|
||||
*/
|
||||
if (has_glyph && !tindex)
|
||||
{
|
||||
buffer->next_glyph ();
|
||||
s_len++;
|
||||
}
|
||||
end = start + s_len;
|
||||
|
||||
unsigned int i = start;
|
||||
info[i++].hangul_shaping_feature() = LJMO;
|
||||
info[i++].hangul_shaping_feature() = VJMO;
|
||||
if (i < end)
|
||||
info[i++].hangul_shaping_feature() = TJMO;
|
||||
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
|
||||
buffer->merge_out_clusters (start, end);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_glyph)
|
||||
{
|
||||
/* We didn't decompose the S, so just advance past it. */
|
||||
end = start + 1;
|
||||
buffer->next_glyph ();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Didn't find a recognizable syllable, so we leave end <= start;
|
||||
* this will prevent tone-mark reordering happening.
|
||||
*/
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
|
||||
static void
|
||||
setup_masks_hangul (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
const hangul_shape_plan_t *hangul_plan = (const hangul_shape_plan_t *) plan->data;
|
||||
|
||||
if (likely (hangul_plan))
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++, info++)
|
||||
info->mask |= hangul_plan->mask_array[info->hangul_shaping_feature()];
|
||||
}
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, hangul_shaping_feature);
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
|
||||
{
|
||||
"hangul",
|
||||
collect_features_hangul,
|
||||
override_features_hangul,
|
||||
data_create_hangul,
|
||||
data_destroy_hangul,
|
||||
preprocess_text_hangul,
|
||||
NULL, /* postprocess_glyphs */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
|
||||
NULL, /* decompose */
|
||||
NULL, /* compose */
|
||||
setup_masks_hangul,
|
||||
NULL, /* disable_otl */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||
false, /* fallback_position */
|
||||
};
|
||||
186
gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
Normal file
186
gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright © 2010,2012 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
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
|
||||
|
||||
static bool
|
||||
compose_hebrew (const hb_ot_shape_normalize_context_t *c,
|
||||
hb_codepoint_t a,
|
||||
hb_codepoint_t b,
|
||||
hb_codepoint_t *ab)
|
||||
{
|
||||
/* Hebrew presentation-form shaping.
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
|
||||
* Hebrew presentation forms with dagesh, for characters U+05D0..05EA;
|
||||
* Note that some letters do not have a dagesh presForm encoded.
|
||||
*/
|
||||
static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = {
|
||||
0xFB30u, /* ALEF */
|
||||
0xFB31u, /* BET */
|
||||
0xFB32u, /* GIMEL */
|
||||
0xFB33u, /* DALET */
|
||||
0xFB34u, /* HE */
|
||||
0xFB35u, /* VAV */
|
||||
0xFB36u, /* ZAYIN */
|
||||
0x0000u, /* HET */
|
||||
0xFB38u, /* TET */
|
||||
0xFB39u, /* YOD */
|
||||
0xFB3Au, /* FINAL KAF */
|
||||
0xFB3Bu, /* KAF */
|
||||
0xFB3Cu, /* LAMED */
|
||||
0x0000u, /* FINAL MEM */
|
||||
0xFB3Eu, /* MEM */
|
||||
0x0000u, /* FINAL NUN */
|
||||
0xFB40u, /* NUN */
|
||||
0xFB41u, /* SAMEKH */
|
||||
0x0000u, /* AYIN */
|
||||
0xFB43u, /* FINAL PE */
|
||||
0xFB44u, /* PE */
|
||||
0x0000u, /* FINAL TSADI */
|
||||
0xFB46u, /* TSADI */
|
||||
0xFB47u, /* QOF */
|
||||
0xFB48u, /* RESH */
|
||||
0xFB49u, /* SHIN */
|
||||
0xFB4Au /* TAV */
|
||||
};
|
||||
|
||||
bool found = (bool) c->unicode->compose (a, b, ab);
|
||||
|
||||
if (!found && !c->plan->has_mark)
|
||||
{
|
||||
/* Special-case Hebrew presentation forms that are excluded from
|
||||
* standard normalization, but wanted for old fonts. */
|
||||
switch (b) {
|
||||
case 0x05B4u: /* HIRIQ */
|
||||
if (a == 0x05D9u) { /* YOD */
|
||||
*ab = 0xFB1Du;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B7u: /* patah */
|
||||
if (a == 0x05F2u) { /* YIDDISH YOD YOD */
|
||||
*ab = 0xFB1Fu;
|
||||
found = true;
|
||||
} else if (a == 0x05D0u) { /* ALEF */
|
||||
*ab = 0xFB2Eu;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B8u: /* QAMATS */
|
||||
if (a == 0x05D0u) { /* ALEF */
|
||||
*ab = 0xFB2Fu;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05B9u: /* HOLAM */
|
||||
if (a == 0x05D5u) { /* VAV */
|
||||
*ab = 0xFB4Bu;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05BCu: /* DAGESH */
|
||||
if (a >= 0x05D0u && a <= 0x05EAu) {
|
||||
*ab = sDageshForms[a - 0x05D0u];
|
||||
found = (*ab != 0);
|
||||
} else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */
|
||||
*ab = 0xFB2Cu;
|
||||
found = true;
|
||||
} else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */
|
||||
*ab = 0xFB2Du;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05BFu: /* RAFE */
|
||||
switch (a) {
|
||||
case 0x05D1u: /* BET */
|
||||
*ab = 0xFB4Cu;
|
||||
found = true;
|
||||
break;
|
||||
case 0x05DBu: /* KAF */
|
||||
*ab = 0xFB4Du;
|
||||
found = true;
|
||||
break;
|
||||
case 0x05E4u: /* PE */
|
||||
*ab = 0xFB4Eu;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x05C1u: /* SHIN DOT */
|
||||
if (a == 0x05E9u) { /* SHIN */
|
||||
*ab = 0xFB2Au;
|
||||
found = true;
|
||||
} else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
|
||||
*ab = 0xFB2Cu;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
case 0x05C2u: /* SIN DOT */
|
||||
if (a == 0x05E9u) { /* SHIN */
|
||||
*ab = 0xFB2Bu;
|
||||
found = true;
|
||||
} else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
|
||||
*ab = 0xFB2Du;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool
|
||||
disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
|
||||
{
|
||||
/* For Hebrew shaper, use fallback if GPOS does not have 'hebr'
|
||||
* script. This matches Uniscribe better, and makes fonts like
|
||||
* Arial that have GSUB/GPOS/GDEF but no data for Hebrew work.
|
||||
* See:
|
||||
* https://github.com/behdad/harfbuzz/issues/347#issuecomment-267838368
|
||||
*/
|
||||
return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r');
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
|
||||
{
|
||||
"hebrew",
|
||||
NULL, /* collect_features */
|
||||
NULL, /* override_features */
|
||||
NULL, /* data_create */
|
||||
NULL, /* data_destroy */
|
||||
NULL, /* preprocess_text */
|
||||
NULL, /* postprocess_glyphs */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
|
||||
NULL, /* decompose */
|
||||
compose_hebrew,
|
||||
NULL, /* setup_masks */
|
||||
disable_otl_hebrew,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||
true, /* fallback_position */
|
||||
};
|
||||
1564
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
Normal file
1564
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh
Normal file
File diff suppressed because it is too large
Load diff
129
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.rl
Normal file
129
gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.rl
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_SHAPE_COMPLEX_INDIC_MACHINE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
%%{
|
||||
machine indic_syllable_machine;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
}%%
|
||||
|
||||
%%{
|
||||
|
||||
# Same order as enum indic_category_t. Not sure how to avoid duplication.
|
||||
X = 0;
|
||||
C = 1;
|
||||
V = 2;
|
||||
N = 3;
|
||||
H = 4;
|
||||
ZWNJ = 5;
|
||||
ZWJ = 6;
|
||||
M = 7;
|
||||
SM = 8;
|
||||
VD = 9;
|
||||
A = 10;
|
||||
PLACEHOLDER = 11;
|
||||
DOTTEDCIRCLE = 12;
|
||||
RS = 13;
|
||||
Coeng = 14;
|
||||
Repha = 15;
|
||||
Ra = 16;
|
||||
CM = 17;
|
||||
Symbol= 18;
|
||||
|
||||
c = (C | Ra); # is_consonant
|
||||
n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier
|
||||
z = ZWJ|ZWNJ; # is_joiner
|
||||
h = H | Coeng; # is_halant_or_coeng
|
||||
reph = (Ra H | Repha); # possible reph
|
||||
|
||||
cn = c.ZWJ?.n?;
|
||||
forced_rakar = ZWJ H ZWJ Ra;
|
||||
symbol = Symbol.N?;
|
||||
matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
|
||||
syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}? VD{0,2};
|
||||
place_holder = PLACEHOLDER | DOTTEDCIRCLE;
|
||||
halant_group = (z?.h.(ZWJ.N?)?);
|
||||
final_halant_group = halant_group | h.ZWNJ;
|
||||
medial_group = CM?;
|
||||
halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}) (Coeng (cn|V))?;
|
||||
|
||||
|
||||
consonant_syllable = Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
|
||||
vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
|
||||
standalone_cluster = (Repha? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
||||
symbol_cluster = symbol syllable_tail;
|
||||
broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
||||
other = any;
|
||||
|
||||
main := |*
|
||||
consonant_syllable => { found_syllable (consonant_syllable); };
|
||||
vowel_syllable => { found_syllable (vowel_syllable); };
|
||||
standalone_cluster => { found_syllable (standalone_cluster); };
|
||||
symbol_cluster => { found_syllable (symbol_cluster); };
|
||||
broken_cluster => { found_syllable (broken_cluster); };
|
||||
other => { found_syllable (non_indic_cluster); };
|
||||
*|;
|
||||
|
||||
|
||||
}%%
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
|
||||
for (unsigned int i = last; i < p+1; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
last = p+1; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
|
||||
int cs;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
%%{
|
||||
write init;
|
||||
getkey info[p].indic_category();
|
||||
}%%
|
||||
|
||||
p = 0;
|
||||
pe = eof = buffer->len;
|
||||
|
||||
unsigned int last = 0;
|
||||
unsigned int syllable_serial = 1;
|
||||
%%{
|
||||
write exec;
|
||||
}%%
|
||||
}
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
|
||||
189
gfx/harfbuzz/src/hb-ot-shape-complex-indic-private.hh
Normal file
189
gfx/harfbuzz/src/hb-ot-shape-complex-indic-private.hh
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright © 2012 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_SHAPE_COMPLEX_INDIC_PRIVATE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-private.hh" /* XXX Remove */
|
||||
|
||||
|
||||
#define INDIC_TABLE_ELEMENT_TYPE uint16_t
|
||||
|
||||
/* Cateories used in the OpenType spec:
|
||||
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
|
||||
*/
|
||||
/* Note: This enum is duplicated in the -machine.rl source file.
|
||||
* Not sure how to avoid duplication. */
|
||||
enum indic_category_t {
|
||||
OT_X = 0,
|
||||
OT_C = 1,
|
||||
OT_V = 2,
|
||||
OT_N = 3,
|
||||
OT_H = 4,
|
||||
OT_ZWNJ = 5,
|
||||
OT_ZWJ = 6,
|
||||
OT_M = 7,
|
||||
OT_SM = 8,
|
||||
OT_VD = 9,
|
||||
OT_A = 10,
|
||||
OT_PLACEHOLDER = 11,
|
||||
OT_DOTTEDCIRCLE = 12,
|
||||
OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
|
||||
OT_Coeng = 14, /* Khmer-style Virama. */
|
||||
OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
|
||||
OT_Ra = 16,
|
||||
OT_CM = 17, /* Consonant-Medial. */
|
||||
OT_Symbol = 18 /* Avagraha, etc that take marks (SM,A,VD). */
|
||||
};
|
||||
|
||||
#define MEDIAL_FLAGS (FLAG (OT_CM))
|
||||
|
||||
/* Note:
|
||||
*
|
||||
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
|
||||
* cannot happen in a consonant syllable. The plus side however is, we can call the
|
||||
* consonant syllable logic from the vowel syllable function and get it all right! */
|
||||
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
|
||||
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
|
||||
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
|
||||
|
||||
|
||||
/* Visual positions in a syllable from left to right. */
|
||||
enum indic_position_t {
|
||||
POS_START,
|
||||
|
||||
POS_RA_TO_BECOME_REPH,
|
||||
POS_PRE_M,
|
||||
POS_PRE_C,
|
||||
|
||||
POS_BASE_C,
|
||||
POS_AFTER_MAIN,
|
||||
|
||||
POS_ABOVE_C,
|
||||
|
||||
POS_BEFORE_SUB,
|
||||
POS_BELOW_C,
|
||||
POS_AFTER_SUB,
|
||||
|
||||
POS_BEFORE_POST,
|
||||
POS_POST_C,
|
||||
POS_AFTER_POST,
|
||||
|
||||
POS_FINAL_C,
|
||||
POS_SMVD,
|
||||
|
||||
POS_END
|
||||
};
|
||||
|
||||
/* Categories used in IndicSyllabicCategory.txt from UCD. */
|
||||
enum indic_syllabic_category_t {
|
||||
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
|
||||
|
||||
INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol,
|
||||
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
|
||||
INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* Don't care. */
|
||||
INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER = OT_M, /* U+17CD only. */
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N,
|
||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_Repha, /* TODO */
|
||||
INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM,
|
||||
INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng,
|
||||
INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ,
|
||||
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
|
||||
INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ,
|
||||
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
|
||||
INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER,
|
||||
INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* Don't care. */
|
||||
INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_M, /* Is like a vowel matra. */
|
||||
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
|
||||
INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_M, /* Misc Khmer signs. */
|
||||
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
|
||||
INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
|
||||
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
|
||||
INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
|
||||
INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
|
||||
};
|
||||
|
||||
/* Categories used in IndicSMatraCategory.txt from UCD */
|
||||
enum indic_matra_category_t {
|
||||
INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
|
||||
|
||||
INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
|
||||
INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
|
||||
INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
|
||||
INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
|
||||
|
||||
/* These should resolve to the position of the last part of the split sequence. */
|
||||
INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||
|
||||
INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
|
||||
INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
|
||||
};
|
||||
|
||||
#define INDIC_COMBINE_CATEGORIES(S,M) \
|
||||
( \
|
||||
ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
|
||||
( S | \
|
||||
( \
|
||||
( \
|
||||
S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \
|
||||
S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \
|
||||
S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \
|
||||
S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \
|
||||
S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \
|
||||
S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \
|
||||
false \
|
||||
? M : INDIC_MATRA_CATEGORY_NOT_APPLICABLE \
|
||||
) << 8 \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
|
||||
hb_indic_get_categories (hb_codepoint_t u);
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
|
||||
484
gfx/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
Normal file
484
gfx/harfbuzz/src/hb-ot-shape-complex-indic-table.cc
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/* == Start of generated table == */
|
||||
/*
|
||||
* The following table is generated by running:
|
||||
*
|
||||
* ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
|
||||
*
|
||||
* on files with these headers:
|
||||
*
|
||||
* # IndicSyllabicCategory-9.0.0.txt
|
||||
* # Date: 2016-05-21, 02:46:00 GMT [RP]
|
||||
* # IndicPositionalCategory-9.0.0.txt
|
||||
* # Date: 2016-02-25, 00:48:00 GMT [RP]
|
||||
* # Blocks-9.0.0.txt
|
||||
* # Date: 2016-02-05, 23:48:00 GMT [KW]
|
||||
*/
|
||||
|
||||
#include "hb-ot-shape-complex-indic-private.hh"
|
||||
|
||||
|
||||
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 15 chars; Avagraha */
|
||||
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 67 chars; Bindu */
|
||||
#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
|
||||
#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 53 chars; Cantillation_Mark */
|
||||
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1907 chars; Consonant */
|
||||
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 10 chars; Consonant_Dead */
|
||||
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */
|
||||
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
|
||||
#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
|
||||
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */
|
||||
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 16 chars; Consonant_Placeholder */
|
||||
#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */
|
||||
#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */
|
||||
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 90 chars; Consonant_Subjoined */
|
||||
#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */
|
||||
#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */
|
||||
#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */
|
||||
#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */
|
||||
#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
|
||||
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
|
||||
#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
|
||||
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 24 chars; Nukta */
|
||||
#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 459 chars; Number */
|
||||
#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
|
||||
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
|
||||
#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */
|
||||
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
|
||||
#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 22 chars; Syllable_Modifier */
|
||||
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
|
||||
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
|
||||
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 24 chars; Virama */
|
||||
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 31 chars; Visarga */
|
||||
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
|
||||
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 602 chars; Vowel_Dependent */
|
||||
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 431 chars; Vowel_Independent */
|
||||
|
||||
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 300 chars; Bottom */
|
||||
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
|
||||
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 57 chars; Left */
|
||||
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */
|
||||
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
|
||||
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
|
||||
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 258 chars; Right */
|
||||
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 342 chars; Top */
|
||||
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
|
||||
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
|
||||
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
|
||||
#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */
|
||||
#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */
|
||||
#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */
|
||||
|
||||
#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
|
||||
|
||||
|
||||
static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
|
||||
|
||||
|
||||
#define indic_offset_0x0028u 0
|
||||
|
||||
|
||||
/* Basic Latin */
|
||||
|
||||
/* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), _(x,x),
|
||||
/* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x00b0u 24
|
||||
|
||||
|
||||
/* Latin-1 Supplement */
|
||||
|
||||
/* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x),
|
||||
|
||||
#define indic_offset_0x0900u 64
|
||||
|
||||
|
||||
/* Devanagari */
|
||||
|
||||
/* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,B), _(A,x), _(M,R), _(M,L),
|
||||
/* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
|
||||
/* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
|
||||
/* 0950 */ _(x,x), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(M,T), _(M,B), _(M,B),
|
||||
/* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
|
||||
/* Bengali */
|
||||
|
||||
/* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
|
||||
/* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
||||
/* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
|
||||
/* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
||||
/* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Gurmukhi */
|
||||
|
||||
/* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L),
|
||||
/* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
|
||||
/* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
|
||||
/* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
|
||||
/* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0A70 */ _(Bi,T), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,B), _(x,x), _(x,x),
|
||||
/* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Gujarati */
|
||||
|
||||
/* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
|
||||
/* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L),
|
||||
/* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
|
||||
/* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
|
||||
/* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Oriya */
|
||||
|
||||
/* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
|
||||
/* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
||||
/* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
|
||||
/* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR),
|
||||
/* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
||||
/* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Tamil */
|
||||
|
||||
/* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
||||
/* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
|
||||
/* 0BC0 */ _(M,T), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
|
||||
/* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
|
||||
/* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Telugu */
|
||||
|
||||
/* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T),
|
||||
/* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
|
||||
/* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
|
||||
/* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
|
||||
/* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Kannada */
|
||||
|
||||
/* 0C80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T),
|
||||
/* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
|
||||
/* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
|
||||
/* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
|
||||
/* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x),
|
||||
/* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
/* Malayalam */
|
||||
|
||||
/* 0D00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
||||
/* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
|
||||
/* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
|
||||
/* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,x), _(x,x),
|
||||
/* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R),
|
||||
/* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
|
||||
/* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
|
||||
|
||||
/* Sinhala */
|
||||
|
||||
/* 0D80 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
|
||||
/* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
|
||||
/* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
||||
/* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
||||
/* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
|
||||
/* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR),_(M,TLR), _(M,LR), _(M,R),
|
||||
/* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
|
||||
/* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1000u 1336
|
||||
|
||||
|
||||
/* Myanmar */
|
||||
|
||||
/* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
|
||||
/* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B),
|
||||
/* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x),
|
||||
/* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x),
|
||||
/* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
|
||||
/* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B),
|
||||
/* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R),
|
||||
/* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(C,x), _(C,x),
|
||||
/* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
|
||||
/* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1080 */ _(C,x), _(C,x), _(CM,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R),
|
||||
/* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R),
|
||||
/* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1780u 1496
|
||||
|
||||
|
||||
/* Khmer */
|
||||
|
||||
/* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
||||
/* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
|
||||
/* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
|
||||
/* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,T), _(Vs,R),
|
||||
/* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T),
|
||||
/* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(SM,T), _(x,x), _(x,x),
|
||||
/* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x1cd0u 1608
|
||||
|
||||
|
||||
/* Vedic Extensions */
|
||||
|
||||
/* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B),
|
||||
/* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
|
||||
/* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O),
|
||||
/* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x),
|
||||
/* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x),
|
||||
/* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x2008u 1656
|
||||
|
||||
|
||||
/* General Punctuation */
|
||||
|
||||
/* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x),
|
||||
/* 2010 */ _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0x2070u 1672
|
||||
|
||||
|
||||
/* Superscripts and Subscripts */
|
||||
|
||||
/* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
/* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0xa8e0u 1696
|
||||
|
||||
|
||||
/* Devanagari Extended */
|
||||
|
||||
/* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
|
||||
/* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
|
||||
/* A8F0 */ _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
||||
|
||||
#define indic_offset_0xa9e0u 1720
|
||||
|
||||
|
||||
/* Myanmar Extended-B */
|
||||
|
||||
/* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x),
|
||||
/* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
|
||||
/* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
||||
|
||||
#define indic_offset_0xaa60u 1752
|
||||
|
||||
|
||||
/* Myanmar Extended-A */
|
||||
|
||||
/* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
||||
/* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x),
|
||||
/* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x),
|
||||
|
||||
}; /* Table items: 1784; occupancy: 69% */
|
||||
|
||||
INDIC_TABLE_ELEMENT_TYPE
|
||||
hb_indic_get_categories (hb_codepoint_t u)
|
||||
{
|
||||
switch (u >> 12)
|
||||
{
|
||||
case 0x0u:
|
||||
if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
|
||||
if (hb_in_range (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
|
||||
if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
|
||||
if (unlikely (u == 0x00A0u)) return _(CP,x);
|
||||
break;
|
||||
|
||||
case 0x1u:
|
||||
if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
|
||||
if (hb_in_range (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u];
|
||||
if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
|
||||
break;
|
||||
|
||||
case 0x2u:
|
||||
if (hb_in_range (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
|
||||
if (hb_in_range (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
|
||||
if (unlikely (u == 0x25CCu)) return _(CP,x);
|
||||
break;
|
||||
|
||||
case 0xAu:
|
||||
if (hb_in_range (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
|
||||
if (hb_in_range (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
|
||||
if (hb_in_range (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return _(x,x);
|
||||
}
|
||||
|
||||
#undef _
|
||||
|
||||
#undef ISC_A
|
||||
#undef ISC_Bi
|
||||
#undef ISC_BJN
|
||||
#undef ISC_Ca
|
||||
#undef ISC_C
|
||||
#undef ISC_CD
|
||||
#undef ISC_CF
|
||||
#undef ISC_CHL
|
||||
#undef ISC_CK
|
||||
#undef ISC_CM
|
||||
#undef ISC_CP
|
||||
#undef ISC_CPR
|
||||
#undef ISC_CPrf
|
||||
#undef ISC_CS
|
||||
#undef ISC_CSR
|
||||
#undef ISC_CWS
|
||||
#undef ISC_GM
|
||||
#undef ISC_IS
|
||||
#undef ISC_ZWJ
|
||||
#undef ISC_ML
|
||||
#undef ISC_ZWNJ
|
||||
#undef ISC_N
|
||||
#undef ISC_Nd
|
||||
#undef ISC_NJ
|
||||
#undef ISC_x
|
||||
#undef ISC_PK
|
||||
#undef ISC_RS
|
||||
#undef ISC_SM
|
||||
#undef ISC_TL
|
||||
#undef ISC_TM
|
||||
#undef ISC_V
|
||||
#undef ISC_Vs
|
||||
#undef ISC_Vo
|
||||
#undef ISC_M
|
||||
#undef ISC_VI
|
||||
|
||||
#undef IMC_B
|
||||
#undef IMC_BR
|
||||
#undef IMC_L
|
||||
#undef IMC_LR
|
||||
#undef IMC_x
|
||||
#undef IMC_O
|
||||
#undef IMC_R
|
||||
#undef IMC_T
|
||||
#undef IMC_TB
|
||||
#undef IMC_TBR
|
||||
#undef IMC_TL
|
||||
#undef IMC_TLR
|
||||
#undef IMC_TR
|
||||
#undef IMC_VOL
|
||||
|
||||
/* == End of generated table == */
|
||||
1820
gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc
Normal file
1820
gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc
Normal file
File diff suppressed because it is too large
Load diff
400
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
Normal file
400
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
|
||||
#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
/*
|
||||
* Copyright © 2011,2012 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_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
|
||||
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
|
||||
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_key_spans[] = {
|
||||
31, 28, 25, 4, 25, 23, 21, 21,
|
||||
27, 27, 27, 27, 16, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 25, 4,
|
||||
25, 23, 21, 21, 27, 27, 27, 27,
|
||||
28, 27, 30, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 1
|
||||
};
|
||||
|
||||
static const short _myanmar_syllable_machine_index_offsets[] = {
|
||||
0, 32, 61, 87, 92, 118, 142, 164,
|
||||
186, 214, 242, 270, 298, 315, 343, 371,
|
||||
399, 427, 455, 483, 511, 539, 567, 593,
|
||||
598, 624, 648, 670, 692, 720, 748, 776,
|
||||
804, 833, 861, 892, 920, 948, 976, 1004,
|
||||
1032, 1060, 1088, 1116, 1144
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_indicies[] = {
|
||||
1, 1, 2, 3, 4, 4, 0, 5,
|
||||
0, 6, 1, 0, 0, 0, 0, 7,
|
||||
0, 8, 1, 0, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 18, 19, 0,
|
||||
21, 22, 23, 23, 20, 24, 20, 25,
|
||||
20, 20, 20, 20, 20, 20, 20, 26,
|
||||
20, 20, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 20, 23, 23, 20,
|
||||
24, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 37, 20, 20, 20, 20, 20,
|
||||
20, 31, 20, 20, 20, 35, 20, 23,
|
||||
23, 20, 24, 20, 23, 23, 20, 24,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
31, 20, 20, 20, 35, 20, 38, 20,
|
||||
23, 23, 20, 24, 20, 31, 20, 20,
|
||||
20, 20, 20, 20, 20, 39, 20, 20,
|
||||
20, 20, 20, 20, 31, 20, 23, 23,
|
||||
20, 24, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 39, 20, 20, 20, 20,
|
||||
20, 20, 31, 20, 23, 23, 20, 24,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
31, 20, 21, 20, 23, 23, 20, 24,
|
||||
20, 25, 20, 20, 20, 20, 20, 20,
|
||||
20, 40, 20, 20, 40, 20, 20, 20,
|
||||
31, 41, 20, 20, 35, 20, 21, 20,
|
||||
23, 23, 20, 24, 20, 25, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 31, 20, 20, 20,
|
||||
35, 20, 21, 20, 23, 23, 20, 24,
|
||||
20, 25, 20, 20, 20, 20, 20, 20,
|
||||
20, 40, 20, 20, 20, 20, 20, 20,
|
||||
31, 41, 20, 20, 35, 20, 21, 20,
|
||||
23, 23, 20, 24, 20, 25, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 31, 41, 20, 20,
|
||||
35, 20, 1, 1, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 1, 20, 21, 20, 23, 23, 20,
|
||||
24, 20, 25, 20, 20, 20, 20, 20,
|
||||
20, 20, 26, 20, 20, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 20, 21,
|
||||
20, 23, 23, 20, 24, 20, 25, 20,
|
||||
20, 20, 20, 20, 20, 20, 34, 20,
|
||||
20, 20, 20, 20, 20, 31, 32, 33,
|
||||
34, 35, 20, 21, 20, 23, 23, 20,
|
||||
24, 20, 25, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 31, 32, 33, 34, 35, 20, 21,
|
||||
20, 23, 23, 20, 24, 20, 25, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 31, 32, 33,
|
||||
20, 35, 20, 21, 20, 23, 23, 20,
|
||||
24, 20, 25, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 31, 20, 33, 20, 35, 20, 21,
|
||||
20, 23, 23, 20, 24, 20, 25, 20,
|
||||
20, 20, 20, 20, 20, 20, 34, 20,
|
||||
20, 27, 20, 29, 20, 31, 32, 33,
|
||||
34, 35, 20, 21, 20, 23, 23, 20,
|
||||
24, 20, 25, 20, 20, 20, 20, 20,
|
||||
20, 20, 34, 20, 20, 27, 20, 20,
|
||||
20, 31, 32, 33, 34, 35, 20, 21,
|
||||
20, 23, 23, 20, 24, 20, 25, 20,
|
||||
20, 20, 20, 20, 20, 20, 34, 20,
|
||||
20, 27, 28, 29, 20, 31, 32, 33,
|
||||
34, 35, 20, 21, 22, 23, 23, 20,
|
||||
24, 20, 25, 20, 20, 20, 20, 20,
|
||||
20, 20, 26, 20, 20, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 20, 3,
|
||||
3, 42, 5, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 43, 42, 42, 42,
|
||||
42, 42, 42, 13, 42, 42, 42, 17,
|
||||
42, 3, 3, 42, 5, 42, 3, 3,
|
||||
42, 5, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 13, 42, 42, 42, 17, 42,
|
||||
44, 42, 3, 3, 42, 5, 42, 13,
|
||||
42, 42, 42, 42, 42, 42, 42, 45,
|
||||
42, 42, 42, 42, 42, 42, 13, 42,
|
||||
3, 3, 42, 5, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 45, 42, 42,
|
||||
42, 42, 42, 42, 13, 42, 3, 3,
|
||||
42, 5, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 13, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 46, 42, 42, 46, 42,
|
||||
42, 42, 13, 47, 42, 42, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 13, 42,
|
||||
42, 42, 17, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 46, 42, 42, 42, 42,
|
||||
42, 42, 13, 47, 42, 42, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 13, 47,
|
||||
42, 42, 17, 42, 21, 22, 23, 23,
|
||||
20, 24, 20, 25, 20, 20, 20, 20,
|
||||
20, 20, 20, 48, 20, 20, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36,
|
||||
20, 21, 49, 23, 23, 20, 24, 20,
|
||||
25, 20, 20, 20, 20, 20, 20, 20,
|
||||
26, 20, 20, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 20, 1, 1, 2,
|
||||
3, 3, 3, 42, 5, 42, 6, 1,
|
||||
42, 42, 42, 42, 1, 42, 8, 1,
|
||||
42, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 8, 42, 42, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 16,
|
||||
42, 42, 42, 42, 42, 42, 13, 14,
|
||||
15, 16, 17, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 13, 14, 15, 16, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 13, 14,
|
||||
15, 42, 17, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 42, 13, 42, 15, 42, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 16,
|
||||
42, 42, 9, 42, 11, 42, 13, 14,
|
||||
15, 16, 17, 42, 2, 42, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 16, 42, 42, 9, 42,
|
||||
42, 42, 13, 14, 15, 16, 17, 42,
|
||||
2, 42, 3, 3, 42, 5, 42, 6,
|
||||
42, 42, 42, 42, 42, 42, 42, 16,
|
||||
42, 42, 9, 10, 11, 42, 13, 14,
|
||||
15, 16, 17, 42, 2, 3, 3, 3,
|
||||
42, 5, 42, 6, 42, 42, 42, 42,
|
||||
42, 42, 42, 8, 42, 42, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 42,
|
||||
51, 50, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_trans_targs[] = {
|
||||
0, 1, 22, 0, 0, 23, 29, 32,
|
||||
35, 36, 40, 41, 42, 25, 38, 39,
|
||||
37, 28, 43, 44, 0, 2, 12, 0,
|
||||
3, 9, 13, 14, 18, 19, 20, 5,
|
||||
16, 17, 15, 8, 21, 4, 6, 7,
|
||||
10, 11, 0, 24, 26, 27, 30, 31,
|
||||
33, 34, 0, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_trans_actions[] = {
|
||||
3, 0, 0, 4, 5, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 6, 0, 0, 7,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 8, 0, 0, 0, 0, 0,
|
||||
0, 0, 9, 10
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_to_state_actions[] = {
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char _myanmar_syllable_machine_from_state_actions[] = {
|
||||
2, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const short _myanmar_syllable_machine_eof_trans[] = {
|
||||
0, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 43, 43,
|
||||
43, 43, 43, 43, 43, 43, 43, 43,
|
||||
21, 21, 43, 43, 43, 43, 43, 43,
|
||||
43, 43, 43, 43, 51
|
||||
};
|
||||
|
||||
static const int myanmar_syllable_machine_start = 0;
|
||||
static const int myanmar_syllable_machine_first_final = 0;
|
||||
static const int myanmar_syllable_machine_error = -1;
|
||||
|
||||
static const int myanmar_syllable_machine_en_main = 0;
|
||||
|
||||
|
||||
#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
|
||||
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
|
||||
for (unsigned int i = last; i < p+1; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
last = p+1; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
|
||||
int cs;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
{
|
||||
cs = myanmar_syllable_machine_start;
|
||||
ts = 0;
|
||||
te = 0;
|
||||
act = 0;
|
||||
}
|
||||
|
||||
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
p = 0;
|
||||
pe = eof = buffer->len;
|
||||
|
||||
unsigned int last = 0;
|
||||
unsigned int syllable_serial = 1;
|
||||
|
||||
#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
_resume:
|
||||
switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
|
||||
case 2:
|
||||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
break;
|
||||
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
|
||||
_inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
|
||||
|
||||
_slen = _myanmar_syllable_machine_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
|
||||
( info[p].myanmar_category()) <= _keys[1] ?
|
||||
( info[p].myanmar_category()) - _keys[0] : _slen ];
|
||||
|
||||
_eof_trans:
|
||||
cs = _myanmar_syllable_machine_trans_targs[_trans];
|
||||
|
||||
if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
|
||||
case 7:
|
||||
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 5:
|
||||
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||
break;
|
||||
case 10:
|
||||
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (punctuation_cluster); }}
|
||||
break;
|
||||
case 4:
|
||||
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
case 3:
|
||||
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||
break;
|
||||
case 6:
|
||||
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
||||
break;
|
||||
case 8:
|
||||
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p;p--;{ found_syllable (broken_cluster); }}
|
||||
break;
|
||||
case 9:
|
||||
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
|
||||
break;
|
||||
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
|
||||
case 1:
|
||||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
if ( p == eof )
|
||||
{
|
||||
if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
|
||||
_trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
|
||||
goto _eof_trans;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
|
||||
128
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
Normal file
128
gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright © 2011,2012 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_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
%%{
|
||||
machine myanmar_syllable_machine;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
}%%
|
||||
|
||||
%%{
|
||||
|
||||
# Same order as enum myanmar_category_t. Not sure how to avoid duplication.
|
||||
A = 10;
|
||||
As = 18;
|
||||
C = 1;
|
||||
D = 19;
|
||||
D0 = 20;
|
||||
DB = 3;
|
||||
GB = 11;
|
||||
H = 4;
|
||||
IV = 2;
|
||||
MH = 21;
|
||||
MR = 22;
|
||||
MW = 23;
|
||||
MY = 24;
|
||||
PT = 25;
|
||||
V = 8;
|
||||
VAbv = 26;
|
||||
VBlw = 27;
|
||||
VPre = 28;
|
||||
VPst = 29;
|
||||
VS = 30;
|
||||
ZWJ = 6;
|
||||
ZWNJ = 5;
|
||||
Ra = 16;
|
||||
P = 31;
|
||||
|
||||
j = ZWJ|ZWNJ; # Joiners
|
||||
k = (Ra As H); # Kinzi
|
||||
|
||||
c = C|Ra; # is_consonant
|
||||
|
||||
medial_group = MY? MR? MW? MH? As?;
|
||||
main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
|
||||
post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
|
||||
pwo_tone_group = PT A* DB? As?;
|
||||
|
||||
complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
|
||||
syllable_tail = (H | complex_syllable_tail);
|
||||
|
||||
consonant_syllable = k? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
|
||||
punctuation_cluster = P V;
|
||||
broken_cluster = k? VS? syllable_tail;
|
||||
other = any;
|
||||
|
||||
main := |*
|
||||
consonant_syllable => { found_syllable (consonant_syllable); };
|
||||
j => { found_syllable (non_myanmar_cluster); };
|
||||
punctuation_cluster => { found_syllable (punctuation_cluster); };
|
||||
broken_cluster => { found_syllable (broken_cluster); };
|
||||
other => { found_syllable (non_myanmar_cluster); };
|
||||
*|;
|
||||
|
||||
|
||||
}%%
|
||||
|
||||
#define found_syllable(syllable_type) \
|
||||
HB_STMT_START { \
|
||||
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
|
||||
for (unsigned int i = last; i < p+1; i++) \
|
||||
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
|
||||
last = p+1; \
|
||||
syllable_serial++; \
|
||||
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
|
||||
} HB_STMT_END
|
||||
|
||||
static void
|
||||
find_syllables (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
|
||||
int cs;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
%%{
|
||||
write init;
|
||||
getkey info[p].myanmar_category();
|
||||
}%%
|
||||
|
||||
p = 0;
|
||||
pe = eof = buffer->len;
|
||||
|
||||
unsigned int last = 0;
|
||||
unsigned int syllable_serial = 1;
|
||||
%%{
|
||||
write exec;
|
||||
}%%
|
||||
}
|
||||
|
||||
#undef found_syllable
|
||||
|
||||
#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue